Programmatically determine pip 'user install' location Scripts directory
Question:
As explained in pip’s documentation a user can install packages in his personal account using pip install --user <pkg>
.
How can I programmatically determine the user install location for scripts installed like this? I am talking about the directory that should be added to the PATH so that installed packages can be invoked from command line.
For example, in Windows when installing pip install -U pylint --user
I get the following warning because I don’t have 'C:UsersmyusernameAppDataRoamingPythonPython37Scripts'
in my PATH:
...
Installing collected packages: wrapt, six, typed-ast, lazy-object-proxy, astroid, mccabe, isort, colorama, toml, pylint
Running setup.py install for wrapt ... done
WARNING: The script isort.exe is installed in 'C:UsersmyusernameAppDataRoamingPythonPython37Scripts' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
WARNING: The scripts epylint.exe, pylint.exe, pyreverse.exe and symilar.exe are installed in 'C:UsersmyusernameAppDataRoamingPythonPython37Scripts' which is not on PATH.
Is there some python code I can use to determine that location programmatically (that will work on Windows/Linux/Darwin/etc)? Something like:
def get_user_install_scripts_dir():
...
# would return 'C:UsersmyusernameAppDataRoamingPythonPython37Scripts'
# on Windows with Python 3.7.x, '/home/myusername/.local/bin' in Linux, etc
return platform_scripts_dir
As a fallback, is there some command I can run to obtain this location? Something like (but for the script location not the site’s base directory):
PS C:Usersmyusername> python -m site --user-base
C:UsersmyusernameAppDataRoamingPython
$ python -m site --user-base
/home/myusername/.local
Answers:
Command-line:
python -c "import os, site; print(os.path.join(site.USER_BASE, 'Scripts' if os.name == 'nt' else 'bin'))"
Function:
import os, site
if os.name == 'nt':
bin_dir = 'Scripts'
else:
bin_dir = 'bin'
def get_user_install_bin_dir():
return os.path.join(site.USER_BASE, bin_dir)
I believe the following should give the expected result
import os
import sysconfig
user_scripts_path = sysconfig.get_path('scripts', f'{os.name}_user')
print(user_scripts_path)
Command-line:
python -c 'import os,sysconfig;print(sysconfig.get_path("scripts",f"{os.name}_user"))'
Since pip 21.3 released on 2021-10-11, pip itself uses sysconfig
to compute paths.
References:
- https://docs.python.org/3/library/sysconfig.html#installation-paths
- https://docs.python.org/3/library/os.html#os.name
- https://discuss.python.org/t/proper-way-to-determine-install-location-of-console-scripts/7188
- pip 21.3 "Deprecations and removals"
- github.com/pypa/pip/pull/10358 "Switch install scheme backend to sysconfig"
As explained in pip’s documentation a user can install packages in his personal account using pip install --user <pkg>
.
How can I programmatically determine the user install location for scripts installed like this? I am talking about the directory that should be added to the PATH so that installed packages can be invoked from command line.
For example, in Windows when installing pip install -U pylint --user
I get the following warning because I don’t have 'C:UsersmyusernameAppDataRoamingPythonPython37Scripts'
in my PATH:
...
Installing collected packages: wrapt, six, typed-ast, lazy-object-proxy, astroid, mccabe, isort, colorama, toml, pylint
Running setup.py install for wrapt ... done
WARNING: The script isort.exe is installed in 'C:UsersmyusernameAppDataRoamingPythonPython37Scripts' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
WARNING: The scripts epylint.exe, pylint.exe, pyreverse.exe and symilar.exe are installed in 'C:UsersmyusernameAppDataRoamingPythonPython37Scripts' which is not on PATH.
Is there some python code I can use to determine that location programmatically (that will work on Windows/Linux/Darwin/etc)? Something like:
def get_user_install_scripts_dir():
...
# would return 'C:UsersmyusernameAppDataRoamingPythonPython37Scripts'
# on Windows with Python 3.7.x, '/home/myusername/.local/bin' in Linux, etc
return platform_scripts_dir
As a fallback, is there some command I can run to obtain this location? Something like (but for the script location not the site’s base directory):
PS C:Usersmyusername> python -m site --user-base
C:UsersmyusernameAppDataRoamingPython
$ python -m site --user-base
/home/myusername/.local
Command-line:
python -c "import os, site; print(os.path.join(site.USER_BASE, 'Scripts' if os.name == 'nt' else 'bin'))"
Function:
import os, site
if os.name == 'nt':
bin_dir = 'Scripts'
else:
bin_dir = 'bin'
def get_user_install_bin_dir():
return os.path.join(site.USER_BASE, bin_dir)
I believe the following should give the expected result
import os
import sysconfig
user_scripts_path = sysconfig.get_path('scripts', f'{os.name}_user')
print(user_scripts_path)
Command-line:
python -c 'import os,sysconfig;print(sysconfig.get_path("scripts",f"{os.name}_user"))'
Since pip 21.3 released on 2021-10-11, pip itself uses sysconfig
to compute paths.
References:
- https://docs.python.org/3/library/sysconfig.html#installation-paths
- https://docs.python.org/3/library/os.html#os.name
- https://discuss.python.org/t/proper-way-to-determine-install-location-of-console-scripts/7188
- pip 21.3 "Deprecations and removals"
- github.com/pypa/pip/pull/10358 "Switch install scheme backend to sysconfig"