This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: "python -m site" does not print path details
Type: Stage:
Components: Library (Lib) Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: doughellmann, eric.araujo, ncoghlan, ned.deily, ronaldoussoren, tarek
Priority: normal Keywords:

Created on 2010-10-31 13:18 by doughellmann, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (17)
msg120045 - (view) Author: Doug Hellmann (doughellmann) * (Python committer) Date: 2010-10-31 13:18
Running "python -m site" is supposed to print a report about the current import path and its components (like USER_BASE and USER_SITE).

This works under 2.6 and 3.1, but not 2.7.  No output is produced under 2.7 at all.  

When I add a print statement to the end of the module, I see that __name__ is set to "site" instead of "__main__", so the _script() function isn't being invoked at all.
msg120048 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2010-10-31 14:53
Since it works for me (I tried both r84120, my old 2.7 build from August or so, and r86033, which is the 2.7 head), we'll need more information. The starting blurb from the interactive prompt would be a good place to start.

(-m was slightly broken from April-June or so during 2.7 development, so custom builds in that window may exhibit occasional weirdness)
msg120052 - (view) Author: Doug Hellmann (doughellmann) * (Python committer) Date: 2010-10-31 15:10
I downloaded an OS X installer from python.org, but I don't remember the date I did that.

Here's the output when I start the interpreter:

$ which python
/Library/Frameworks/Python.framework/Versions/2.7/bin/python
$ python
Python 2.7 (r27:82508, Jul  3 2010, 21:12:11) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
msg120053 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2010-10-31 15:15
Note also that site.py runs twice when used with -m: once implicitly during interpreter startup, and a second time as the main module. Due to the way the interpreter starts up and figures out sys.path, it is possible for the implicit import to pick up the correct version, but for the explicit invocation to find an old version.

With my site.py patched to include a "print __name__" line, I get the following:

$ ./python -m site
site
__main__
sys.path = [
  <details cut>
]
USER_BASE: <details cut> (exists)
USER_SITE: <details cut> (exists)
ENABLE_USER_SITE: True

The fact that you're only seeing one printout suggests to me that this is exactly the problem you're running into. The easiest way to confirm that is to run "python Lib/site.py" explicitly rather than via -m. That way you aren't relying on the second import working correctly (and I'm assuming you want to run this because you have doubts as to the correctness of the contents of your sys.path)
msg120055 - (view) Author: Doug Hellmann (doughellmann) * (Python committer) Date: 2010-10-31 15:18
Actually I'm trying to update the PyMOTW article about site, and I discovered that the output from the old examples that showed using --user-base and --user-site were no longer producing any output.  It looks like the build of 2.7 I downloaded is fairly old, so I'll try updating that.
msg120057 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2010-10-31 15:20
r82508 is the correct release binary (created after the error I mentioned above was fixed).

I've CC'ed Ronald to see if he can shed any light - it may be a platform specific issue with the way sys.path is calculated.
msg120058 - (view) Author: Doug Hellmann (doughellmann) * (Python committer) Date: 2010-10-31 15:24
Ah, I assumed that since the revision number was older there might be a newer build available now.
msg120060 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2010-10-31 15:30
No, there won't be another binary release until 2.7.1 comes out. The SVN revision number ratchets up pretty fast, since it is counting checkins on *all* branches, even experimental ones.
msg120083 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2010-10-31 20:47
Unfortunately, the problem here is caused by having setuptools or Distribute installed. As released, both setuptools and Distribute install an easy-install.pth into site-packages to insert its "egg" into sys.path.  If you look inside the egg, you'll see it has its own site.py which gets executed first as a bootstrap to do sys.path manipulations after finding and importing the site module from the standard library.  So -m site actually runs the setuptools/distribute site module and not the expected standard library one.  To work as expected, the problem needs to be corrected in setuptools and Distribute so you may want to open issues with both projects if necessary.

BTW, I was unable to reproduce the problem with a current Debian Linux system with the Debian distribute package installed; it seems that the package there is patched to not install easy-install.pth.  I expect you would see the problem there if you installed either manually.
msg120094 - (view) Author: Doug Hellmann (doughellmann) * (Python committer) Date: 2010-10-31 22:29
That's strange.  I have Distribute 0.6.10, including an easy-install.pth file, installed under 2.6 and it doesn't exhibit the problem.  Is there some interaction between a change in Python 2.7 and Distribute?
msg120097 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2010-10-31 23:12
For me, python2.6 exhibits the same behavior as python2.7, using either Distribute 0.6.14 or 0.6.10 for both (this is on OS X with a stock framework build but that should not be significant). Perhaps you have a file permissions problem with your 2.6 site-packages or sys.path isn't what you expect?  Try adding a print in the distribute site.py to verify whether it is being executed at startup time.
msg120140 - (view) Author: Doug Hellmann (doughellmann) * (Python committer) Date: 2010-11-01 16:53
Adding a print to the site.py in Distribute's egg shows it is being run when I use 'python -m site'.  However, when I run 'python -c "import site; print site.__file__"' I get the version from the stdlib, as expected.

