Python setuptools is stripping slashes from path a

2020-08-21 06:10发布

问题:

I'm trying to install a package with setuptools including console_scripts on Windows 7. I'm trying to change the value of my PYTHONUSERBASE to install into a custom directory with the --user flag. If I use backslashes in the value of PYTHONUSERBASE, as in

set PYTHONUSERBASE=C:\testing

everything works fine. However, if I use a forward slash, as in

set PYTHONUSERBASE=C:/testing

the package itself installs to the right place, but the console_scripts (and only the console_scripts) are installed into C:testing\Scripts. Obviously, when the forward slash is present, setuptools is treating the path as a relative path only for the console_scripts. In my real package, I'm reading values from a configuration file, so I would really rather not have to deal with normalizing the path separator since it needs to work on Linux as well. For testing, I have a package with the structure

|-- setup.py
|-- foobar\
|---- __init__.py
|---- __main__.py

The code in the __main__.py is

def main(): print('This is the main function')

and setup.py looks like:

from setuptools import setup

setup(
    name='foobar',
    version='1.0.0',
    packages=['foobar'],
    entry_points={
        'console_scripts': [
            'foobar=foobar.__main__:main',
        ],
    },
)

Why is setuptools stripping out the first forward slash in the path and how can I fix it? I think this question is related to my problem, but I don't think it solves it: Python os.path.join on Windows

回答1:

The short answer is that Windows doesn't work well with forward slashes in the path name - as documented here. Avoid setting the PYTHONUSERBASE environment variable with such a name.

The longer version is that setuptools normalizes most of its path names (which converts / to \ on Windows versions of Python) either directly or by calling abs path. However it does not do so for the directory name which it uses when creating scripts (see write_script in this file).

You therefore see inconsistent behavior between scripts and other files. The fix is to avoid needing to normalize the files by avoiding the forward slashes in your paths.

If you're reading the path from a config file and then using that to set PYTHONUSERBASE simply use os.path.normpath to convert from Linux to Windows file names. This is fine on Linux as it will have no effect on the slashes.