Yes, os.py is the hardcoded landmark.
Modules/getpath.c
#ifndef LANDMARK
#define LANDMARK "os.py"
#endif| z, ? | toggle help (this) |
| space, → | next slide |
| shift-space, ← | previous slide |
| d | toggle debug mode |
| ## <ret> | go to slide # |
| c, t | table of contents (vi) |
| f | toggle footer |
| r | reload slides |
| n | toggle notes |
| p | run preshow |

site-packages directorysite-packages.site-packages/usr/lib/python2.6/site-packages//usr/lib/python2.6)site-packagessite.py at startup.usr/lib/python2.6/site.pyLib/site.py in the Python source.site.py# Prefixes for site-packages;
PREFIXES = [sys.prefix, sys.exec_prefix]
def getsitepackages():
"""Returns a list containing all global site-packages
directories (and possibly site-python).
For each directory present in the global ``PREFIXES``,
this function will find its `site-packages` subdirectory
depending on the system environment, and will return a
list of full paths.
"""
sitepackages = []
seen = set()
for prefix in PREFIXES:
if not prefix or prefix in seen:
continue
seen.add(prefix)
if sys.platform in ('os2emx', 'riscos'):
sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
elif os.sep == '/':
sitepackages.append(os.path.join(prefix, "lib",
"python" + sys.version[:3],
"site-packages"))
sitepackages.append(os.path.join(prefix, "lib", "site-python"))
else:
sitepackages.append(prefix)
sitepackages.append(os.path.join(prefix, "lib", "site-packages"))
if sys.platform == "darwin":
# for framework builds *only* we add the standard Apple
# locations.
from sysconfig import get_config_var
framework = get_config_var("PYTHONFRAMEWORK")
if framework and "/%s.framework/"%(framework,) in prefix:
sitepackages.append(
os.path.join("/Library", framework,
sys.version[:3], "site-packages"))
return sitepackagessys.prefix come from?Python/sysmodule.cModules/getpath.cModules/getpath.c#ifndef LANDMARK
#define LANDMARK "os.py"
#endif
static int
search_for_prefix(char *argv0_path, char *home)
{
/* ... */
/* Search from argv0_path, until root is found */
copy_absolute(prefix, argv0_path);
do {
n = strlen(prefix);
joinpath(prefix, lib_python);
joinpath(prefix, LANDMARK);
if (ismodule(prefix))
return 1;
prefix[n] = '\0';
reduce(prefix);
} while (prefix[0]);sys.prefixPYTHONHOME is set, that's sys.prefix.lib/pythonX.X/os.py.sys.prefix.configure --prefix from build.os.py is the hardcoded landmark.Modules/getpath.c#ifndef LANDMARK
#define LANDMARK "os.py"
#endif$ mkdir scratch; cd scratch
$ mkdir bin
$ cp /usr/bin/python bin/
$ tree
.
`-- bin
`-- python
$ ./bin/python -c "import sys; print(sys.prefix)"
/usr
sys.prefix is still /usr.PYTHONHOME set./home/carljm/scratch/bin/./home/carljm/scratch/bin/lib/python2.6/os.py/home/carljm/scratch/lib/python2.6/os.py/home/carljm/lib/python2.6/os.py/home/lib/python2.6/os.py/usr is the fallback build prefix.$ mkdir -p lib/python2.6
$ touch lib/python2.6/os.py
$ tree
.
|-- bin
| `-- python
`-- lib
`-- python2.6
`-- os.py
$ ./bin/python -c "import sys; print(sys.prefix)"
'import site' failed; use -v for traceback
/home/carljm/scratch
$ ./bin/python -c "import sys; print(sys.path)"
'import site' failed; use -v for traceback
['',
'/home/carljm/scratch/lib/python2.6/',
'/home/carljm/scratch/lib/python2.6/plat-linux2',
'/home/carljm/scratch/lib/python2.6/lib-tk',
'/home/carljm/scratch/lib/python2.6/lib-old',
'/usr/lib/python2.6/lib-dynload']
sys.exec_prefix$ mkdir lib/python2.6/lib-dynload
$ ./bin/python -c "import sys; print(sys.exec_prefix)"
'import site' failed; use -v for traceback
/home/carljm/scratch
$ ./bin/python -c "import sys; print(sys.path)"
'import site' failed; use -v for traceback
['',
'/home/carljm/scratch/lib/python2.6/',
'/home/carljm/scratch/lib/python2.6/plat-linux2',
'/home/carljm/scratch/lib/python2.6/lib-tk',
'/home/carljm/scratch/lib/python2.6/lib-old',
'/home/carljm/scratch/lib/python2.6/lib-dynload']
site.py, thus no site-packages at all.site.py) into our lib/python2.6.virtualenv.orig-prefix.txt to lib/python2.6.sys.prefix.site.py in lib/python2.6.site.py reads orig-prefix.txt and adds system stdlib paths to
sys.path.$ tree
.
|-- bin
| `-- python
`-- lib
`-- python2.6
|-- lib-dynload
|-- orig-prefix.txt
|-- os.py
`-- site.py
site.pydef virtual_install_main_packages():
f = open(os.path.join(os.path.dirname(__file__),
'orig-prefix.txt'))
sys.real_prefix = f.read().strip()
# ...
if sys.platform == 'win32':
paths = [os.path.join(sys.real_prefix, 'Lib'),
os.path.join(sys.real_prefix, 'DLLs')]
# ...
else:
paths = [os.path.join(sys.real_prefix,
'lib',
'python'+sys.version[:3])]
# ...
sys.path.extend(paths)site.py depends on the standard library!site.py.site.py runs, we'll have access to the full stdlib thanks to its
sys.path additions.virtualenv.pyREQUIRED_MODULES = [
'os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
'fnmatch', 'locale', 'encodings', 'codecs',
'stat', 'UserDict', 'readline', 'copy_reg', 'types',
're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
'zlib']
def copy_required_modules(dst_prefix):
import imp
for modname in REQUIRED_MODULES:
# ...
try:
f, filename, _ = imp.find_module(modname)
except ImportError:
logger.info("Cannot import bootstrap module: %s" % modname)
else:
if f is not None:
f.close()
dst_filename = change_prefix(filename, dst_prefix)
copyfile(filename, dst_filename)
# ...site-packages, if we want it.site.pydef virtual_addsitepackages(known_paths):
# ...
return addsitepackages(known_paths,
sys_prefix=sys.real_prefix)
# ...
def main():
# ...
if GLOBAL_SITE_PACKAGES:
paths_in_sys = virtual_addsitepackages(paths_in_sys)
# ...site.py.bin/activate?bin/ to the front of your shell PATH.import sys
sys.path.insert(0,
"/path/to/venv/lib/python2.6/site-packages")
import site
site.addsitedir(
"/path/to/venv/lib/python2.6/site-packages")
execfile("/path/to/venv/bin/activate_this.py")site.py.site.py (e.g. Debian dist-packages).site.py.https://bitbucket.org/brandon/virtualenv-small-sitepysite.py a light wrapper around the system site.py.https://github.com/kvbik/rvirtualenvPYTHONHOME!sys.prefix with no copied binary.site.py hacks.pip/req.pydef install(self, install_options, global_options=()):
# ...
install_args = [
sys.executable, '-c',
"import setuptools;__file__=%r;"\
"execfile(__file__)" % self.setup_py] +\
list(global_options) + [
'install',
'--single-version-externally-managed',
'--record', record_filename]
# ...
call_subprocess(install_args + install_options,
cwd=self.source_dir,
filter_stdout=self._filter_install,
show_stdout=False)python -c
"import setuptools;__file__=/p/to/setup.py;execfile(__file__)"
install
--single-version-externally-managed
--record /tmp/pip-ZgGVWG-record/install-record.txt
"import setuptools;__file__=/p/to/setup.py;execfile(__file__)"installpython setup.py install.--single-version-externally-managedTells setuptools to do a "flat" (distutils-style) install and put the
metadata next to it in a .egg-info directory, rather than a zipped egg or
egg-directory.
A setuptools feature.
$ easy_install yolk
# cd to site-packages
$ ls | egrep "(yolk|easy)"
easy-install.pth
yolk-0.4.1-py2.6.egg
$ cat easy-install.pth
./setuptools-0.6c11-py2.6.egg
./pip-0.8.1-py2.6.egg
./yolk-0.4.1-py2.6.egg
import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)
--single-version-externally-managed:$ pip install yolk
$ ls | grep yolk
yolk/
yolk-0.4.1-py2.6.egg-info/
--record /tmp/pip-ZgGVWG-record/install-record.txtinstalled-files.txt in the .egg-info metadata directory.pip as an APIpip/commands/install.pyclass InstallCommand(Command):
name = 'install'
usage = '%prog [OPTIONS] PACKAGE_NAMES...'
summary = 'Install packages'
bundle = False
def __init__(self):
super(InstallCommand, self).__init__()
self.parser.add_option(
'-e', '--editable',
dest='editables',
action='append',
default=[],
metavar='VCS+REPOS_URL[@REV]#egg=PACKAGE',
# ...
def run(self, options, args):
# ...from pip.req import InstallRequirement, RequirementSet
from pip.index import PackageFinder
from pip.locations import build_prefix, src_prefix
reqset = RequirementSet(build_dir=build_prefix,
src_dir=src_prefix,
download_dir=None)
req = InstallRequirement.from_line("yolk==0.4.1",
comes_from=None)
reqset.add_requirement(req)
finder = PackageFinder(
find_links=[],
index_urls=["http://pypi.python.org/simple"])
reqset.prepare_files(finder)
reqset.install(install_options=[], global_options=[])
reqset.cleanup_files()#pip on Freenode