I guess the module finding mechanism for -m is different from the import code?
msg120148 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2010-11-01 18:03
Nick is the authority on -m so perhaps he can confirm this but I believe the execution of -m is carried out by the runpy standard library module and the runpy module essentially goes through the process of finding a module from scratch by searching through the modules in sys.path, thus bypassing the altered sys.path which the setuptools/Distribute site module "bootstrapped" and removed itself from.  So runpy will always find the setuptools/Distribute site module first since it is first on sys.path (until it executes and removes itself from sys.path).  It seems you've found one case where the sys.path manipulations of setuptools/Distributes make a difference: when trying to run site itself.  You can see which site module is found by runpy by trying:
  import runpy
  runpy.run_module("site")
msg120261 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2010-11-02 21:56
Yeah, because the internal import system isn't fully exposed, runpy and a couple of other tools in the standard library rely on the emulation in pkgutil instead. I know there are some differences between the emulation and the builtin mechanism on Windows in terms of search order, but I thought they were the same on OS X.

Manipulating sys.path and the various caches in sys should affect both import mechanisms though - just what are setuptools/distribute doing?

I'm also curious as to which version of the module importlib finds ("import importlib; print(importlib.import_module("site").__file__)" will tell you that for both 2.7 and 3.x)
msg120290 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2010-11-02 23:37
The issue here is not unique to OS X. I see the same behavior on Linux with a built-from-source Python 3.2a3 and Distribute 0.6.14. (As I noted earlier, Debian and presumably various other distributors package a patched version of setuptools / Distribute which does not do the "bootstrap" manipulations so you likely wouldn't see the problem.)

importlib.import_module('site') finds the standard library version whether s/D is installed or not.  But that is to be expected.  This problem is unique to the site module because the path manipulation stuff happens first and in the normal environment (not -m), sys.modules['site'] will always be pointing to the standard lib version; the s/D bootstrap erases its tracks so to speak.

Just to be clear, I don't think there is any Python problem here.  It's all due to how s/D tries to manage import order.  The only way around it is for s/D to recognize and support the -m site case.

Here's what is in easy_install.pth, with my {} annotations:

import sys; sys.__plen = len(sys.path)
{... an entry for the first easy_installed distribution ... }
./appscript-0.21.1-py2.7-macosx-10.3-fat.egg
{... and entries here for any other easy_installed distributions ...}
{... ending with this last one for distribute or setuptools itself ...}
./distribute-0.6.8-py2.7.egg
[ ... which creates the _egginsert attribute used here }
import sys; new=sys.path[_sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; s
ys.__egginsert = p+len(new)

The distribute egg contains a site.py at the top level.  If you are interested in looking at it, it's probably best to just install distribute and look at what happens in site-packages.
msg120317 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2010-11-03 11:58
Ah, yes, I see what you mean - because runpy ignores the sys.modules cache (by design), it won't see the precached module instance placed there by the bootstrap code.

We actually *could* make this work on our end: if we find an existing module in sys.modules, derive the file to be executed from the __file__ attribute of that module rather than searching the whole path again.
msg120320 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2010-11-03 12:42
Sounds good to me.
History
Date User Action Args
2022-04-11 14:57:08adminsetgithub: 54472
2010-11-03 12:42:06eric.araujosetmessages: + msg120320
2010-11-03 11:58:14ncoghlansetmessages: + msg120317
2010-11-02 23:37:51ned.deilysetmessages: + msg120290
2010-11-02 21:56:48ncoghlansetmessages: + msg120261
2010-11-01 18:03:08ned.deilysetmessages: + msg120148
2010-11-01 16:54:41doughellmannsetnosy: + tarek
2010-11-01 16:53:19doughellmannsetmessages: + msg120140
2010-10-31 23:12:45ned.deilysetmessages: + msg120097
2010-10-31 22:29:43doughellmannsetmessages: + msg120094
2010-10-31 20:47:54ned.deilysetstatus: open -> closed

nosy: + ned.deily
messages: + msg120083

resolution: not a bug
2010-10-31 15:30:39ncoghlansetmessages: + msg120060
2010-10-31 15:24:54doughellmannsetmessages: + msg120058
2010-10-31 15:20:13ncoghlansetmessages: + msg120057
2010-10-31 15:18:21doughellmannsetmessages: + msg120055
2010-10-31 15:16:24ncoghlansetnosy: + ronaldoussoren
2010-10-31 15:15:15ncoghlansetmessages: + msg120053
2010-10-31 15:10:54doughellmannsetmessages: + msg120052
2010-10-31 14:53:31ncoghlansetmessages: + msg120048
2010-10-31 13:59:42pitrousetnosy: + ncoghlan, eric.araujo
2010-10-31 13:18:42doughellmanncreate