Cross-platform way to get default directory for binary files like console scripts?
Hi! I posted (https://groups.google.com/forum/#!topic/comp.lang.python/s3vLkVy2xJk) to comp.lang.python yesterday the following question: ------- Is there cross-platform way to get default directory for binary files (console scripts for instance) the same way one can use sys.executable to get path to the Python's interpreter in cross-platform way? Context: There's Python script which runs various tools like pip using subprocess and we would like to make sure we run tools that accompany Python's interpreter used to run this script. Please note that the script may be run from within virtualenv which had not been activated - ./venv/bin/python our_script.py ------- In replay Oscar Benjamin showed roundabout way to get this info In [1]: from distutils.command.install import install In [2]: from distutils.dist import Distribution In [3]: c = install(Distribution()) In [4]: c.finalize_ c.finalize_options c.finalize_other c.finalize_unix In [4]: c.finalize_options() In [5]: c.insta c.install_base c.install_headers c.install_lib c.install_path_file c.install_platlib c.install_scripts c.install_usersite c.install_data c.install_layout c.install_libbase c.install_platbase c.install_purelib c.install_userbase In [5]: c.install_scripts Out[5]: '/usr/local/bin' Is it really that there's no API like sys.executable to get this info and if so are there any plans to provide such API? Best regards, Piotr Dobrogost
On 21 February 2014 08:55, Piotr Dobrogost <p@google-groups-2014.dobrogost.net> wrote:
Hi!
I posted (https://groups.google.com/forum/#!topic/comp.lang.python/s3vLkVy2xJk) to comp.lang.python yesterday the following question:
------- Is there cross-platform way to get default directory for binary files (console scripts for instance) the same way one can use sys.executable to get path to the Python's interpreter in cross-platform way?
sysconfig.get_path("scripts") should work. If you're on a Python too old to have sysconfig then sorry, I've no idea (other than "you should upgrade" :-)) Paul
On 21 February 2014 13:24, Paul Moore <p.f.moore@gmail.com> wrote:
Is there cross-platform way to get default directory for binary files (console scripts for instance) the same way one can use sys.executable to get path to the Python's interpreter in cross-platform way?
sysconfig.get_path("scripts") should work. If you're on a Python too old to have sysconfig then sorry, I've no idea (other than "you should upgrade" :-))
Ah, well that's better. One question though: are these guaranteed to be consistent. I was pointing at the actual code that distutils uses when installing where as you're pointing at a module that independently lists an over-lapping set of data: http://hg.python.org/cpython/file/005d0678f93c/Lib/sysconfig.py#l21 http://hg.python.org/cpython/file/005d0678f93c/Lib/distutils/command/install... For example sysconfig defines a scheme 'osx_framework_user' that doesn't appear in distutils.command.install and uses slightly different paths from posix_user. Does that mean that it is inconsistent with what distutils would do? Oscar
On 21 February 2014 17:04, Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote:
On 21 February 2014 13:24, Paul Moore <p.f.moore@gmail.com> wrote:
Is there cross-platform way to get default directory for binary files (console scripts for instance) the same way one can use sys.executable to get path to the Python's interpreter in cross-platform way?
sysconfig.get_path("scripts") should work. If you're on a Python too old to have sysconfig then sorry, I've no idea (other than "you should upgrade" :-))
Ah, well that's better.
One question though: are these guaranteed to be consistent. I was pointing at the actual code that distutils uses when installing where as you're pointing at a module that independently lists an over-lapping set of data: http://hg.python.org/cpython/file/005d0678f93c/Lib/sysconfig.py#l21 http://hg.python.org/cpython/file/005d0678f93c/Lib/distutils/command/install...
For example sysconfig defines a scheme 'osx_framework_user' that doesn't appear in distutils.command.install and uses slightly different paths from posix_user. Does that mean that it is inconsistent with what distutils would do?
Well, it's difficult to tell. As you say, there are "schemes" involved - the original question isn't actually well-defined as there are "user" and "system" installs on each platform:
sysconfig.get_path("scripts") 'C:\\Apps\\Python33\\Scripts' sysconfig.get_path("scripts", "nt_user") 'C:\\Users\\Gustav\\AppData\\Roaming\\Python\\Scripts' sysconfig.get_path("scripts", "nt") 'C:\\Apps\\Python33\\Scripts'
So the best you can really say is that sysconfig lets you get the script path for a given scheme. But distutils predates sysconfig (and setuptools hacks the internals of distutils in ways that potentially add even more variability) so no, I can't guarantee that distutils might not be consistent. If the two did give different results it's probably a bug, though. But whether it's a bug taht would get *fixed* is yet another problem (compatibility and all that). For the use case described by the OP, using sysconfig is probably sensible. But the tool should likely document that it won't find executables installed with --user, and maybe provide a flag to say to use the user scheme rather than the default scheme, so that the user can control things. Depending on the complexity of the tool, and the importance of being able to cope with unusual situations, having a config file that allows the user to specify the full path on a program-by-program basis might be necessary. In summary - sysconfig is what you should use if you want the "official" answer. But the question is not as easy as it looks. Paul
Is there cross-platform way to get default directory for binary files (console scripts for instance)
Well, there's $ /tmp/venv/bin/python Python 3.3.0+ (3.3:c28b0b4e872b, Mar 25 2013, 17:51:34) [GCC 4.6.1] on linux Type "help", "copyright", "credits" or "license" for more information.
import sysconfig; print(sysconfig.get_path('scripts')) /tmp/venv/bin
$ python Python 2.7.2+ (default, Jul 20 2012, 22:15:08) [GCC 4.6.1] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import sysconfig; print(sysconfig.get_path('scripts')) /usr/local/bin
Regards, Vinay Sajip
participants (4)
-
Oscar Benjamin
-
Paul Moore
-
Piotr Dobrogost
-
Vinay Sajip