python / cpython

The Python programming language
https://www.python.org
Other
62.84k stars 30.1k forks source link

Add PYTHONPREFIXES environment variable #50069

Closed larryhastings closed 12 years ago

larryhastings commented 15 years ago
BPO 5819
Nosy @warsaw, @larryhastings, @merwok, @asvetlov
Files
  • lch.pythonprefixes.r71812.diff: Patch against py3k/trunk r71812.
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields: ```python assignee = None closed_at = created_at = labels = ['type-feature', 'library'] title = 'Add PYTHONPREFIXES environment variable' updated_at = user = 'https://github.com/larryhastings' ``` bugs.python.org fields: ```python activity = actor = 'asvetlov' assignee = 'none' closed = True closed_date = closer = 'asvetlov' components = ['Library (Lib)'] creation = creator = 'larry' dependencies = [] files = ['13745'] hgrepos = [] issue_num = 5819 keywords = ['patch'] message_count = 11.0 messages = ['86352', '86353', '86370', '86371', '86383', '96543', '120796', '147607', '166114', '166211', '167819'] nosy_count = 6.0 nosy_names = ['barry', 'larry', 'eric.araujo', 'ianb', 'asvetlov', 'cdunn2001'] pr_nums = [] priority = 'normal' resolution = 'out of date' stage = 'resolved' status = 'closed' superseder = None type = 'enhancement' url = 'https://bugs.python.org/issue5819' versions = ['Python 3.2'] ```

    larryhastings commented 15 years ago

    The attached patch adds support for a new environment variable, PYTHONPREFIXES. PYTHONPREFIXES is similar to PYTHONUSERBASE: it lets you add "prefix directories" to be culled for site packages. It differs from PYTHONUSERBASE in three ways:

    This last point bears further discussion. PYTHONUSERBASE's custom code to inspect only a single directory has resulted in at least one bug, if not more, as follows:

    PYTHONUSERBASE's custom code path to add site package directories is a source of unnecessary complexity and bugs. I cannot fathom why its implementors chose this approach; in any case I think reusing site.addsitepackages is a clear win. I suspect it's too late to change the semantics of PYTHONUSERBASE to simply call site.addsitepackages, though if that idea found support I'd be happy to contribute a patch.

    A few more notes on PYTHONPREFIXES:

    The attached patch is thrillingly simple and works fine. However it's not ready to be merged because I haven't touched the documentation. I figured I'd hold off until I see which way the wind blows.

    I'd also be happy to whip out a PEP if that's what is called for.

    larryhastings commented 15 years ago

    Whoops, didn't classify the patch before submission.

    53404a3c-d211-4751-a5b8-5687f2a08300 commented 15 years ago

    This has a similar purpose to virtualenv, but using an environmental variable. An earlier package, workingenv, also used an environmental variable, and this led to a set of problems.

    The biggest problem is that the environmental variable is inherited by subprocesses. This means if you install hg globally, then do subprocess.call(['hg', ...]), then hg will have picked up your local environment. Sometimes this is what you want (e.g., when using ipython) and sometimes not (probably not when using hg).

    Another problem is that scripts aren't really sticky with respect to the environment. When you install a script using this, it may only work when that same environmental variable is set. But the script remains present and callable regardless. Also, it's hard to mix and match environments in this system.

    These are real-world problems I encountered with workingenv, and virtualenv has resolved them very reliably by instead using sys.executable to select the environment. This requires some infrastructure in each environment which is unfortunate, but the result is more consistent behavior.

    53404a3c-d211-4751-a5b8-5687f2a08300 commented 15 years ago

    Also with respect to the patch, for consistency there needs to be changes to distutils to make use of this variable. PYTHONUSERBASE included changes so that you can install based on that variable.

    larryhastings commented 15 years ago

    Thanks for your battle-tested feedback, Mr. Bicking! I reply inline.

    The biggest problem is that the environmental variable is inherited by subprocesses. [...] Another problem is that scripts aren't really sticky with respect to the environment. [...] These are real-world problems I encountered with workingenv, and virtualenv has resolved them very reliably by instead using sys.executable to select the environment.

    Excellent points. PYTHONPREFIXES is not a virtualization cure-all; for a complete solution you clearly need an executable file for folks to hang their hat on.

    However: wouldn't PYTHONPREFIXES greatly simplify virtualenv? All you should need is an executable and a "sitecustomize" module. Your executable would set PYTHONPREFIXES as makes sense and run Python. Your usercustomize would:

    In fact I just tried this. A two-line shell script for "python3", a twenty-line "sitecustomize.py", installed lib/python3.1/config/Makefile and include/python3.1 in my virtualized environment, and I was able to install HeapDict for python3 using its setup.py. (PyPI lies, though; HeapDict doesn't work unmodified in python3. It calls callable(). But once I fixed that it ran fine.) So it passes a smoke-test at least.

    Also, it's hard to mix and match environments in this system.

    How so? I thought this proposal made it far easier to mix and match environments. PYTHONPREFIXES is a stack; push and pop environments as you like.

    Also with respect to the patch, for consistency there needs to be changes to distutils to make use of this variable. PYTHONUSERBASE included changes so that you can install based on that variable.

    Good call. I found it infuriating that setuptools didn't (still doesn't iirc) understand PYTHONUSERBASE, and would complain that the --prefix directory doesn't support .pth files. If this patch goes further I'll fix up distutils.

    Thanks again for your feedback!

    df501793-f767-4b11-a23d-de40a0e0e148 commented 14 years ago

    I am not sure that this guy's idea is good, but I think that he deserves more attention. In comments elsewhere on the web, I noticed that people thought the PYTHONUSERBASE site-packages directory could contain .pth files which would serve the same purpose as his proposed environment variable. However, .pth files are not recursive; a .pth file in one directory does not cause .pth files to be processed in the directories named by its contents.

    I agree with ianb that this is a poor way to mimic virtualenv. There is a difference between user additions -- which should affect *all* python code that he uses -- and separate Python installations.

    There might be other reasons for multiple user site-packages directories. For example, Python lacks Perl's architecture awareness. Perl can load from lib/ lib/5.10.0/ lib/5.10.0/linux-x86 lib/5.10.0/linux-x86/auto and a few other combinations.

    Python also lacks a PERL5OPT equivalent. I am forced to use the PYTHONUSERBASE mechanism to simulate that behavior (which I use to turn on code coverage everywhere during testing) but I only get to set that once.

    warsaw commented 13 years ago

    I'll look at this in more detail, but I can at least answer one question right now:

    "The bona-fide known bug: the Debian package mantainer for Python decided to change "site-packages" to "dist-packages" in 2.6, for reasons I still don't quite understand."

    This was done as an accommodation to upstream Python developers. A from-source build of Python installs into /usr/local by default, with a site-packages situated there. But the Debian interpretation of the FHS states that site-installed (i.e. not through the package manager) add-ons to Python should also live in /usr/local, and /usr/local/lib/pythonX.Y/site-packages was chosen as the most obvious place for that.

    Unfortunately, this meant that if you installed Python from source using the defaults, it was possible to clobber either your system Python or your from-source installed Python by installing third party packages to an unintentionally shared directory. This was a real problem.

    Now, the Debian answer (probably rightly so) was that Python's from-source defaults should install into /opt not /usr/local, but this broke a decade's (at least) convention from upstream. The compromise was to keep Debian's /usr/local interpretation of the FHS, but to choose a directory that would not conflict with a from-source installation of Python. Thus dist-packages was chosen. To keep the system Python consistent, Python packages installed via apt are installed to /usr/lib/pythonX.Y/dist-packages too.

    I've had discussions with developers on both sides. It's not an ideal solution to anyone, but I thought it was the best compromise available at that time, and still do.

    merwok commented 12 years ago

    See also bpo-1298835 and PEP-405.

    asvetlov commented 12 years ago

    As PEP-405 has been implemented in Python 3.3 this issue can be closed I think.

    df501793-f767-4b11-a23d-de40a0e0e148 commented 12 years ago

    I agree. venv solves this problem and more.

    asvetlov commented 12 years ago

    Close issue as superseded by venv package.