Bug 1602745 - PIP3 and python3 setup.py unable to install scripts
Summary: PIP3 and python3 setup.py unable to install scripts
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: python3
Version: 28
Hardware: Unspecified
OS: Linux
unspecified
unspecified
Target Milestone: ---
Assignee: Miro Hrončok
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2018-07-18 12:07 UTC by Michael Clerx
Modified: 2018-07-23 09:41 UTC (History)
12 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2018-07-23 09:41:30 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
Minimal example to reproduce (978 bytes, application/zip)
2018-07-19 09:51 UTC, Michael Clerx
no flags Details
Minimal example to reproduce. With bugfix (979 bytes, application/zip)
2018-07-19 10:14 UTC, Michael Clerx
no flags Details

Description Michael Clerx 2018-07-18 12:07:17 UTC
Description of problem:

I have a setup.py that includes a shell script

    # Register as a shell script
    entry_points={
        'console_scripts': ['my_command = my_module.my_command:main']
    },

Using Python 2 we get the correct behavior: After installing this with setup.py or via pip (as root), the script is added to /usr/bin

Using Python 3 this doesn't happen. And typing `my_command` results in the error

    bash: /usr/bin/my_command: No such file or directory

Comment 1 Miro Hrončok 2018-07-19 09:07:09 UTC
Could you please give me an exact reproducer witch all the commands?

Note that sudo pip installing is dangerous and you should not do it.

Comment 2 Michael Clerx 2018-07-19 09:51:41 UTC
Created attachment 1459958 [details]
Minimal example to reproduce

Setup.py

    # SetupTools for example script
    from setuptools import setup, find_packages
    setup(
        name='example',
        packages=find_packages(include=('example')),
        entry_points={
            'console_scripts': ['example = example.__main__:main']
        },
    )

example/__init__.py

    # Example module

example/__main__.py

    def main():
        print('Hello world')
    if __name__ == '__main__':
        main()

Comment 3 Miro Hrončok 2018-07-19 09:58:08 UTC
What exact command do I need to run?

Comment 4 Michael Clerx 2018-07-19 10:14:40 UTC
Created attachment 1459968 [details]
Minimal example to reproduce. With bugfix

Minimal example to reproduce

Setup.py

    # SetupTools for example script
    from setuptools import setup, find_packages
    setup(
        version='1.0.0',
        name='example',
        packages=find_packages(include=('example')),
        entry_points={
            'console_scripts': ['example = example.__main__:main']
        },
    )

example/__init__.py

    # Example module

example/__main__.py

    def main():
        print('Hello world')
    if __name__ == '__main__':
        main()


To test:

Python 2 (works):

    $ sudo pip install 
    $ example
    Hello world

Python 3

   $ sudo pip3 install
   $ example
   -bash: /usr/bin/example: No such file or directory

Comment 5 Miro Hrončok 2018-07-19 10:45:59 UTC
Ends up in /usr/local/bin/example which is in sync with https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard

https://unix.stackexchange.com/a/4187/196399

Comment 6 Michael Clerx 2018-07-19 11:05:06 UTC
Don't see it there on my system!

Comment 7 Miro Hrončok 2018-07-19 11:19:40 UTC
Ok, here is a complete reproducer on Fedora 28:

<mock-chroot> sh-4.4# rpm -q python3
python3-3.6.5-1.fc28.x86_64
<mock-chroot> sh-4.4# rpm -q python3-setuptools
python3-setuptools-39.2.0-1.fc28.noarch
<mock-chroot> sh-4.4# mkdir reproducer
<mock-chroot> sh-4.4# cd reproducer/
<mock-chroot> sh-4.4# cat > setup.py
# SetupTools for example script
from setuptools import setup, find_packages
setup(
    version='1.0.0',
    name='example',
    packages=find_packages(include=('example')),
    entry_points={
        'console_scripts': ['example = example.__main__:main']
    },
)
<mock-chroot> sh-4.4# mkdir example
<mock-chroot> sh-4.4# touch example/__init__.py
<mock-chroot> sh-4.4# cat > example/__main__.py
def main():
    print('Hello world')
if __name__ == '__main__':
    main()
<mock-chroot> sh-4.4# whoami 
root
<mock-chroot> sh-4.4# pip3 install .
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.
The directory '/builddir/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/builddir/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Processing /reproducer
Installing collected packages: example
  Running setup.py install for example ... done
Successfully installed example-1.0.0
<mock-chroot> sh-4.4# cat /usr/local/bin/example 
#!/usr/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'example==1.0.0','console_scripts','example'
__requires__ = 'example==1.0.0'
import re
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(
        load_entry_point('example==1.0.0', 'console_scripts', 'example')()
    )

Comment 8 Victor Stinner 2018-07-19 13:55:00 UTC
python2 -m pip installs the program in /usr/bin, whereas python3 -m pip installs the program into /usr/local/bin.

But I upgraded Python 3 pip manually using "python3 -m pip install -U pip" which installed pip in /usr/local/lib/python3.6/site-packages/pip(...). Maybe it explains why python3 -m pip uses /usr/local (at least, on my case).

Comment 9 Miro Hrončok 2018-07-19 14:02:37 UTC
python3 -m pip installs the program into /usr/local/bin because of https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe

Comment 10 Michael Clerx 2018-07-19 14:53:07 UTC
Hmmm. It works using `python3 -m pip install .` but not using `pip3 -m install .`

Comment 11 Miro Hrončok 2018-07-19 14:58:50 UTC
I'm assuming you mean `pip3 install .` without m.

What is the output of:

$ pip3 --version
$ python3 -m pip --veriosn

Comment 12 Michael Clerx 2018-07-19 15:06:49 UTC
[root@laptop example-script]# pip3 --version
pip 9.0.3 from /usr/lib/python3.6/site-packages (python 3.6)
[root@laptop example-script]# python3 -m pip --version
pip 9.0.3 from /usr/lib/python3.6/site-packages (python 3.6)

Now seeing expected behavior with pip3 as well... Repeated install/uninstall works about half the time

Comment 13 Miro Hrončok 2018-07-19 15:27:12 UTC
> works about half the time

and what happens the other half? Don't tell that "it doesn't work", tall me what's wrong. I cannot reproduce your problem.

Comment 14 Michael Clerx 2018-07-19 15:48:21 UTC
I get this message:

[root@laptop example-script]# example
-bash: /usr/bin/example: No such file or directory


Ok, as far as I can tell the issue is this:

1. Install with Python 2.7 --> Creates /usr/bin/example
2. Uninstall Python 2.7
3. Install with Python 3.6 --> Creates /usr/local/bin/example
4. Type "example" --> Bash remembers to look in /usr/bin/ but can't find it there.

So just a side effect, really?

Comment 15 Miro Hrončok 2018-07-19 15:58:41 UTC
what's your PATH?

Comment 16 Miro Hrončok 2018-07-19 16:01:24 UTC
So this is a bash behaviour and nothing we can fix:

[~]$ sudo ln -s /usr/bin/echo /usr/bin/bz1602745
[~]$ bz1602745 ha
ha
[~]$ sudo unlink /usr/bin/bz1602745
[~]$ sudo ln -s /usr/bin/echo /usr/local/bin/bz1602745
[~]$ bz1602745 ha
bash: /usr/bin/bz1602745: No such file or directory
[~]$ bash
[~]$ bz1602745 ha
ha


Note You need to log in before you can comment on or make changes to this bug.