├── .gitignore
├── MANIFEST.in
├── README.rst
├── TODO.rst
├── garbage
├── inherit
│ ├── a
│ ├── b
│ ├── c
│ └── d
├── little-py
│ └── PY
│ │ ├── pythonrc.py
│ │ ├── rvirtualenvinstall.egg-info
│ │ ├── PKG-INFO
│ │ └── entry_points.txt
│ │ ├── rvirtualenvinstall
│ │ ├── __init__.py
│ │ ├── boot.py
│ │ ├── develop.py
│ │ ├── install.py
│ │ └── scheme.py
│ │ └── site.py
├── notes
├── schemes
│ ├── install.linux.py27.normal.txt
│ ├── install.linux.py27.prefixed.txt
│ ├── install.macosmini.py26.normal.txt
│ ├── install.macosmini.py26.prefixed.txt
│ ├── install.macossrv.py25.normal.txt
│ ├── install.macossrv.py25.prefixed.txt
│ ├── install.py
│ ├── install.sh
│ ├── install.win.py26.normal.txt
│ └── install.win.py26.prefixed.txt
└── sysconfig
│ ├── sysconfig27.py
│ └── sysconfig32.py
├── rvirtualenv.py
├── rvirtualenv
├── __init__.py
├── copy.py
├── generate.py
├── rvirtualenvinstall
│ ├── __init__.py
│ ├── boot.py
│ ├── develop.py
│ ├── install.py
│ └── scheme.py
└── template
│ ├── inst
│ ├── bin
│ │ ├── activate
│ │ ├── activate.bat
│ │ ├── activate.bat.template
│ │ ├── activate.py
│ │ ├── activate.template
│ │ ├── deactivate.bat
│ │ ├── deactivate.bat.template
│ │ ├── getpythondist.py
│ │ ├── python
│ │ ├── python.bat
│ │ └── python.py
│ ├── rvirtualenvkeep.py
│ └── setup.py
│ └── venv
│ ├── pythonrc.py
│ ├── rvirtualenvinstall.egg-info
│ ├── PKG-INFO
│ └── entry_points.txt
│ └── site.py
├── setup.py
└── tests
├── __init__.py
├── helpers.py
├── installs
├── venvtest-distutils
│ ├── setup.py
│ └── venvtest.py
└── venvtest-setuptools
│ ├── setup.py
│ └── venvtest.py
├── scripts
└── print.py
├── test_all.py
├── test_copy.py
├── test_generate.py
└── test_rvirtualenv.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.py[co]
2 | .*.sw?
3 | *~
4 |
5 | /tests/installs/venvtest-distutils/build/
6 | /tests/installs/venvtest-setuptools/VEnvTest.egg-info/
7 | /tests/installs/venvtest-setuptools/build/
8 | /tests/installs/venvtest-setuptools/dist/
9 |
10 | pokus.*
11 |
12 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | recursive-include rvirtualenv *
2 | global-exclude *.py[co]
3 | include README.rst TODO.rst
4 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | ======================================
2 | relocatable python virtual environment
3 | ======================================
4 |
5 | package inspired a lot by ian bicking's virtualenv_ but created in fashion
6 | that it can be relocated freely through the filesystem, renamed, backuped, ...
7 |
8 | .. _virtualenv: http://bitbucket.org/ianb/virtualenv/
9 |
10 | second nice feature is, that you can customize your python environment
11 | via ``{{ENV}}/pythonrc.py`` in any curious way you want.
12 |
13 | works with python3, pypy
14 |
15 | install
16 | -------
17 |
18 | you can `install this package from pypi`_::
19 |
20 | pip install RVirtualEnv
21 |
22 | # or
23 | easy_install RVirtualEnv
24 |
25 | # or just clone this repository
26 | git clone http://github.com/kvbik/rvirtualenv
27 |
28 | you should definitely `try development version`__
29 |
30 | .. _install this package from pypi: http://pypi.python.org/pypi/RVirtualEnv
31 |
32 | __ development_
33 |
34 | to create new virtual environment just call::
35 |
36 | rvirtualenv ~/PYENV1
37 |
38 | # or directly from this repo
39 |
40 | ./rvirtualenv.py ~/PYENV2
41 |
42 | usage
43 | -----
44 |
45 | to enable environment, do::
46 |
47 | # on unix
48 | export PYTHONPATH=~/PYENV1:$PYTHONPATH
49 |
50 | # on windows
51 | set PYTHONPATH=c:\PYENV1;%PYTHONPATH%
52 |
53 | after that, you can call any python command (eg: ``pip`` or ``easy_install``, ``ipython``, ...)
54 | and it will have access to your virtual environment.
55 |
56 | if you don't want to mess up with environment, just call our wrapper::
57 |
58 | # on unix
59 | ~/PYENV1/bin/python [any [params]]
60 |
61 | # on win
62 | c:\PYENV1\bin\python.bat [any [params]]
63 |
64 | it should work with mod-wsgi ``python-path`` option as well,
65 | and you can enable it in runtime via ``site.addsitedir(venv_directory)``.
66 |
67 | tests
68 | -----
69 |
70 | if you are interested in testing this package, it should support many standard ways of running tests.
71 | nose is used for test discovery.
72 |
73 | you can run any of these commands:
74 |
75 | * ``python setup.py test``
76 | * ``nosetests``
77 | * ``./tests/test_all.py``
78 |
79 | package was tested on:
80 |
81 | * archlinux with python 3.2
82 | * archlinux with python 2.7
83 | * macosx 10.6 python 2.6
84 | * ms windows with python 2.6
85 | * ubuntu 10.04 python 2.6
86 | * debian lenny with python 2.5
87 | * debian etch with python 2.4
88 |
89 | but there is no build environment yet.
90 |
91 | why
92 | ---
93 |
94 | main reasons why this package came into existence:
95 |
96 | * it does not copy python binary
97 | * it does not symlink core python libraries
98 | * you can just set up PYTHONPATH env variable
99 | and you can use any system-wide command (eg: easy_install, pip)
100 | * you can tune ``pythonrc.py`` file to your needs
101 | in any curious ways (useful for debugging/testing)
102 |
103 | todo
104 | ----
105 |
106 | you can use the `issue tracker`__ for more (or in `TODO.rst` in this repo)
107 | but some of the long term goals are here
108 |
109 | * test building and installing some c extension
110 | * test install tools (``pip``, ``easy_install`` and others)
111 | * better virtualenv inheritance
112 | (and handle more virtualenvs defined on ``pythonpath``)
113 |
114 | __ https://github.com/kvbik/rvirtualenv/issues
115 |
116 | development
117 | -----------
118 |
119 | see http://github.com/kvbik/rvirtualenv
120 |
121 | changelog
122 | ---------
123 |
124 | 0.3.x
125 | ~~~~~
126 |
127 | aka branch `releases/rvirtualenv-0.3`__
128 |
129 | __ https://github.com/kvbik/rvirtualenv/tree/releases/rvirtualenv-0.3
130 |
131 | 0.3.2
132 | ~~~~~
133 |
134 | * sorry, this version does not work in interactive mode on windows, we will try hard to
135 | solve bill's issue
136 | * a subprocess call in ``python.py`` replaced with ``os.execvp``, which means less forks
137 | and `gunicorn`_ via `supervisor`_ should work when called via our ``python`` wrapper
138 | (see `issue #2`_ for more)
139 | * system-wide installed rvirtualenv does work and creates virtualenvs correctly
140 | - there were issues with read only fs for non privileged users
141 | * repository cleanup before `upload to pypi`_, so it should be installable
142 | (without any notes from build env - like ``#!/usr/bin/python2`` in `issue #1`_)
143 | * `setuptools_dummy`_ replaced in favour of plain `MANIFEST.in`_
144 |
145 | .. _setuptools_dummy: http://pypi.python.org/pypi/setuptools_dummy/
146 | .. _MANIFEST.in: http://docs.python.org/distutils/sourcedist.html#the-manifest-in-template
147 | .. _upload to pypi: http://pypi.python.org/pypi/RVirtualEnv
148 | .. _issue #1: https://github.com/kvbik/rvirtualenv/issues/1
149 | .. _gunicorn: http://gunicorn.org/
150 | .. _supervisor: http://supervisord.org/
151 | .. _issue #2: https://github.com/kvbik/rvirtualenv/pull/2
152 |
153 | 0.3.1
154 | ~~~~~
155 |
156 | * implemented cmd-line virtualenv compatible options
157 | (``--no-site-packages``, ``--python``, ``--prompt``)
158 | * no site packages option for pythonrc
159 | * non python data installed to python package (fixed bug introduced in `0.3.0`_)
160 |
161 | 0.3.0
162 | ~~~~~
163 |
164 | * `python3`_ support - it really works, tests are passing
165 | * support for `virtualenv wrapper`_ (via: ``source PY/bin/activate``)
166 | * inherit one virtualenv to another
167 | * ``bin/activate`` works, also on windows and relocatable
168 | * complete rewrite of venv
169 | * custom install command so you can define your own layout
170 | * proper functionality on macos and ubuntu
171 |
172 | .. _virtualenv wrapper: http://www.doughellmann.com/projects/virtualenvwrapper/
173 | .. _python3: http://diveintopython3.org/
174 |
175 | 0.2.x
176 | ~~~~~
177 |
178 | aka branch `releases/rvirtualenv-0.2`__
179 |
180 | __ https://github.com/kvbik/rvirtualenv/tree/releases/rvirtualenv-0.2
181 |
182 | * installing extensions into virtual environment works
183 | * not released, but merged to 0.3
184 |
185 | 0.2.3
186 | ~~~~~
187 |
188 | * fixing problems with relative path when creating virtualenv
189 | * more compatibility with pip and uninstalling system packages (``sys.real_prefix``)
190 | * tests passing with distribute_ (aka setuptools_ fork)
191 |
192 | .. _distribute: http://bitbucket.org/tarek/distribute/
193 | .. _setuptools: http://pypi.python.org/pypi/setuptools
194 |
195 | 0.2.2
196 | ~~~~~
197 |
198 | initial versions (<=0.2.2)
199 |
200 |
--------------------------------------------------------------------------------
/TODO.rst:
--------------------------------------------------------------------------------
1 |
2 | some more todos
3 | ---------------
4 |
5 | * do not fork so many processes, try to exec script in python
6 | something like ``python -c '__file__="neco.py"; execfile("neco.py")'`` (eg in ``pip/req.py``)
7 |
8 | * find the difference between pip installed and setup.py installed rvirtualenv -
9 | - all the \*.py files are executable in the second case on debian etch
10 | probably some distribute (setuptools fork) behaviour
11 |
12 | * add logging
13 |
14 | * clean up ``run_command`` (in ``rvirtualenv``, ``tests.test_rvirtualenv``)
15 | and use it for ``rvirtualenv.generate.run_setup``
16 |
17 | * once ``distutils.install`` command is monkey-patched,
18 | do the same for ``setuptools.develop``
19 |
20 | * run_command cleanup and tests
21 | test run_command
22 | use run_command from rvirtualenv in tests
23 | generate.run_setup VS run_command
24 |
25 | * use os.pathsep variable in python.py
26 |
27 | * virtualenv inheritance
28 | if you create one venv inside another it should take precedence
29 | not ready yet, try::
30 |
31 | ./rvirtualenv.py PY1
32 | source PY1/bin/activate
33 | ./rvirtualenv.py PY2
34 | ./PY2/bin/python -c "import rvirtualenvkeep; print(rvirtualenvkeep.__file__)"
35 |
36 | it should return rvirtualenvkeep from PY2
37 | .. i repaired this one, but sys.path is ugly sometimes now..
38 |
39 | * investigate and improve site.py execution
40 |
41 |
--------------------------------------------------------------------------------
/garbage/inherit/a:
--------------------------------------------------------------------------------
1 | prazdny python
2 |
3 | /usr/lib/python27.zip
4 | /usr/lib/python2.7
5 | /usr/lib/python2.7/plat-linux2
6 | /usr/lib/python2.7/lib-tk
7 | /usr/lib/python2.7/lib-old
8 | /usr/lib/python2.7/lib-dynload
9 | /usr/lib/python2.7/site-packages
10 | /usr/lib/python2.7/site-packages/setuptools-0.6c11.egg-info
11 |
12 |
--------------------------------------------------------------------------------
/garbage/inherit/b:
--------------------------------------------------------------------------------
1 | aktivovany python1
2 |
3 | /home/kvbik/GIT/github/kvbik/rvirtualenv/PY1/lib/python2.7/site-packages
4 | /home/kvbik/GIT/github/kvbik/rvirtualenv/PY1
5 | /home/kvbik/GIT/github/kvbik/rvirtualenv
6 | /usr/lib/python27.zip
7 | /usr/lib/python2.7
8 | /usr/lib/python2.7/plat-linux2
9 | /usr/lib/python2.7/lib-tk
10 | /usr/lib/python2.7/lib-old
11 | /usr/lib/python2.7/lib-dynload
12 | /usr/lib/python2.7/site-packages
13 | /usr/lib/python2.7/site-packages/setuptools-0.6c11.egg-info
14 |
15 |
--------------------------------------------------------------------------------
/garbage/inherit/c:
--------------------------------------------------------------------------------
1 | pysteny python2 z aktivovaneho python1
2 |
3 | /home/kvbik/GIT/github/kvbik/rvirtualenv/PY2/lib/python2.7/site-packages
4 | /home/kvbik/GIT/github/kvbik/rvirtualenv/PY1/lib/python2.7/site-packages
5 | /home/kvbik/GIT/github/kvbik/rvirtualenv/PY2
6 | /home/kvbik/GIT/github/kvbik/rvirtualenv/PY1
7 | /home/kvbik/GIT/github/kvbik/rvirtualenv
8 | /usr/lib/python27.zip
9 | /usr/lib/python2.7
10 | /usr/lib/python2.7/plat-linux2
11 | /usr/lib/python2.7/lib-tk
12 | /usr/lib/python2.7/lib-old
13 | /usr/lib/python2.7/lib-dynload
14 | /usr/lib/python2.7/site-packages
15 | /usr/lib/python2.7/site-packages/setuptools-0.6c11.egg-info
16 |
17 |
--------------------------------------------------------------------------------
/garbage/inherit/d:
--------------------------------------------------------------------------------
1 | python2 bez aktivovaneho python1
2 |
3 | /home/kvbik/GIT/github/kvbik/rvirtualenv/PY1
4 | /home/kvbik/GIT/github/kvbik/rvirtualenv/PY2
5 | /home/kvbik/GIT/github/kvbik/rvirtualenv/PY2/lib/python2.7/site-packages
6 | /home/kvbik/GIT/github/kvbik/rvirtualenv
7 | /home/kvbik/GIT/github/kvbik/rvirtualenv/PY1/lib/python2.7/site-packages
8 | /home/kvbik/GIT/github/kvbik/rvirtualenv/PY1
9 | /usr/lib/python27.zip
10 | /usr/lib/python2.7
11 | /usr/lib/python2.7/plat-linux2
12 | /usr/lib/python2.7/lib-tk
13 | /usr/lib/python2.7/lib-old
14 | /usr/lib/python2.7/lib-dynload
15 | /usr/lib/python2.7/site-packages
16 | /usr/lib/python2.7/site-packages/setuptools-0.6c11.egg-info
17 |
18 |
--------------------------------------------------------------------------------
/garbage/little-py/PY/pythonrc.py:
--------------------------------------------------------------------------------
1 |
2 | scheme = 'unix'
3 | #extra_paths = ['/path/to/inheriting/site-packages/',] # add some if you need access to other venvs
4 |
5 |
--------------------------------------------------------------------------------
/garbage/little-py/PY/rvirtualenvinstall.egg-info/PKG-INFO:
--------------------------------------------------------------------------------
1 | Metadata-Version: 1.0
2 | Name: rvirtualenvinstall
3 | Version: 0.1
4 | Summary: UNKNOWN
5 | Home-page: UNKNOWN
6 | Author: UNKNOWN
7 | Author-email: UNKNOWN
8 | License: UNKNOWN
9 | Description: UNKNOWN
10 | Platform: UNKNOWN
11 |
--------------------------------------------------------------------------------
/garbage/little-py/PY/rvirtualenvinstall.egg-info/entry_points.txt:
--------------------------------------------------------------------------------
1 | [distutils.commands]
2 | install = rvirtualenvinstall.install:install
3 | developp = rvirtualenvinstall.develop:develop
4 |
--------------------------------------------------------------------------------
/garbage/little-py/PY/rvirtualenvinstall/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kvbik/rvirtualenv/aaacde2171144bc3c1d8ab8668e36a0dbc29bf3d/garbage/little-py/PY/rvirtualenvinstall/__init__.py
--------------------------------------------------------------------------------
/garbage/little-py/PY/rvirtualenvinstall/boot.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from os import path
3 |
4 | import rvirtualenvinstall.install
5 | from rvirtualenvinstall import scheme
6 | import pythonrc
7 |
8 | base = path.abspath(path.dirname(pythonrc.__file__))
9 |
10 | # real_prefix is useful for pip and uninstalling system pkgs
11 | sys.real_prefix = sys.prefix
12 | # python uses this almost everywhere
13 | sys.prefix = base
14 |
15 | this_site_packages = [
16 | scheme.get_scheme(pythonrc.scheme, 'purelib'),
17 | scheme.get_scheme(pythonrc.scheme, 'platlib'),
18 | ]
19 |
20 | scheme.add_to_path(getattr(pythonrc, 'extra_paths', []))
21 | scheme.add_to_path(this_site_packages)
22 |
23 |
--------------------------------------------------------------------------------
/garbage/little-py/PY/rvirtualenvinstall/develop.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 | from setuptools.command.develop import develop as _develop
3 |
4 |
5 | class develop(_develop):
6 | description = "rvirtualenv's %s" % _develop.description
7 | def run(self):
8 | print('WTF')
9 |
10 | # don't know why isn't it overriden by entry_points
11 | setuptools.command.develop.develop = develop
12 |
13 |
--------------------------------------------------------------------------------
/garbage/little-py/PY/rvirtualenvinstall/install.py:
--------------------------------------------------------------------------------
1 | import distutils
2 | from distutils.command.install import install as _install
3 |
4 | import pythonrc
5 | from rvirtualenvinstall import scheme
6 |
7 |
8 | class install(_install):
9 | description = "rvirtualenv's %s" % _install.description
10 | def finalize_options(self):
11 | _install.finalize_options(self)
12 |
13 | vars = {'dist_name': self.distribution.get_name(),}
14 | self.install_purelib = scheme.get_scheme(pythonrc.scheme, 'purelib')
15 | self.install_platlib = scheme.get_scheme(pythonrc.scheme, 'purelib')
16 | self.install_headers = scheme.get_scheme(pythonrc.scheme, 'headers', vars=vars)
17 | self.install_scripts = scheme.get_scheme(pythonrc.scheme, 'scripts')
18 | self.install_data = scheme.get_scheme(pythonrc.scheme, 'data')
19 |
20 | if self.distribution.ext_modules: # has extensions: non-pure
21 | self.install_lib = self.install_platlib
22 | else:
23 | self.install_lib = self.install_purelib
24 |
25 | # monkey patch for distutils
26 | distutils.command.install.install = install
27 |
28 |
--------------------------------------------------------------------------------
/garbage/little-py/PY/rvirtualenvinstall/scheme.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from os import path
3 | import site
4 | from distutils.util import subst_vars
5 |
6 | INSTALL_SCHEMES = {
7 | 'custom': {
8 | 'purelib': '$base/lib/python/site-packages',
9 | 'platlib': '$base/lib/python$py_version_short/site-packages',
10 | 'headers': '$base/include/python$py_version_short/$dist_name',
11 | 'scripts': '$base/bin',
12 | 'data' : '$base',
13 | },
14 | 'unix': {
15 | 'purelib': '$base/lib/python$py_version_short/site-packages',
16 | 'platlib': '$base/lib/python$py_version_short/site-packages',
17 | 'headers': '$base/include/python$py_version_short/$dist_name',
18 | 'scripts': '$base/bin',
19 | 'data' : '$base',
20 | },
21 | 'windows': {
22 | 'purelib': '$base/Lib/site-packages',
23 | 'platlib': '$base/Lib/site-packages',
24 | 'headers': '$base/Include/$dist_name',
25 | 'scripts': '$base/Scripts',
26 | 'data' : '$base',
27 | },
28 | 'os2': {
29 | 'purelib': '$base/Lib/site-packages',
30 | 'platlib': '$base/Lib/site-packages',
31 | 'headers': '$base/Include/$dist_name',
32 | 'scripts': '$base/Scripts',
33 | 'data' : '$base',
34 | },
35 | 'darwin': {
36 | 'purelib': '$base/Library/Python$py_version_short/site-packages',
37 | 'platlib': '$base/Library/Python$py_version_short/site-packages',
38 | 'headers': '$base/Include/$dist_name',
39 | 'scripts': '$base/bin',
40 | 'data' : '$base',
41 | },
42 | }
43 |
44 | def guess_scheme():
45 | return 'unix'
46 |
47 | def get_scheme(platform, what, vars={}):
48 | # TODO: maybe use syslinux.get_path in next versions
49 | replace = {
50 | 'base': sys.prefix,
51 | 'py_version_short': sys.version[:3],
52 | 'dist_name': 'UNKNOWN',
53 | }
54 | replace.update(vars)
55 | line = INSTALL_SCHEMES[platform][what]
56 | line = path.join(*line.split('/'))
57 | return subst_vars(line, replace)
58 |
59 | def add_to_path(new_paths):
60 | "add dirs to the beginnig of sys.path"
61 | __plen = len(sys.path)
62 | for i in new_paths:
63 | if i not in sys.path:
64 | site.addsitedir(i)
65 | new = sys.path[__plen:]
66 | del sys.path[__plen:]
67 | sys.path[0:0] = new
68 |
69 |
--------------------------------------------------------------------------------
/garbage/little-py/PY/site.py:
--------------------------------------------------------------------------------
1 | def __boot():
2 | import sys, imp, os, os.path
3 | PYTHONPATH = os.environ.get('PYTHONPATH')
4 | if PYTHONPATH is None or (sys.platform=='win32' and not PYTHONPATH):
5 | PYTHONPATH = []
6 | else:
7 | PYTHONPATH = PYTHONPATH.split(os.pathsep)
8 |
9 | pic = getattr(sys,'path_importer_cache',{})
10 | stdpath = sys.path[len(PYTHONPATH):]
11 | mydir = os.path.dirname(__file__)
12 | #print "searching",stdpath,sys.path
13 |
14 | for item in stdpath:
15 | if item==mydir or not item:
16 | continue # skip if current dir. on Windows, or my own directory
17 | importer = pic.get(item)
18 | if importer is not None:
19 | loader = importer.find_module('site')
20 | if loader is not None:
21 | # This should actually reload the current module
22 | loader.load_module('site')
23 | break
24 | else:
25 | try:
26 | stream, path, descr = imp.find_module('site',[item])
27 | except ImportError:
28 | continue
29 | if stream is None:
30 | continue
31 | try:
32 | # This should actually reload the current module
33 | imp.load_module('site',stream,path,descr)
34 | finally:
35 | stream.close()
36 | break
37 | else:
38 | raise ImportError("Couldn't find the real 'site' module")
39 |
40 | #print "loaded", __file__
41 |
42 | known_paths = dict([(makepath(item)[1],1) for item in sys.path]) # 2.2 comp
43 |
44 | oldpos = getattr(sys,'__egginsert',0) # save old insertion position
45 | sys.__egginsert = 0 # and reset the current one
46 |
47 | for item in PYTHONPATH:
48 | addsitedir(item)
49 |
50 | sys.__egginsert += oldpos # restore effective old position
51 |
52 | d,nd = makepath(stdpath[0])
53 | insert_at = None
54 | new_path = []
55 |
56 | for item in sys.path:
57 | p,np = makepath(item)
58 |
59 | if np==nd and insert_at is None:
60 | # We've hit the first 'system' path entry, so added entries go here
61 | insert_at = len(new_path)
62 |
63 | if np in known_paths or insert_at is None:
64 | new_path.append(item)
65 | else:
66 | # new path after the insert point, back-insert it
67 | new_path.insert(insert_at, item)
68 | insert_at += 1
69 |
70 | sys.path[:] = new_path
71 |
72 | import rvirtualenvinstall.boot
73 |
74 | if __name__=='site':
75 | __boot()
76 | del __boot
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/garbage/notes:
--------------------------------------------------------------------------------
1 |
2 | ------------------------
3 |
4 | rvirtualenv
5 | ~~~~~~~~~~~
6 |
7 | vytvorit rvirtualenv.main
8 | presunout kod z __init__ a procistit, aby copy&spol bylo rozumne importovatelne
9 |
10 | rvirtualenv.utils
11 | nasypat tam helpers jako: basepath (rvirtualenv.__file__), is_windows, apod
12 |
13 | nosetests
14 | monkeypatched sys.stdout a encoding
15 |
16 |
17 | ------------------
18 |
19 | -- zpetne kompatibilni (2 a 3) python kod
20 | http://www.voidspace.org.uk/python/articles/porting-mock-to-python-3.shtml
21 |
22 | mozna by stacilo predat setup.py install --moje-schema
23 | http://docs.python.org/install/index.html
24 | http://stackoverflow.com/questions/1710839/custom-distutils-commands
25 | http://stackoverflow.com/questions/1321270/how-to-extend-distutils-with-a-simple-post-install-script
26 |
27 | grr...
28 | /usr/lib/python3.2/distutils/core.py
29 | /usr/lib/python3.2/distutils/dist.py
30 | /usr/lib/python3.2/distutils/cmd.py
31 |
32 |
33 | --------------------------------
34 |
35 | -- ve virtualenvu se taky ruzne fidluje s macosem
36 | https://bitbucket.org/ianb/virtualenv/src/204f249efc32/virtualenv_support/site.py#cl-570
37 |
38 | -- jo, jezdezovi to nejde
39 | http://d.pr/pdiK
40 | http://d.pr/FeCk
41 |
42 | -- v djangu taky fidlujou se schematem
43 | http://code.djangoproject.com/browser/django/trunk/setup.py#L39
44 |
45 | -- kez by mi to nekdo spravil..
46 | https://gist.github.com/709004/
47 |
48 | -- pak bych se konecne zaradil sem
49 | http://pypi.python.org/pypi?:action=browse&c=533&show=all
50 |
51 |
52 |
53 | .FFFFF.FFF
54 | ======================================================================
55 | FAIL: test_install_venv_keep_package (tests.test_generate.TestGenerate)
56 | ----------------------------------------------------------------------
57 | Traceback (most recent call last):
58 | File "/Users/kvbik/GIT/rvirtualenv/tests/test_generate.py", line 33, in test_install_venv_keep_package
59 | self.assertTrue(len(l) > 1)
60 | AssertionError
61 |
62 |
63 | /usr/bin/python -c "import sys; sys.prefix=r'/tmp/keke'; __file__='setup.py'; execfile('setup.py')" install
64 |
65 | /System/Library/Frameworks/Python.framework/Versions/2.5/Resources/Python.app/Contents/MacOS/Python -c "import sys; sys.real_prefix=r'/tmp/keke'; __file__='setup.py'; execfile('setup.py')" install
66 |
67 |
68 |
69 | i = distutils.command.install.install(distutils.core.Distribution())
70 | i.initialize_options()
71 | i.finalize_options()
72 |
73 | /usr/bin/python -c "import sys; sys.prefix=r'/tmp/keke'; __file__='setup.py'; execfile('setup.py')" install
74 |
75 |
76 | -- asi proste pridam jinej install command do venvu, podobne jako rozbijej tyhlencti upload
77 | http://bazaar.launchpad.net/~python-distutils-extra-hackers/python-distutils-extra/debian/files
78 | http://aur.archlinux.org/packages/python-distutils-extra-bzr/python-distutils-extra-bzr/PKGBUILD
79 |
80 |
81 |
--------------------------------------------------------------------------------
/garbage/schemes/install.linux.py27.normal.txt:
--------------------------------------------------------------------------------
1 | install_base: /usr
2 | install_data: /usr
3 | install_headers: /usr/include/python2.7/UNKNOWN
4 | install_lib: /usr/lib/python2.7/site-packages/
5 | install_libbase: /usr/lib/python2.7/site-packages
6 | install_path_file: 1
7 | install_platbase: /usr
8 | install_platlib: /usr/lib/python2.7/site-packages
9 | install_purelib: /usr/lib/python2.7/site-packages
10 | install_scripts: /usr/bin
11 | install_userbase: /home/kvbik/.local
12 | install_usersite: /home/kvbik/.local/lib/python2.7/site-packages
13 |
--------------------------------------------------------------------------------
/garbage/schemes/install.linux.py27.prefixed.txt:
--------------------------------------------------------------------------------
1 | install_base: /tmp/keke
2 | install_data: /tmp/keke
3 | install_headers: /tmp/keke/include/python2.7/UNKNOWN
4 | install_lib: /tmp/keke/lib/python2.7/site-packages/
5 | install_libbase: /tmp/keke/lib/python2.7/site-packages
6 | install_path_file: 1
7 | install_platbase: /usr
8 | install_platlib: /usr/lib/python2.7/site-packages
9 | install_purelib: /tmp/keke/lib/python2.7/site-packages
10 | install_scripts: /tmp/keke/bin
11 | install_userbase: /home/kvbik/.local
12 | install_usersite: /home/kvbik/.local/lib/python2.7/site-packages
13 |
--------------------------------------------------------------------------------
/garbage/schemes/install.macosmini.py26.normal.txt:
--------------------------------------------------------------------------------
1 | install_base: /System/Library/Frameworks/Python.framework/Versions/2.6
2 | install_data: /System/Library/Frameworks/Python.framework/Versions/2.6
3 | install_headers: /System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6/UNKNOWN
4 | install_lib: /Library/Python/2.6/site-packages/
5 | install_libbase: /Library/Python/2.6/site-packages
6 | install_path_file: 1
7 | install_platbase: /System/Library/Frameworks/Python.framework/Versions/2.6
8 | install_platlib: /Library/Python/2.6/site-packages
9 | install_purelib: /Library/Python/2.6/site-packages
10 | install_scripts: /usr/local/bin
11 | install_userbase: /Users/jakub.vysoky/.local
12 | install_usersite: /Users/jakub.vysoky/.local/lib/python2.6/site-packages
13 |
--------------------------------------------------------------------------------
/garbage/schemes/install.macosmini.py26.prefixed.txt:
--------------------------------------------------------------------------------
1 | install_base: /tmp/keke
2 | install_data: /tmp/keke
3 | install_headers: /tmp/keke/include/python2.6/UNKNOWN
4 | install_lib: /Library/Python/2.6/site-packages/
5 | install_libbase: /Library/Python/2.6/site-packages
6 | install_path_file: 1
7 | install_platbase: /System/Library/Frameworks/Python.framework/Versions/2.6
8 | install_platlib: /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages
9 | install_purelib: /Library/Python/2.6/site-packages
10 | install_scripts: /usr/local/bin
11 | install_userbase: /Users/jakub.vysoky/.local
12 | install_usersite: /Users/jakub.vysoky/.local/lib/python2.6/site-packages
13 |
--------------------------------------------------------------------------------
/garbage/schemes/install.macossrv.py25.normal.txt:
--------------------------------------------------------------------------------
1 | install_base: /System/Library/Frameworks/Python.framework/Versions/2.5
2 | install_data: /System/Library/Frameworks/Python.framework/Versions/2.5
3 | install_headers: /System/Library/Frameworks/Python.framework/Versions/2.5/include/python2.5/UNKNOWN
4 | install_lib: /Library/Python/2.5/site-packages/
5 | install_libbase: /Library/Python/2.5/site-packages
6 | install_path_file: 1
7 | install_platbase: /System/Library/Frameworks/Python.framework/Versions/2.5
8 | install_platlib: /Library/Python/2.5/site-packages
9 | install_purelib: /Library/Python/2.5/site-packages
10 | install_scripts: /usr/local/bin
11 |
--------------------------------------------------------------------------------
/garbage/schemes/install.macossrv.py25.prefixed.txt:
--------------------------------------------------------------------------------
1 | install_base: /tmp/keke
2 | install_data: /tmp/keke
3 | install_headers: /tmp/keke/include/python2.5/UNKNOWN
4 | install_lib: /Library/Python/2.5/site-packages/
5 | install_libbase: /Library/Python/2.5/site-packages
6 | install_path_file: 1
7 | install_platbase: /System/Library/Frameworks/Python.framework/Versions/2.5
8 | install_platlib: /System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages
9 | install_purelib: /Library/Python/2.5/site-packages
10 | install_scripts: /usr/local/bin
11 |
--------------------------------------------------------------------------------
/garbage/schemes/install.py:
--------------------------------------------------------------------------------
1 |
2 | import distutils.command.install
3 | import distutils.core
4 | from distutils import command, core
5 |
6 | i = command.install.install(core.Distribution())
7 |
8 | i.initialize_options()
9 | i.finalize_options()
10 |
11 | for a in dir(i):
12 | if a.startswith('install_'):
13 | print '%s: %s' % (a, getattr(i, a))
14 |
15 |
--------------------------------------------------------------------------------
/garbage/schemes/install.sh:
--------------------------------------------------------------------------------
1 |
2 | python -c "import sys; sys.prefix=r'/tmp/keke'; __file__='install.py'; execfile('install.py')"
3 |
4 |
--------------------------------------------------------------------------------
/garbage/schemes/install.win.py26.normal.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kvbik/rvirtualenv/aaacde2171144bc3c1d8ab8668e36a0dbc29bf3d/garbage/schemes/install.win.py26.normal.txt
--------------------------------------------------------------------------------
/garbage/schemes/install.win.py26.prefixed.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kvbik/rvirtualenv/aaacde2171144bc3c1d8ab8668e36a0dbc29bf3d/garbage/schemes/install.win.py26.prefixed.txt
--------------------------------------------------------------------------------
/garbage/sysconfig/sysconfig27.py:
--------------------------------------------------------------------------------
1 | """Provide access to Python's configuration information.
2 |
3 | """
4 | import sys
5 | import os
6 | from os.path import pardir, realpath
7 | from string import Template
8 |
9 | _INSTALL_SCHEMES = {
10 | 'posix_prefix': {
11 | 'stdlib': '{base}/lib/python{py_version_short}',
12 | 'platstdlib': '{platbase}/lib/python{py_version_short}',
13 | 'purelib': '{base}/lib/python{py_version_short}/site-packages',
14 | 'platlib': '{platbase}/lib/python{py_version_short}/site-packages',
15 | 'include': '{base}/include/python{py_version_short}',
16 | 'platinclude': '{platbase}/include/python{py_version_short}',
17 | 'scripts': '{base}/bin',
18 | 'data': '{base}',
19 | },
20 | 'posix_home': {
21 | 'stdlib': '{base}/lib/python',
22 | 'platstdlib': '{base}/lib/python',
23 | 'purelib': '{base}/lib/python',
24 | 'platlib': '{base}/lib/python',
25 | 'include': '{base}/include/python',
26 | 'platinclude': '{base}/include/python',
27 | 'scripts': '{base}/bin',
28 | 'data' : '{base}',
29 | },
30 | 'nt': {
31 | 'stdlib': '{base}/Lib',
32 | 'platstdlib': '{base}/Lib',
33 | 'purelib': '{base}/Lib/site-packages',
34 | 'platlib': '{base}/Lib/site-packages',
35 | 'include': '{base}/Include',
36 | 'platinclude': '{base}/Include',
37 | 'scripts': '{base}/Scripts',
38 | 'data' : '{base}',
39 | },
40 | 'os2': {
41 | 'stdlib': '{base}/Lib',
42 | 'platstdlib': '{base}/Lib',
43 | 'purelib': '{base}/Lib/site-packages',
44 | 'platlib': '{base}/Lib/site-packages',
45 | 'include': '{base}/Include',
46 | 'platinclude': '{base}/Include',
47 | 'scripts': '{base}/Scripts',
48 | 'data' : '{base}',
49 | },
50 | 'os2_home': {
51 | 'stdlib': '{userbase}/lib/python{py_version_short}',
52 | 'platstdlib': '{userbase}/lib/python{py_version_short}',
53 | 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
54 | 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
55 | 'include': '{userbase}/include/python{py_version_short}',
56 | 'scripts': '{userbase}/bin',
57 | 'data' : '{userbase}',
58 | },
59 | 'nt_user': {
60 | 'stdlib': '{userbase}/Python{py_version_nodot}',
61 | 'platstdlib': '{userbase}/Python{py_version_nodot}',
62 | 'purelib': '{userbase}/Python{py_version_nodot}/site-packages',
63 | 'platlib': '{userbase}/Python{py_version_nodot}/site-packages',
64 | 'include': '{userbase}/Python{py_version_nodot}/Include',
65 | 'scripts': '{userbase}/Scripts',
66 | 'data' : '{userbase}',
67 | },
68 | 'posix_user': {
69 | 'stdlib': '{userbase}/lib/python{py_version_short}',
70 | 'platstdlib': '{userbase}/lib/python{py_version_short}',
71 | 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
72 | 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
73 | 'include': '{userbase}/include/python{py_version_short}',
74 | 'scripts': '{userbase}/bin',
75 | 'data' : '{userbase}',
76 | },
77 | 'osx_framework_user': {
78 | 'stdlib': '{userbase}/lib/python',
79 | 'platstdlib': '{userbase}/lib/python',
80 | 'purelib': '{userbase}/lib/python/site-packages',
81 | 'platlib': '{userbase}/lib/python/site-packages',
82 | 'include': '{userbase}/include',
83 | 'scripts': '{userbase}/bin',
84 | 'data' : '{userbase}',
85 | },
86 | }
87 |
88 | _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
89 | 'scripts', 'data')
90 | _PY_VERSION = sys.version.split()[0]
91 | _PY_VERSION_SHORT = sys.version[:3]
92 | _PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2]
93 | _PREFIX = os.path.normpath(sys.prefix)
94 | _EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
95 | _CONFIG_VARS = None
96 | _USER_BASE = None
97 |
98 | def _safe_realpath(path):
99 | try:
100 | return realpath(path)
101 | except OSError:
102 | return path
103 |
104 | if sys.executable:
105 | _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable))
106 | else:
107 | # sys.executable can be empty if argv[0] has been changed and Python is
108 | # unable to retrieve the real program name
109 | _PROJECT_BASE = _safe_realpath(os.getcwd())
110 |
111 | if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower():
112 | _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir))
113 | # PC/VS7.1
114 | if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower():
115 | _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
116 | # PC/AMD64
117 | if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower():
118 | _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
119 |
120 | def is_python_build():
121 | for fn in ("Setup.dist", "Setup.local"):
122 | if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)):
123 | return True
124 | return False
125 |
126 | _PYTHON_BUILD = is_python_build()
127 |
128 | if _PYTHON_BUILD:
129 | for scheme in ('posix_prefix', 'posix_home'):
130 | _INSTALL_SCHEMES[scheme]['include'] = '{projectbase}/Include'
131 | _INSTALL_SCHEMES[scheme]['platinclude'] = '{srcdir}'
132 |
133 | def _format_template(s, **kwargs):
134 | if hasattr(s, 'format'):
135 | return s.format(**kwargs)
136 | t = Template(s.replace('{', '${'))
137 | return t.substitute(**kwargs)
138 |
139 | def _subst_vars(s, local_vars):
140 | try:
141 | return _format_template(s, **local_vars)
142 | except KeyError:
143 | try:
144 | return _format_template(s, **os.environ)
145 | except KeyError, var:
146 | raise AttributeError('{%s}' % var)
147 |
148 | def _extend_dict(target_dict, other_dict):
149 | target_keys = target_dict.keys()
150 | for key, value in other_dict.items():
151 | if key in target_keys:
152 | continue
153 | target_dict[key] = value
154 |
155 | def _expand_vars(scheme, vars):
156 | res = {}
157 | if vars is None:
158 | vars = {}
159 | _extend_dict(vars, get_config_vars())
160 |
161 | for key, value in _INSTALL_SCHEMES[scheme].items():
162 | if os.name in ('posix', 'nt'):
163 | value = os.path.expanduser(value)
164 | res[key] = os.path.normpath(_subst_vars(value, vars))
165 | return res
166 |
167 | def _get_default_scheme():
168 | if os.name == 'posix':
169 | # the default scheme for posix is posix_prefix
170 | return 'posix_prefix'
171 | return os.name
172 |
173 | def _getuserbase():
174 | env_base = os.environ.get("PYTHONUSERBASE", None)
175 | def joinuser(*args):
176 | return os.path.expanduser(os.path.join(*args))
177 |
178 | # what about 'os2emx', 'riscos' ?
179 | if os.name == "nt":
180 | base = os.environ.get("APPDATA") or "~"
181 | return env_base and env_base or joinuser(base, "Python")
182 |
183 | if sys.platform == "darwin":
184 | framework = get_config_var("PYTHONFRAMEWORK")
185 | if framework:
186 | return joinuser("~", "Library", framework, "%d.%d"%(
187 | sys.version_info[:2]))
188 |
189 | return env_base and env_base or joinuser("~", ".local")
190 |
191 |
192 | def _parse_makefile(filename, vars=None):
193 | """Parse a Makefile-style file.
194 |
195 | A dictionary containing name/value pairs is returned. If an
196 | optional dictionary is passed in as the second argument, it is
197 | used instead of a new dictionary.
198 | """
199 | import re
200 | # Regexes needed for parsing Makefile (and similar syntaxes,
201 | # like old-style Setup files).
202 | _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
203 | _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
204 | _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
205 |
206 | if vars is None:
207 | vars = {}
208 | done = {}
209 | notdone = {}
210 |
211 | f = open(filename)
212 | try:
213 | lines = f.readlines()
214 | finally:
215 | f.close()
216 |
217 | for line in lines:
218 | if line.startswith('#') or line.strip() == '':
219 | continue
220 | m = _variable_rx.match(line)
221 | if m:
222 | n, v = m.group(1, 2)
223 | v = v.strip()
224 | # `$$' is a literal `$' in make
225 | tmpv = v.replace('$$', '')
226 |
227 | if "$" in tmpv:
228 | notdone[n] = v
229 | else:
230 | try:
231 | v = int(v)
232 | except ValueError:
233 | # insert literal `$'
234 | done[n] = v.replace('$$', '$')
235 | else:
236 | done[n] = v
237 |
238 | # do variable interpolation here
239 | while notdone:
240 | for name in notdone.keys():
241 | value = notdone[name]
242 | m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
243 | if m:
244 | n = m.group(1)
245 | found = True
246 | if n in done:
247 | item = str(done[n])
248 | elif n in notdone:
249 | # get it on a subsequent round
250 | found = False
251 | elif n in os.environ:
252 | # do it like make: fall back to environment
253 | item = os.environ[n]
254 | else:
255 | done[n] = item = ""
256 | if found:
257 | after = value[m.end():]
258 | value = value[:m.start()] + item + after
259 | if "$" in after:
260 | notdone[name] = value
261 | else:
262 | try: value = int(value)
263 | except ValueError:
264 | done[name] = value.strip()
265 | else:
266 | done[name] = value
267 | del notdone[name]
268 | else:
269 | # bogus variable reference; just drop it since we can't deal
270 | del notdone[name]
271 | # strip spurious spaces
272 | for k, v in done.items():
273 | if isinstance(v, str):
274 | done[k] = v.strip()
275 |
276 | # save the results in the global dictionary
277 | vars.update(done)
278 | return vars
279 |
280 |
281 | def _get_makefile_filename():
282 | if _PYTHON_BUILD:
283 | return os.path.join(_PROJECT_BASE, "Makefile")
284 | return os.path.join(get_path('stdlib'), "config", "Makefile")
285 |
286 |
287 | def _init_posix(vars):
288 | """Initialize the module as appropriate for POSIX systems."""
289 | # load the installed Makefile:
290 | makefile = _get_makefile_filename()
291 | try:
292 | _parse_makefile(makefile, vars)
293 | except IOError, e:
294 | msg = "invalid Python installation: unable to open %s" % makefile
295 | if hasattr(e, "strerror"):
296 | msg = msg + " (%s)" % e.strerror
297 | raise IOError(msg)
298 |
299 | # load the installed pyconfig.h:
300 | config_h = get_config_h_filename()
301 | try:
302 | f = open(config_h)
303 | try:
304 | parse_config_h(f, vars)
305 | finally:
306 | f.close()
307 | except IOError, e:
308 | msg = "invalid Python installation: unable to open %s" % config_h
309 | if hasattr(e, "strerror"):
310 | msg = msg + " (%s)" % e.strerror
311 | raise IOError(msg)
312 |
313 | # On MacOSX we need to check the setting of the environment variable
314 | # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so
315 | # it needs to be compatible.
316 | # If it isn't set we set it to the configure-time value
317 | if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in vars:
318 | cfg_target = vars['MACOSX_DEPLOYMENT_TARGET']
319 | cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '')
320 | if cur_target == '':
321 | cur_target = cfg_target
322 | os.putenv('MACOSX_DEPLOYMENT_TARGET', cfg_target)
323 | elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')):
324 | msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" '
325 | 'during configure' % (cur_target, cfg_target))
326 | raise IOError(msg)
327 |
328 | # On AIX, there are wrong paths to the linker scripts in the Makefile
329 | # -- these paths are relative to the Python source, but when installed
330 | # the scripts are in another directory.
331 | if _PYTHON_BUILD:
332 | vars['LDSHARED'] = vars['BLDSHARED']
333 |
334 | def _init_non_posix(vars):
335 | """Initialize the module as appropriate for NT"""
336 | # set basic install directories
337 | vars['LIBDEST'] = get_path('stdlib')
338 | vars['BINLIBDEST'] = get_path('platstdlib')
339 | vars['INCLUDEPY'] = get_path('include')
340 | vars['SO'] = '.pyd'
341 | vars['EXE'] = '.exe'
342 | vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
343 | vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))
344 |
345 | #
346 | # public APIs
347 | #
348 |
349 |
350 | def parse_config_h(fp, vars=None):
351 | """Parse a config.h-style file.
352 |
353 | A dictionary containing name/value pairs is returned. If an
354 | optional dictionary is passed in as the second argument, it is
355 | used instead of a new dictionary.
356 | """
357 | import re
358 | if vars is None:
359 | vars = {}
360 | define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
361 | undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
362 |
363 | while True:
364 | line = fp.readline()
365 | if not line:
366 | break
367 | m = define_rx.match(line)
368 | if m:
369 | n, v = m.group(1, 2)
370 | try: v = int(v)
371 | except ValueError: pass
372 | vars[n] = v
373 | else:
374 | m = undef_rx.match(line)
375 | if m:
376 | vars[m.group(1)] = 0
377 | return vars
378 |
379 | def get_config_h_filename():
380 | """Returns the path of pyconfig.h."""
381 | if _PYTHON_BUILD:
382 | if os.name == "nt":
383 | inc_dir = os.path.join(_PROJECT_BASE, "PC")
384 | else:
385 | inc_dir = _PROJECT_BASE
386 | else:
387 | inc_dir = get_path('platinclude')
388 | return os.path.join(inc_dir, 'pyconfig.h')
389 |
390 | def get_scheme_names():
391 | """Returns a tuple containing the schemes names."""
392 | schemes = _INSTALL_SCHEMES.keys()
393 | schemes.sort()
394 | return tuple(schemes)
395 |
396 | def get_path_names():
397 | """Returns a tuple containing the paths names."""
398 | return _SCHEME_KEYS
399 |
400 | def get_paths(scheme=_get_default_scheme(), vars=None, expand=True):
401 | """Returns a mapping containing an install scheme.
402 |
403 | ``scheme`` is the install scheme name. If not provided, it will
404 | return the default scheme for the current platform.
405 | """
406 | if expand:
407 | return _expand_vars(scheme, vars)
408 | else:
409 | return _INSTALL_SCHEMES[scheme]
410 |
411 | def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True):
412 | """Returns a path corresponding to the scheme.
413 |
414 | ``scheme`` is the install scheme name.
415 | """
416 | return get_paths(scheme, vars, expand)[name]
417 |
418 | def get_config_vars(*args):
419 | """With no arguments, return a dictionary of all configuration
420 | variables relevant for the current platform.
421 |
422 | On Unix, this means every variable defined in Python's installed Makefile;
423 | On Windows and Mac OS it's a much smaller set.
424 |
425 | With arguments, return a list of values that result from looking up
426 | each argument in the configuration variable dictionary.
427 | """
428 | import re
429 | global _CONFIG_VARS
430 | if _CONFIG_VARS is None:
431 | _CONFIG_VARS = {}
432 | # Normalized versions of prefix and exec_prefix are handy to have;
433 | # in fact, these are the standard versions used most places in the
434 | # Distutils.
435 | _CONFIG_VARS['prefix'] = _PREFIX
436 | _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX
437 | _CONFIG_VARS['py_version'] = _PY_VERSION
438 | _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
439 | _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2]
440 | _CONFIG_VARS['base'] = _PREFIX
441 | _CONFIG_VARS['platbase'] = _EXEC_PREFIX
442 | _CONFIG_VARS['projectbase'] = _PROJECT_BASE
443 |
444 | if os.name in ('nt', 'os2'):
445 | _init_non_posix(_CONFIG_VARS)
446 | if os.name == 'posix':
447 | _init_posix(_CONFIG_VARS)
448 |
449 | # Setting 'userbase' is done below the call to the
450 | # init function to enable using 'get_config_var' in
451 | # the init-function.
452 | _CONFIG_VARS['userbase'] = _getuserbase()
453 |
454 | if 'srcdir' not in _CONFIG_VARS:
455 | _CONFIG_VARS['srcdir'] = _PROJECT_BASE
456 |
457 | # Convert srcdir into an absolute path if it appears necessary.
458 | # Normally it is relative to the build directory. However, during
459 | # testing, for example, we might be running a non-installed python
460 | # from a different directory.
461 | if _PYTHON_BUILD and os.name == "posix":
462 | base = _PROJECT_BASE
463 | try:
464 | cwd = os.getcwd()
465 | except OSError:
466 | cwd = None
467 | if (not os.path.isabs(_CONFIG_VARS['srcdir']) and
468 | base != cwd):
469 | # srcdir is relative and we are not in the same directory
470 | # as the executable. Assume executable is in the build
471 | # directory and make srcdir absolute.
472 | srcdir = os.path.join(base, _CONFIG_VARS['srcdir'])
473 | _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir)
474 |
475 | if sys.platform == 'darwin':
476 | kernel_version = os.uname()[2] # Kernel version (8.4.3)
477 | major_version = int(kernel_version.split('.')[0])
478 |
479 | if major_version < 8:
480 | # On Mac OS X before 10.4, check if -arch and -isysroot
481 | # are in CFLAGS or LDFLAGS and remove them if they are.
482 | # This is needed when building extensions on a 10.3 system
483 | # using a universal build of python.
484 | for key in ('LDFLAGS', 'BASECFLAGS',
485 | # a number of derived variables. These need to be
486 | # patched up as well.
487 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
488 | flags = _CONFIG_VARS[key]
489 | flags = re.sub('-arch\s+\w+\s', ' ', flags)
490 | flags = re.sub('-isysroot [^ \t]*', ' ', flags)
491 | _CONFIG_VARS[key] = flags
492 | else:
493 | # Allow the user to override the architecture flags using
494 | # an environment variable.
495 | # NOTE: This name was introduced by Apple in OSX 10.5 and
496 | # is used by several scripting languages distributed with
497 | # that OS release.
498 | if 'ARCHFLAGS' in os.environ:
499 | arch = os.environ['ARCHFLAGS']
500 | for key in ('LDFLAGS', 'BASECFLAGS',
501 | # a number of derived variables. These need to be
502 | # patched up as well.
503 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
504 |
505 | flags = _CONFIG_VARS[key]
506 | flags = re.sub('-arch\s+\w+\s', ' ', flags)
507 | flags = flags + ' ' + arch
508 | _CONFIG_VARS[key] = flags
509 |
510 | # If we're on OSX 10.5 or later and the user tries to
511 | # compiles an extension using an SDK that is not present
512 | # on the current machine it is better to not use an SDK
513 | # than to fail.
514 | #
515 | # The major usecase for this is users using a Python.org
516 | # binary installer on OSX 10.6: that installer uses
517 | # the 10.4u SDK, but that SDK is not installed by default
518 | # when you install Xcode.
519 | #
520 | CFLAGS = _CONFIG_VARS.get('CFLAGS', '')
521 | m = re.search('-isysroot\s+(\S+)', CFLAGS)
522 | if m is not None:
523 | sdk = m.group(1)
524 | if not os.path.exists(sdk):
525 | for key in ('LDFLAGS', 'BASECFLAGS',
526 | # a number of derived variables. These need to be
527 | # patched up as well.
528 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
529 |
530 | flags = _CONFIG_VARS[key]
531 | flags = re.sub('-isysroot\s+\S+(\s|$)', ' ', flags)
532 | _CONFIG_VARS[key] = flags
533 |
534 | if args:
535 | vals = []
536 | for name in args:
537 | vals.append(_CONFIG_VARS.get(name))
538 | return vals
539 | else:
540 | return _CONFIG_VARS
541 |
542 | def get_config_var(name):
543 | """Return the value of a single variable using the dictionary returned by
544 | 'get_config_vars()'.
545 |
546 | Equivalent to get_config_vars().get(name)
547 | """
548 | return get_config_vars().get(name)
549 |
550 | def get_platform():
551 | """Return a string that identifies the current platform.
552 |
553 | This is used mainly to distinguish platform-specific build directories and
554 | platform-specific built distributions. Typically includes the OS name
555 | and version and the architecture (as supplied by 'os.uname()'),
556 | although the exact information included depends on the OS; eg. for IRIX
557 | the architecture isn't particularly important (IRIX only runs on SGI
558 | hardware), but for Linux the kernel version isn't particularly
559 | important.
560 |
561 | Examples of returned values:
562 | linux-i586
563 | linux-alpha (?)
564 | solaris-2.6-sun4u
565 | irix-5.3
566 | irix64-6.2
567 |
568 | Windows will return one of:
569 | win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
570 | win-ia64 (64bit Windows on Itanium)
571 | win32 (all others - specifically, sys.platform is returned)
572 |
573 | For other non-POSIX platforms, currently just returns 'sys.platform'.
574 | """
575 | import re
576 | if os.name == 'nt':
577 | # sniff sys.version for architecture.
578 | prefix = " bit ("
579 | i = sys.version.find(prefix)
580 | if i == -1:
581 | return sys.platform
582 | j = sys.version.find(")", i)
583 | look = sys.version[i+len(prefix):j].lower()
584 | if look == 'amd64':
585 | return 'win-amd64'
586 | if look == 'itanium':
587 | return 'win-ia64'
588 | return sys.platform
589 |
590 | if os.name != "posix" or not hasattr(os, 'uname'):
591 | # XXX what about the architecture? NT is Intel or Alpha,
592 | # Mac OS is M68k or PPC, etc.
593 | return sys.platform
594 |
595 | # Try to distinguish various flavours of Unix
596 | osname, host, release, version, machine = os.uname()
597 |
598 | # Convert the OS name to lowercase, remove '/' characters
599 | # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh")
600 | osname = osname.lower().replace('/', '')
601 | machine = machine.replace(' ', '_')
602 | machine = machine.replace('/', '-')
603 |
604 | if osname[:5] == "linux":
605 | # At least on Linux/Intel, 'machine' is the processor --
606 | # i386, etc.
607 | # XXX what about Alpha, SPARC, etc?
608 | return "%s-%s" % (osname, machine)
609 | elif osname[:5] == "sunos":
610 | if release[0] >= "5": # SunOS 5 == Solaris 2
611 | osname = "solaris"
612 | release = "%d.%s" % (int(release[0]) - 3, release[2:])
613 | # fall through to standard osname-release-machine representation
614 | elif osname[:4] == "irix": # could be "irix64"!
615 | return "%s-%s" % (osname, release)
616 | elif osname[:3] == "aix":
617 | return "%s-%s.%s" % (osname, version, release)
618 | elif osname[:6] == "cygwin":
619 | osname = "cygwin"
620 | rel_re = re.compile (r'[\d.]+')
621 | m = rel_re.match(release)
622 | if m:
623 | release = m.group()
624 | elif osname[:6] == "darwin":
625 | #
626 | # For our purposes, we'll assume that the system version from
627 | # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set
628 | # to. This makes the compatibility story a bit more sane because the
629 | # machine is going to compile and link as if it were
630 | # MACOSX_DEPLOYMENT_TARGET.
631 | cfgvars = get_config_vars()
632 | macver = os.environ.get('MACOSX_DEPLOYMENT_TARGET')
633 | if not macver:
634 | macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET')
635 |
636 | if 1:
637 | # Always calculate the release of the running machine,
638 | # needed to determine if we can build fat binaries or not.
639 |
640 | macrelease = macver
641 | # Get the system version. Reading this plist is a documented
642 | # way to get the system version (see the documentation for
643 | # the Gestalt Manager)
644 | try:
645 | f = open('/System/Library/CoreServices/SystemVersion.plist')
646 | except IOError:
647 | # We're on a plain darwin box, fall back to the default
648 | # behaviour.
649 | pass
650 | else:
651 | try:
652 | m = re.search(
653 | r'ProductUserVisibleVersion\s*' +
654 | r'(.*?)', f.read())
655 | f.close()
656 | if m is not None:
657 | macrelease = '.'.join(m.group(1).split('.')[:2])
658 | # else: fall back to the default behaviour
659 | finally:
660 | f.close()
661 |
662 | if not macver:
663 | macver = macrelease
664 |
665 | if macver:
666 | release = macver
667 | osname = "macosx"
668 |
669 | if (macrelease + '.') >= '10.4.' and \
670 | '-arch' in get_config_vars().get('CFLAGS', '').strip():
671 | # The universal build will build fat binaries, but not on
672 | # systems before 10.4
673 | #
674 | # Try to detect 4-way universal builds, those have machine-type
675 | # 'universal' instead of 'fat'.
676 |
677 | machine = 'fat'
678 | cflags = get_config_vars().get('CFLAGS')
679 |
680 | archs = re.findall('-arch\s+(\S+)', cflags)
681 | archs = tuple(sorted(set(archs)))
682 |
683 | if len(archs) == 1:
684 | machine = archs[0]
685 | elif archs == ('i386', 'ppc'):
686 | machine = 'fat'
687 | elif archs == ('i386', 'x86_64'):
688 | machine = 'intel'
689 | elif archs == ('i386', 'ppc', 'x86_64'):
690 | machine = 'fat3'
691 | elif archs == ('ppc64', 'x86_64'):
692 | machine = 'fat64'
693 | elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'):
694 | machine = 'universal'
695 | else:
696 | raise ValueError(
697 | "Don't know machine value for archs=%r"%(archs,))
698 |
699 | elif machine == 'i386':
700 | # On OSX the machine type returned by uname is always the
701 | # 32-bit variant, even if the executable architecture is
702 | # the 64-bit variant
703 | if sys.maxint >= 2**32:
704 | machine = 'x86_64'
705 |
706 | elif machine in ('PowerPC', 'Power_Macintosh'):
707 | # Pick a sane name for the PPC architecture.
708 | # See 'i386' case
709 | if sys.maxint >= 2**32:
710 | machine = 'ppc64'
711 | else:
712 | machine = 'ppc'
713 |
714 | return "%s-%s-%s" % (osname, release, machine)
715 |
716 |
717 | def get_python_version():
718 | return _PY_VERSION_SHORT
719 |
--------------------------------------------------------------------------------
/garbage/sysconfig/sysconfig32.py:
--------------------------------------------------------------------------------
1 | """Provide access to Python's configuration information.
2 |
3 | """
4 | import sys
5 | import os
6 | from os.path import pardir, realpath
7 |
8 | __all__ = [
9 | 'get_config_h_filename',
10 | 'get_config_var',
11 | 'get_config_vars',
12 | 'get_makefile_filename',
13 | 'get_path',
14 | 'get_path_names',
15 | 'get_paths',
16 | 'get_platform',
17 | 'get_python_version',
18 | 'get_scheme_names',
19 | 'parse_config_h',
20 | ]
21 |
22 | _INSTALL_SCHEMES = {
23 | 'posix_prefix': {
24 | 'stdlib': '{base}/lib/python{py_version_short}',
25 | 'platstdlib': '{platbase}/lib/python{py_version_short}',
26 | 'purelib': '{base}/lib/python{py_version_short}/site-packages',
27 | 'platlib': '{platbase}/lib/python{py_version_short}/site-packages',
28 | 'include':
29 | '{base}/include/python{py_version_short}{abiflags}',
30 | 'platinclude':
31 | '{platbase}/include/python{py_version_short}{abiflags}',
32 | 'scripts': '{base}/bin',
33 | 'data': '{base}',
34 | },
35 | 'posix_home': {
36 | 'stdlib': '{base}/lib/python',
37 | 'platstdlib': '{base}/lib/python',
38 | 'purelib': '{base}/lib/python',
39 | 'platlib': '{base}/lib/python',
40 | 'include': '{base}/include/python',
41 | 'platinclude': '{base}/include/python',
42 | 'scripts': '{base}/bin',
43 | 'data' : '{base}',
44 | },
45 | 'nt': {
46 | 'stdlib': '{base}/Lib',
47 | 'platstdlib': '{base}/Lib',
48 | 'purelib': '{base}/Lib/site-packages',
49 | 'platlib': '{base}/Lib/site-packages',
50 | 'include': '{base}/Include',
51 | 'platinclude': '{base}/Include',
52 | 'scripts': '{base}/Scripts',
53 | 'data' : '{base}',
54 | },
55 | 'os2': {
56 | 'stdlib': '{base}/Lib',
57 | 'platstdlib': '{base}/Lib',
58 | 'purelib': '{base}/Lib/site-packages',
59 | 'platlib': '{base}/Lib/site-packages',
60 | 'include': '{base}/Include',
61 | 'platinclude': '{base}/Include',
62 | 'scripts': '{base}/Scripts',
63 | 'data' : '{base}',
64 | },
65 | 'os2_home': {
66 | 'stdlib': '{userbase}/lib/python{py_version_short}',
67 | 'platstdlib': '{userbase}/lib/python{py_version_short}',
68 | 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
69 | 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
70 | 'include': '{userbase}/include/python{py_version_short}',
71 | 'scripts': '{userbase}/bin',
72 | 'data' : '{userbase}',
73 | },
74 | 'nt_user': {
75 | 'stdlib': '{userbase}/Python{py_version_nodot}',
76 | 'platstdlib': '{userbase}/Python{py_version_nodot}',
77 | 'purelib': '{userbase}/Python{py_version_nodot}/site-packages',
78 | 'platlib': '{userbase}/Python{py_version_nodot}/site-packages',
79 | 'include': '{userbase}/Python{py_version_nodot}/Include',
80 | 'scripts': '{userbase}/Scripts',
81 | 'data' : '{userbase}',
82 | },
83 | 'posix_user': {
84 | 'stdlib': '{userbase}/lib/python{py_version_short}',
85 | 'platstdlib': '{userbase}/lib/python{py_version_short}',
86 | 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
87 | 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
88 | 'include': '{userbase}/include/python{py_version_short}',
89 | 'scripts': '{userbase}/bin',
90 | 'data' : '{userbase}',
91 | },
92 | 'osx_framework_user': {
93 | 'stdlib': '{userbase}/lib/python',
94 | 'platstdlib': '{userbase}/lib/python',
95 | 'purelib': '{userbase}/lib/python/site-packages',
96 | 'platlib': '{userbase}/lib/python/site-packages',
97 | 'include': '{userbase}/include',
98 | 'scripts': '{userbase}/bin',
99 | 'data' : '{userbase}',
100 | },
101 | }
102 |
103 | _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
104 | 'scripts', 'data')
105 | _PY_VERSION = sys.version.split()[0]
106 | _PY_VERSION_SHORT = sys.version[:3]
107 | _PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2]
108 | _PREFIX = os.path.normpath(sys.prefix)
109 | _EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
110 | _CONFIG_VARS = None
111 | _USER_BASE = None
112 |
113 | def _safe_realpath(path):
114 | try:
115 | return realpath(path)
116 | except OSError:
117 | return path
118 |
119 | if sys.executable:
120 | _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable))
121 | else:
122 | # sys.executable can be empty if argv[0] has been changed and Python is
123 | # unable to retrieve the real program name
124 | _PROJECT_BASE = _safe_realpath(os.getcwd())
125 |
126 | if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower():
127 | _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir))
128 | # PC/VS7.1
129 | if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower():
130 | _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
131 | # PC/AMD64
132 | if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower():
133 | _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
134 |
135 | def is_python_build():
136 | for fn in ("Setup.dist", "Setup.local"):
137 | if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)):
138 | return True
139 | return False
140 |
141 | _PYTHON_BUILD = is_python_build()
142 |
143 | if _PYTHON_BUILD:
144 | for scheme in ('posix_prefix', 'posix_home'):
145 | _INSTALL_SCHEMES[scheme]['include'] = '{srcdir}/Include'
146 | _INSTALL_SCHEMES[scheme]['platinclude'] = '{projectbase}/.'
147 |
148 | def _subst_vars(s, local_vars):
149 | try:
150 | return s.format(**local_vars)
151 | except KeyError:
152 | try:
153 | return s.format(**os.environ)
154 | except KeyError as var:
155 | raise AttributeError('{%s}' % var)
156 |
157 | def _extend_dict(target_dict, other_dict):
158 | target_keys = target_dict.keys()
159 | for key, value in other_dict.items():
160 | if key in target_keys:
161 | continue
162 | target_dict[key] = value
163 |
164 | def _expand_vars(scheme, vars):
165 | res = {}
166 | if vars is None:
167 | vars = {}
168 | _extend_dict(vars, get_config_vars())
169 |
170 | for key, value in _INSTALL_SCHEMES[scheme].items():
171 | if os.name in ('posix', 'nt'):
172 | value = os.path.expanduser(value)
173 | res[key] = os.path.normpath(_subst_vars(value, vars))
174 | return res
175 |
176 | def _get_default_scheme():
177 | if os.name == 'posix':
178 | # the default scheme for posix is posix_prefix
179 | return 'posix_prefix'
180 | return os.name
181 |
182 | def _getuserbase():
183 | env_base = os.environ.get("PYTHONUSERBASE", None)
184 | def joinuser(*args):
185 | return os.path.expanduser(os.path.join(*args))
186 |
187 | # what about 'os2emx', 'riscos' ?
188 | if os.name == "nt":
189 | base = os.environ.get("APPDATA") or "~"
190 | return env_base if env_base else joinuser(base, "Python")
191 |
192 | if sys.platform == "darwin":
193 | framework = get_config_var("PYTHONFRAMEWORK")
194 | if framework:
195 | return env_base if env_base else joinuser("~", "Library", framework, "%d.%d"%(
196 | sys.version_info[:2]))
197 |
198 | return env_base if env_base else joinuser("~", ".local")
199 |
200 |
201 | def _parse_makefile(filename, vars=None):
202 | """Parse a Makefile-style file.
203 |
204 | A dictionary containing name/value pairs is returned. If an
205 | optional dictionary is passed in as the second argument, it is
206 | used instead of a new dictionary.
207 | """
208 | import re
209 | # Regexes needed for parsing Makefile (and similar syntaxes,
210 | # like old-style Setup files).
211 | _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
212 | _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
213 | _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
214 |
215 | if vars is None:
216 | vars = {}
217 | done = {}
218 | notdone = {}
219 |
220 | with open(filename, errors="surrogateescape") as f:
221 | lines = f.readlines()
222 |
223 | for line in lines:
224 | if line.startswith('#') or line.strip() == '':
225 | continue
226 | m = _variable_rx.match(line)
227 | if m:
228 | n, v = m.group(1, 2)
229 | v = v.strip()
230 | # `$$' is a literal `$' in make
231 | tmpv = v.replace('$$', '')
232 |
233 | if "$" in tmpv:
234 | notdone[n] = v
235 | else:
236 | try:
237 | v = int(v)
238 | except ValueError:
239 | # insert literal `$'
240 | done[n] = v.replace('$$', '$')
241 | else:
242 | done[n] = v
243 |
244 | # do variable interpolation here
245 | variables = list(notdone.keys())
246 |
247 | # Variables with a 'PY_' prefix in the makefile. These need to
248 | # be made available without that prefix through sysconfig.
249 | # Special care is needed to ensure that variable expansion works, even
250 | # if the expansion uses the name without a prefix.
251 | renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS')
252 |
253 | while len(variables) > 0:
254 | for name in tuple(variables):
255 | value = notdone[name]
256 | m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
257 | if m is not None:
258 | n = m.group(1)
259 | found = True
260 | if n in done:
261 | item = str(done[n])
262 | elif n in notdone:
263 | # get it on a subsequent round
264 | found = False
265 | elif n in os.environ:
266 | # do it like make: fall back to environment
267 | item = os.environ[n]
268 |
269 | elif n in renamed_variables:
270 | if name.startswith('PY_') and name[3:] in renamed_variables:
271 | item = ""
272 |
273 | elif 'PY_' + n in notdone:
274 | found = False
275 |
276 | else:
277 | item = str(done['PY_' + n])
278 |
279 | else:
280 | done[n] = item = ""
281 |
282 | if found:
283 | after = value[m.end():]
284 | value = value[:m.start()] + item + after
285 | if "$" in after:
286 | notdone[name] = value
287 | else:
288 | try:
289 | value = int(value)
290 | except ValueError:
291 | done[name] = value.strip()
292 | else:
293 | done[name] = value
294 | variables.remove(name)
295 |
296 | if name.startswith('PY_') \
297 | and name[3:] in renamed_variables:
298 |
299 | name = name[3:]
300 | if name not in done:
301 | done[name] = value
302 |
303 |
304 | else:
305 | # bogus variable reference; just drop it since we can't deal
306 | variables.remove(name)
307 |
308 | # strip spurious spaces
309 | for k, v in done.items():
310 | if isinstance(v, str):
311 | done[k] = v.strip()
312 |
313 | # save the results in the global dictionary
314 | vars.update(done)
315 | return vars
316 |
317 |
318 | def get_makefile_filename():
319 | """Return the path of the Makefile."""
320 | if _PYTHON_BUILD:
321 | return os.path.join(_PROJECT_BASE, "Makefile")
322 | return os.path.join(get_path('stdlib'),
323 | 'config-{}{}'.format(_PY_VERSION_SHORT, sys.abiflags),
324 | 'Makefile')
325 |
326 |
327 | def _init_posix(vars):
328 | """Initialize the module as appropriate for POSIX systems."""
329 | # load the installed Makefile:
330 | makefile = get_makefile_filename()
331 | try:
332 | _parse_makefile(makefile, vars)
333 | except IOError as e:
334 | msg = "invalid Python installation: unable to open %s" % makefile
335 | if hasattr(e, "strerror"):
336 | msg = msg + " (%s)" % e.strerror
337 | raise IOError(msg)
338 | # load the installed pyconfig.h:
339 | config_h = get_config_h_filename()
340 | try:
341 | with open(config_h) as f:
342 | parse_config_h(f, vars)
343 | except IOError as e:
344 | msg = "invalid Python installation: unable to open %s" % config_h
345 | if hasattr(e, "strerror"):
346 | msg = msg + " (%s)" % e.strerror
347 | raise IOError(msg)
348 | # On MacOSX we need to check the setting of the environment variable
349 | # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so
350 | # it needs to be compatible.
351 | # If it isn't set we set it to the configure-time value
352 | if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in vars:
353 | cfg_target = vars['MACOSX_DEPLOYMENT_TARGET']
354 | cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '')
355 | if cur_target == '':
356 | cur_target = cfg_target
357 | os.putenv('MACOSX_DEPLOYMENT_TARGET', cfg_target)
358 | elif (list(map(int, cfg_target.split('.'))) >
359 | list(map(int, cur_target.split('.')))):
360 | msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" '
361 | 'during configure' % (cur_target, cfg_target))
362 | raise IOError(msg)
363 | # On AIX, there are wrong paths to the linker scripts in the Makefile
364 | # -- these paths are relative to the Python source, but when installed
365 | # the scripts are in another directory.
366 | if _PYTHON_BUILD:
367 | vars['LDSHARED'] = vars['BLDSHARED']
368 |
369 | def _init_non_posix(vars):
370 | """Initialize the module as appropriate for NT"""
371 | # set basic install directories
372 | vars['LIBDEST'] = get_path('stdlib')
373 | vars['BINLIBDEST'] = get_path('platstdlib')
374 | vars['INCLUDEPY'] = get_path('include')
375 | vars['SO'] = '.pyd'
376 | vars['EXE'] = '.exe'
377 | vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
378 | vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))
379 |
380 | #
381 | # public APIs
382 | #
383 |
384 |
385 | def parse_config_h(fp, vars=None):
386 | """Parse a config.h-style file.
387 |
388 | A dictionary containing name/value pairs is returned. If an
389 | optional dictionary is passed in as the second argument, it is
390 | used instead of a new dictionary.
391 | """
392 | import re
393 | if vars is None:
394 | vars = {}
395 | define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
396 | undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
397 |
398 | while True:
399 | line = fp.readline()
400 | if not line:
401 | break
402 | m = define_rx.match(line)
403 | if m:
404 | n, v = m.group(1, 2)
405 | try: v = int(v)
406 | except ValueError: pass
407 | vars[n] = v
408 | else:
409 | m = undef_rx.match(line)
410 | if m:
411 | vars[m.group(1)] = 0
412 | return vars
413 |
414 | def get_config_h_filename():
415 | """Return the path of pyconfig.h."""
416 | if _PYTHON_BUILD:
417 | if os.name == "nt":
418 | inc_dir = os.path.join(_PROJECT_BASE, "PC")
419 | else:
420 | inc_dir = _PROJECT_BASE
421 | else:
422 | inc_dir = get_path('platinclude')
423 | return os.path.join(inc_dir, 'pyconfig.h')
424 |
425 | def get_scheme_names():
426 | """Return a tuple containing the schemes names."""
427 | schemes = list(_INSTALL_SCHEMES.keys())
428 | schemes.sort()
429 | return tuple(schemes)
430 |
431 | def get_path_names():
432 | """Return a tuple containing the paths names."""
433 | return _SCHEME_KEYS
434 |
435 | def get_paths(scheme=_get_default_scheme(), vars=None, expand=True):
436 | """Return a mapping containing an install scheme.
437 |
438 | ``scheme`` is the install scheme name. If not provided, it will
439 | return the default scheme for the current platform.
440 | """
441 | if expand:
442 | return _expand_vars(scheme, vars)
443 | else:
444 | return _INSTALL_SCHEMES[scheme]
445 |
446 | def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True):
447 | """Return a path corresponding to the scheme.
448 |
449 | ``scheme`` is the install scheme name.
450 | """
451 | return get_paths(scheme, vars, expand)[name]
452 |
453 | def get_config_vars(*args):
454 | """With no arguments, return a dictionary of all configuration
455 | variables relevant for the current platform.
456 |
457 | On Unix, this means every variable defined in Python's installed Makefile;
458 | On Windows and Mac OS it's a much smaller set.
459 |
460 | With arguments, return a list of values that result from looking up
461 | each argument in the configuration variable dictionary.
462 | """
463 | import re
464 | global _CONFIG_VARS
465 | if _CONFIG_VARS is None:
466 | _CONFIG_VARS = {}
467 | # Normalized versions of prefix and exec_prefix are handy to have;
468 | # in fact, these are the standard versions used most places in the
469 | # Distutils.
470 | _CONFIG_VARS['prefix'] = _PREFIX
471 | _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX
472 | _CONFIG_VARS['py_version'] = _PY_VERSION
473 | _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
474 | _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2]
475 | _CONFIG_VARS['base'] = _PREFIX
476 | _CONFIG_VARS['platbase'] = _EXEC_PREFIX
477 | _CONFIG_VARS['projectbase'] = _PROJECT_BASE
478 | try:
479 | _CONFIG_VARS['abiflags'] = sys.abiflags
480 | except AttributeError:
481 | # sys.abiflags may not be defined on all platforms.
482 | _CONFIG_VARS['abiflags'] = ''
483 |
484 | if os.name in ('nt', 'os2'):
485 | _init_non_posix(_CONFIG_VARS)
486 | if os.name == 'posix':
487 | _init_posix(_CONFIG_VARS)
488 | # Setting 'userbase' is done below the call to the
489 | # init function to enable using 'get_config_var' in
490 | # the init-function.
491 | _CONFIG_VARS['userbase'] = _getuserbase()
492 |
493 | if 'srcdir' not in _CONFIG_VARS:
494 | _CONFIG_VARS['srcdir'] = _PROJECT_BASE
495 | else:
496 | _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['srcdir'])
497 |
498 |
499 | # Convert srcdir into an absolute path if it appears necessary.
500 | # Normally it is relative to the build directory. However, during
501 | # testing, for example, we might be running a non-installed python
502 | # from a different directory.
503 | if _PYTHON_BUILD and os.name == "posix":
504 | base = _PROJECT_BASE
505 | try:
506 | cwd = os.getcwd()
507 | except OSError:
508 | cwd = None
509 | if (not os.path.isabs(_CONFIG_VARS['srcdir']) and
510 | base != cwd):
511 | # srcdir is relative and we are not in the same directory
512 | # as the executable. Assume executable is in the build
513 | # directory and make srcdir absolute.
514 | srcdir = os.path.join(base, _CONFIG_VARS['srcdir'])
515 | _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir)
516 |
517 | if sys.platform == 'darwin':
518 | kernel_version = os.uname()[2] # Kernel version (8.4.3)
519 | major_version = int(kernel_version.split('.')[0])
520 |
521 | if major_version < 8:
522 | # On Mac OS X before 10.4, check if -arch and -isysroot
523 | # are in CFLAGS or LDFLAGS and remove them if they are.
524 | # This is needed when building extensions on a 10.3 system
525 | # using a universal build of python.
526 | for key in ('LDFLAGS', 'BASECFLAGS',
527 | # a number of derived variables. These need to be
528 | # patched up as well.
529 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
530 | flags = _CONFIG_VARS[key]
531 | flags = re.sub('-arch\s+\w+\s', ' ', flags)
532 | flags = re.sub('-isysroot [^ \t]*', ' ', flags)
533 | _CONFIG_VARS[key] = flags
534 | else:
535 | # Allow the user to override the architecture flags using
536 | # an environment variable.
537 | # NOTE: This name was introduced by Apple in OSX 10.5 and
538 | # is used by several scripting languages distributed with
539 | # that OS release.
540 | if 'ARCHFLAGS' in os.environ:
541 | arch = os.environ['ARCHFLAGS']
542 | for key in ('LDFLAGS', 'BASECFLAGS',
543 | # a number of derived variables. These need to be
544 | # patched up as well.
545 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
546 |
547 | flags = _CONFIG_VARS[key]
548 | flags = re.sub('-arch\s+\w+\s', ' ', flags)
549 | flags = flags + ' ' + arch
550 | _CONFIG_VARS[key] = flags
551 |
552 | # If we're on OSX 10.5 or later and the user tries to
553 | # compiles an extension using an SDK that is not present
554 | # on the current machine it is better to not use an SDK
555 | # than to fail.
556 | #
557 | # The major usecase for this is users using a Python.org
558 | # binary installer on OSX 10.6: that installer uses
559 | # the 10.4u SDK, but that SDK is not installed by default
560 | # when you install Xcode.
561 | #
562 | CFLAGS = _CONFIG_VARS.get('CFLAGS', '')
563 | m = re.search('-isysroot\s+(\S+)', CFLAGS)
564 | if m is not None:
565 | sdk = m.group(1)
566 | if not os.path.exists(sdk):
567 | for key in ('LDFLAGS', 'BASECFLAGS',
568 | # a number of derived variables. These need to be
569 | # patched up as well.
570 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
571 |
572 | flags = _CONFIG_VARS[key]
573 | flags = re.sub('-isysroot\s+\S+(\s|$)', ' ', flags)
574 | _CONFIG_VARS[key] = flags
575 |
576 | if args:
577 | vals = []
578 | for name in args:
579 | vals.append(_CONFIG_VARS.get(name))
580 | return vals
581 | else:
582 | return _CONFIG_VARS
583 |
584 | def get_config_var(name):
585 | """Return the value of a single variable using the dictionary returned by
586 | 'get_config_vars()'.
587 |
588 | Equivalent to get_config_vars().get(name)
589 | """
590 | return get_config_vars().get(name)
591 |
592 | def get_platform():
593 | """Return a string that identifies the current platform.
594 |
595 | This is used mainly to distinguish platform-specific build directories and
596 | platform-specific built distributions. Typically includes the OS name
597 | and version and the architecture (as supplied by 'os.uname()'),
598 | although the exact information included depends on the OS; eg. for IRIX
599 | the architecture isn't particularly important (IRIX only runs on SGI
600 | hardware), but for Linux the kernel version isn't particularly
601 | important.
602 |
603 | Examples of returned values:
604 | linux-i586
605 | linux-alpha (?)
606 | solaris-2.6-sun4u
607 | irix-5.3
608 | irix64-6.2
609 |
610 | Windows will return one of:
611 | win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
612 | win-ia64 (64bit Windows on Itanium)
613 | win32 (all others - specifically, sys.platform is returned)
614 |
615 | For other non-POSIX platforms, currently just returns 'sys.platform'.
616 | """
617 | import re
618 | if os.name == 'nt':
619 | # sniff sys.version for architecture.
620 | prefix = " bit ("
621 | i = sys.version.find(prefix)
622 | if i == -1:
623 | return sys.platform
624 | j = sys.version.find(")", i)
625 | look = sys.version[i+len(prefix):j].lower()
626 | if look == 'amd64':
627 | return 'win-amd64'
628 | if look == 'itanium':
629 | return 'win-ia64'
630 | return sys.platform
631 |
632 | if os.name != "posix" or not hasattr(os, 'uname'):
633 | # XXX what about the architecture? NT is Intel or Alpha,
634 | # Mac OS is M68k or PPC, etc.
635 | return sys.platform
636 |
637 | # Try to distinguish various flavours of Unix
638 | osname, host, release, version, machine = os.uname()
639 |
640 | # Convert the OS name to lowercase, remove '/' characters
641 | # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh")
642 | osname = osname.lower().replace('/', '')
643 | machine = machine.replace(' ', '_')
644 | machine = machine.replace('/', '-')
645 |
646 | if osname[:5] == "linux":
647 | # At least on Linux/Intel, 'machine' is the processor --
648 | # i386, etc.
649 | # XXX what about Alpha, SPARC, etc?
650 | return "%s-%s" % (osname, machine)
651 | elif osname[:5] == "sunos":
652 | if release[0] >= "5": # SunOS 5 == Solaris 2
653 | osname = "solaris"
654 | release = "%d.%s" % (int(release[0]) - 3, release[2:])
655 | # fall through to standard osname-release-machine representation
656 | elif osname[:4] == "irix": # could be "irix64"!
657 | return "%s-%s" % (osname, release)
658 | elif osname[:3] == "aix":
659 | return "%s-%s.%s" % (osname, version, release)
660 | elif osname[:6] == "cygwin":
661 | osname = "cygwin"
662 | rel_re = re.compile (r'[\d.]+')
663 | m = rel_re.match(release)
664 | if m:
665 | release = m.group()
666 | elif osname[:6] == "darwin":
667 | #
668 | # For our purposes, we'll assume that the system version from
669 | # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set
670 | # to. This makes the compatibility story a bit more sane because the
671 | # machine is going to compile and link as if it were
672 | # MACOSX_DEPLOYMENT_TARGET.
673 | cfgvars = get_config_vars()
674 | macver = os.environ.get('MACOSX_DEPLOYMENT_TARGET')
675 | if not macver:
676 | macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET')
677 |
678 | if 1:
679 | # Always calculate the release of the running machine,
680 | # needed to determine if we can build fat binaries or not.
681 |
682 | macrelease = macver
683 | # Get the system version. Reading this plist is a documented
684 | # way to get the system version (see the documentation for
685 | # the Gestalt Manager)
686 | try:
687 | f = open('/System/Library/CoreServices/SystemVersion.plist')
688 | except IOError:
689 | # We're on a plain darwin box, fall back to the default
690 | # behaviour.
691 | pass
692 | else:
693 | try:
694 | m = re.search(
695 | r'ProductUserVisibleVersion\s*' +
696 | r'(.*?)', f.read())
697 | f.close()
698 | if m is not None:
699 | macrelease = '.'.join(m.group(1).split('.')[:2])
700 | # else: fall back to the default behaviour
701 | finally:
702 | f.close()
703 |
704 | if not macver:
705 | macver = macrelease
706 |
707 | if macver:
708 | release = macver
709 | osname = "macosx"
710 |
711 | if (macrelease + '.') >= '10.4.' and \
712 | '-arch' in get_config_vars().get('CFLAGS', '').strip():
713 | # The universal build will build fat binaries, but not on
714 | # systems before 10.4
715 | #
716 | # Try to detect 4-way universal builds, those have machine-type
717 | # 'universal' instead of 'fat'.
718 |
719 | machine = 'fat'
720 | cflags = get_config_vars().get('CFLAGS')
721 |
722 | archs = re.findall('-arch\s+(\S+)', cflags)
723 | archs = tuple(sorted(set(archs)))
724 |
725 | if len(archs) == 1:
726 | machine = archs[0]
727 | elif archs == ('i386', 'ppc'):
728 | machine = 'fat'
729 | elif archs == ('i386', 'x86_64'):
730 | machine = 'intel'
731 | elif archs == ('i386', 'ppc', 'x86_64'):
732 | machine = 'fat3'
733 | elif archs == ('ppc64', 'x86_64'):
734 | machine = 'fat64'
735 | elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'):
736 | machine = 'universal'
737 | else:
738 | raise ValueError(
739 | "Don't know machine value for archs=%r"%(archs,))
740 |
741 | elif machine == 'i386':
742 | # On OSX the machine type returned by uname is always the
743 | # 32-bit variant, even if the executable architecture is
744 | # the 64-bit variant
745 | if sys.maxsize >= 2**32:
746 | machine = 'x86_64'
747 |
748 | elif machine in ('PowerPC', 'Power_Macintosh'):
749 | # Pick a sane name for the PPC architecture.
750 | # See 'i386' case
751 | if sys.maxsize >= 2**32:
752 | machine = 'ppc64'
753 | else:
754 | machine = 'ppc'
755 |
756 | return "%s-%s-%s" % (osname, release, machine)
757 |
758 |
759 | def get_python_version():
760 | return _PY_VERSION_SHORT
761 |
762 | def _print_dict(title, data):
763 | for index, (key, value) in enumerate(sorted(data.items())):
764 | if index == 0:
765 | print('{0}: '.format(title))
766 | print('\t{0} = "{1}"'.format(key, value))
767 |
768 | def _main():
769 | """Display all information sysconfig detains."""
770 | print('Platform: "{0}"'.format(get_platform()))
771 | print('Python version: "{0}"'.format(get_python_version()))
772 | print('Current installation scheme: "{0}"'.format(_get_default_scheme()))
773 | print('')
774 | _print_dict('Paths', get_paths())
775 | print('')
776 | _print_dict('Variables', get_config_vars())
777 |
778 | if __name__ == '__main__':
779 | _main()
780 |
--------------------------------------------------------------------------------
/rvirtualenv.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from rvirtualenv import main
4 |
5 | if __name__ == '__main__':
6 | main()
7 |
8 |
--------------------------------------------------------------------------------
/rvirtualenv/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | import os
3 | import sys
4 | from os import path
5 | from optparse import OptionParser
6 | from subprocess import Popen, PIPE
7 |
8 | import rvirtualenv
9 | from rvirtualenv.copy import copy
10 | from rvirtualenv.generate import generate
11 |
12 |
13 | VERSION = (0, 3, 2)
14 | __version__ = VERSION
15 | __versionstr__ = '.'.join(map(str, VERSION))
16 |
17 |
18 | def get_parser():
19 | '''
20 | options parser
21 | '''
22 | parser = OptionParser(usage="%prog [OPTIONS] DEST_DIR")
23 | parser.add_option(
24 | '--no-site-packages', dest='sitepackages', action='store_false', default=True,
25 | help="Don't give access to the global site-packages dir to the virtual environment"
26 | )
27 | parser.add_option(
28 | '-p', '--python', dest='python', metavar='PYTHON_EXE', default=sys.executable,
29 | help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 '
30 | 'interpreter to create the new environment. The default is the interpreter that '
31 | 'virtualenv was installed with (%s)' % sys.executable
32 | )
33 | parser.add_option(
34 | '--prompt=', dest='prompt',
35 | help='Provides an alternative prompt prefix for this environment'
36 | )
37 | return parser
38 |
39 | def get_base():
40 | '''
41 | path to rvirtualenv
42 | '''
43 | return path.abspath(path.join(path.dirname(rvirtualenv.__file__), path.pardir))
44 |
45 | def run_command(cmd):
46 | shell = sys.platform != 'win32'
47 | p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=shell)
48 | return map(lambda b: b.decode(sys.stdout.encoding or 'UTF-8'), p.communicate())
49 |
50 | def create_subprocess(python, venv, sitepackages, prompt):
51 | '''
52 | install rvirtualenv with given interpreter
53 | '''
54 | cmd = ('''%s -c "import sys; sys.path.insert(0, %r); '''
55 | '''from rvirtualenv import create; create(%r, %s, %r)"''') % \
56 | (python, get_base(), venv, sitepackages, prompt)
57 | return run_command(cmd)
58 |
59 | def create(name, sitepackages, prompt):
60 | '''
61 | create rvirtualenv
62 | '''
63 | venv = path.join(os.getcwd(), name)
64 | copy(venv)
65 | generate(venv, sitepackages=sitepackages, prompt=prompt)
66 |
67 | def main(argv=None):
68 | '''
69 | main call for rvirtualenv command
70 | '''
71 | if argv is None:
72 | argv = sys.argv
73 |
74 | parser = get_parser()
75 | options, name = parser.parse_args(argv[1:])
76 |
77 | if len(name) != 1:
78 | parser.print_help()
79 | parser.exit('Invalid parameter count.')
80 |
81 | create_subprocess(options.python, name[0], options.sitepackages, options.prompt)
82 |
83 |
--------------------------------------------------------------------------------
/rvirtualenv/copy.py:
--------------------------------------------------------------------------------
1 |
2 | from os.path import join, dirname, isfile
3 | from os import makedirs, walk, remove
4 | import shutil
5 |
6 | import rvirtualenv
7 |
8 |
9 | def ignore(src, names):
10 | def invalid(s):
11 | if '__pycache__' in s:
12 | return True
13 | if s.endswith('pyc'):
14 | return True
15 | return False
16 | ignored = set()
17 | ignored.update(( i for i in names if invalid(i) ))
18 | return ignored
19 |
20 | def remove_ignored(src, dst, ignore=None):
21 | for base, dirs, files in walk(dst):
22 | ignored = set()
23 | if ignore is not None:
24 | ignored = ignore(base.replace(dst, src), dirs+files)
25 | for i in ignored:
26 | f = join(base, i)
27 | if not isfile(f):
28 | shutil.rmtree(f, True)
29 | else:
30 | remove(f)
31 |
32 | def copytree(src, dst, symlinks=False, ignore=None):
33 | shutil.copytree(src, dst, symlinks)
34 | remove_ignored(src, dst, ignore)
35 |
36 | def copy(where):
37 | '''
38 | main function for copying template/venv into specified new virtualenv
39 | '''
40 | base = dirname(rvirtualenv.__file__)
41 | copytree(join(base, 'template', 'venv'), where, ignore=ignore)
42 | makedirs(join(where, 'src'))
43 | copytree(join(base, 'template', 'inst'), join(where, 'src', 'rvirtualenvkeep'), ignore=ignore)
44 | copytree(join(base, 'rvirtualenvinstall'), join(where, 'rvirtualenvinstall'), ignore=ignore)
45 |
46 |
--------------------------------------------------------------------------------
/rvirtualenv/generate.py:
--------------------------------------------------------------------------------
1 |
2 | import os
3 | from os import path
4 | import sys
5 | from subprocess import Popen, PIPE
6 |
7 | import rvirtualenv
8 | from rvirtualenv.rvirtualenvinstall.scheme import guess_scheme
9 |
10 |
11 | def run_setup(pythonpath, install_dir):
12 | '''
13 | install couple of helper modules via distutils
14 | because it creates its directory (via the correct schema)
15 |
16 | it must be called in subprocess
17 | because of possible setuptools monkeypatching
18 | '''
19 | os.environ['PYTHONPATH'] = pythonpath
20 | install = [
21 | '"%s"' % sys.executable,
22 | path.join(install_dir, 'setup.py'),
23 | 'install',
24 | ]
25 | install = ' '.join(install)
26 |
27 | shell = sys.platform != 'win32'
28 | stdout = stderr = PIPE
29 | p = Popen(install, stdout=stdout, stderr=stderr, shell=shell)
30 | stdoutdata, stderrdata = p.communicate()
31 |
32 | return stdoutdata, stdoutdata
33 |
34 | def generate(where, layout=None, sitepackages=True, prompt=None):
35 | '''
36 | create dirs and files after virtualenv dir itself is prepared
37 | '''
38 | generate_pythonrc_stuff(where, layout, sitepackages, prompt)
39 | install_venv_keep_package(where, path.join(where, 'src', 'rvirtualenvkeep'))
40 |
41 | def install_venv_keep_package(venv_base, install_dir):
42 | '''
43 | install setup.py via distutils
44 | '''
45 | run_setup(venv_base, install_dir)
46 |
47 | def generate_pythonrc_stuff(venv_base, layout, sitepackages, prompt):
48 | '''
49 | insert correct lib dirs into pythonrc.py
50 | '''
51 | # load pythonrc.py file
52 | base = path.dirname(rvirtualenv.__file__)
53 | f = open(path.join(base, 'template', 'venv', 'pythonrc.py'), 'r')
54 | content = f.read()
55 | f.close()
56 |
57 | if layout is None:
58 | layout = guess_scheme()
59 |
60 | # replace pattern in pythonrc.py
61 | patrn = "scheme = 'custom'"
62 | repl = "scheme = '%s'" % layout
63 | content = content.replace(patrn, repl)
64 |
65 | # update no-site-packages option
66 | patrn = "sitepackages = True"
67 | repl = "sitepackages = %s" % sitepackages
68 | content = content.replace(patrn, repl)
69 |
70 | # set custom prompt
71 | patrn = "#prompt = '[CUSTOM]' # set your custom prompt prefix (see -p option)"
72 | repl = "prompt = %r" % prompt
73 | if prompt is not None:
74 | content = content.replace(patrn, repl)
75 |
76 | # write it
77 | f = open(path.join(venv_base, 'pythonrc.py'), 'w')
78 | f.write(content)
79 | f.close()
80 |
81 |
--------------------------------------------------------------------------------
/rvirtualenv/rvirtualenvinstall/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kvbik/rvirtualenv/aaacde2171144bc3c1d8ab8668e36a0dbc29bf3d/rvirtualenv/rvirtualenvinstall/__init__.py
--------------------------------------------------------------------------------
/rvirtualenv/rvirtualenvinstall/boot.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from os import path
3 |
4 | from rvirtualenvinstall import (
5 | scheme,
6 | install,
7 | )
8 | import pythonrc
9 |
10 |
11 | def boot():
12 | base = path.abspath(path.dirname(pythonrc.__file__))
13 |
14 | # real_prefix is useful for pip and uninstalling system pkgs
15 | sys.real_prefix = sys.prefix
16 | # python uses this almost everywhere
17 | sys.prefix = base
18 |
19 | if not pythonrc.sitepackages:
20 | sys.path = sys.__rvirtualenv_prev_path
21 |
22 | this_site_packages = [
23 | scheme.get_scheme(pythonrc.scheme, 'purelib'),
24 | scheme.get_scheme(pythonrc.scheme, 'platlib'),
25 | ]
26 |
27 | scheme.add_to_path(getattr(pythonrc, 'extra_paths', []))
28 | scheme.add_to_path(this_site_packages)
29 |
30 | install.monkeypatch()
31 |
32 |
--------------------------------------------------------------------------------
/rvirtualenv/rvirtualenvinstall/develop.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 | from setuptools.command.develop import develop as _develop
3 |
4 |
5 | class develop(_develop):
6 | description = "rvirtualenv's %s" % _develop.description
7 | def run(self):
8 | print('WTF')
9 |
10 | # don't know why isn't it overriden by entry_points
11 | setuptools.command.develop.develop = develop
12 |
13 |
--------------------------------------------------------------------------------
/rvirtualenv/rvirtualenvinstall/install.py:
--------------------------------------------------------------------------------
1 | import distutils
2 | from distutils.command.install import install as _install
3 |
4 | import pythonrc
5 | from rvirtualenvinstall import scheme
6 |
7 |
8 | class install(_install):
9 | description = "rvirtualenv's %s" % _install.description
10 | def finalize_options(self):
11 | _install.finalize_options(self)
12 |
13 | vars = {'dist_name': self.distribution.get_name(),}
14 | self.install_purelib = scheme.get_scheme(pythonrc.scheme, 'purelib')
15 | self.install_platlib = scheme.get_scheme(pythonrc.scheme, 'purelib')
16 | self.install_headers = scheme.get_scheme(pythonrc.scheme, 'headers', vars=vars)
17 | self.install_scripts = scheme.get_scheme(pythonrc.scheme, 'scripts')
18 | self.install_data = scheme.get_scheme(pythonrc.scheme, 'data')
19 |
20 | if self.distribution.ext_modules: # has extensions: non-pure
21 | self.install_lib = self.install_platlib
22 | else:
23 | self.install_lib = self.install_purelib
24 |
25 | def monkeypatch():
26 | "monkey patch for distutils install command"
27 | distutils.command.install.install = install
28 |
29 |
--------------------------------------------------------------------------------
/rvirtualenv/rvirtualenvinstall/scheme.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from os import path
3 | import site
4 | from distutils.util import subst_vars
5 |
6 | INSTALL_SCHEMES = {
7 | 'custom': {
8 | 'purelib': '$base/lib/python/site-packages',
9 | 'platlib': '$base/lib/python$py_version_short/site-packages',
10 | 'headers': '$base/include/python$py_version_short/$dist_name',
11 | 'scripts': '$base/bin',
12 | 'data' : '$base/lib/python$py_version_short/site-packages',
13 | },
14 | 'unix': {
15 | 'purelib': '$base/lib/python$py_version_short/site-packages',
16 | 'platlib': '$base/lib/python$py_version_short/site-packages',
17 | 'headers': '$base/include/python$py_version_short/$dist_name',
18 | 'scripts': '$base/bin',
19 | 'data' : '$base/lib/python$py_version_short/site-packages',
20 | },
21 | 'windows': {
22 | 'purelib': '$base/Lib/site-packages',
23 | 'platlib': '$base/Lib/site-packages',
24 | 'headers': '$base/Include/$dist_name',
25 | 'scripts': '$base/Scripts',
26 | 'data' : '$base/Lib/site-packages',
27 | },
28 | 'os2': {
29 | 'purelib': '$base/Lib/site-packages',
30 | 'platlib': '$base/Lib/site-packages',
31 | 'headers': '$base/Include/$dist_name',
32 | 'scripts': '$base/Scripts',
33 | 'data' : '$base/Lib/site-packages',
34 | },
35 | 'darwin': {
36 | 'purelib': '$base/Library/Python$py_version_short/site-packages',
37 | 'platlib': '$base/Library/Python$py_version_short/site-packages',
38 | 'headers': '$base/Include/$dist_name',
39 | 'scripts': '$base/bin',
40 | 'data' : '$base/Library/Python$py_version_short/site-packages',
41 | },
42 | }
43 |
44 | def guess_scheme():
45 | return 'unix'
46 |
47 | def get_scheme(platform, what, vars={}):
48 | # TODO: maybe use syslinux.get_path in next versions
49 | replace = {
50 | 'base': sys.prefix,
51 | 'py_version_short': sys.version[:3],
52 | 'dist_name': 'UNKNOWN',
53 | }
54 | replace.update(vars)
55 | line = INSTALL_SCHEMES[platform][what]
56 | line = path.join(*line.split('/'))
57 | return subst_vars(line, replace)
58 |
59 | def add_to_path(new_paths):
60 | "add dirs to the beginnig of sys.path"
61 | __plen = len(sys.path)
62 | for i in new_paths:
63 | if i not in sys.path:
64 | site.addsitedir(i)
65 | new = sys.path[__plen:]
66 | del sys.path[__plen:]
67 | sys.path[0:0] = new
68 |
69 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/bin/activate:
--------------------------------------------------------------------------------
1 |
2 | # you cannot guess path of included file in plain posix shell..
3 | [ $BASH_SOURCE ] && b=`dirname ${BASH_SOURCE[0]}` || b=`dirname $0`
4 | b=`cd $b; pwd`
5 |
6 | $b/activate.py $b/activate.template $b/_activate
7 |
8 | source $b/_activate
9 |
10 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/bin/activate.bat:
--------------------------------------------------------------------------------
1 |
2 | @echo off
3 |
4 | "%~dp0\activate.py" "%~dp0\activate.bat.template" "%~dp0\_activate.bat"
5 | call "%~dp0\_activate.bat"
6 |
7 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/bin/activate.bat.template:
--------------------------------------------------------------------------------
1 | @echo off
2 | set VIRTUAL_ENV=__VIRTUAL_ENV__
3 |
4 | if not defined PROMPT (
5 | set PROMPT=$P$G
6 | )
7 |
8 | if defined _OLD_VIRTUAL_PROMPT (
9 | set PROMPT=%_OLD_VIRTUAL_PROMPT%
10 | )
11 |
12 | if defined _OLD_VIRTUAL_PYTHONHOME (
13 | set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%
14 | )
15 |
16 | set _OLD_VIRTUAL_PROMPT=%PROMPT%
17 | set PROMPT=__VIRTUAL_WINPROMPT__ %PROMPT%
18 |
19 | if defined PYTHONHOME (
20 | set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%
21 | set PYTHONHOME=
22 | )
23 |
24 | if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%; goto SKIPPATH
25 |
26 | set _OLD_VIRTUAL_PATH=%PATH%
27 |
28 | :SKIPPATH
29 | set PATH=%VIRTUAL_ENV%\__BIN_NAME__;%PATH%
30 |
31 | :END
32 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/bin/activate.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import sys
4 | from os import path
5 |
6 | def get_prompt(vname_path, vname):
7 | sys.path.insert(0, vname_path)
8 | import pythonrc
9 | prompt = getattr(pythonrc, 'prompt', '(%s)' % vname)
10 | return prompt
11 |
12 | def get_subst_values():
13 | base = path.dirname(__file__)
14 | vname_path = path.abspath(path.join(base, path.pardir))
15 | vname = path.split(vname_path)[-1]
16 | bin_path = path.split(base)[-1]
17 | prompt = get_prompt(vname_path, vname)
18 | return {
19 | '__VIRTUAL_PROMPT__': prompt,
20 | '__VIRTUAL_WINPROMPT__': prompt,
21 | '__VIRTUAL_ENV__': vname_path,
22 | '__VIRTUAL_NAME__': vname,
23 | '__BIN_NAME__': bin_path,
24 | }
25 |
26 | def generate(ftemplt, foutput):
27 | ftemplt = open(ftemplt, 'r').read()
28 | for k, v in get_subst_values().items():
29 | ftemplt = ftemplt.replace(k, v)
30 | f = open(foutput, 'w')
31 | f.write(ftemplt)
32 | f.close()
33 |
34 | def main(argv=None):
35 | if argv is None:
36 | argv = sys.argv
37 | if len(argv) < 3:
38 | raise NotImplementedError
39 | generate(argv[1], argv[2])
40 |
41 | if __name__ == '__main__':
42 | main()
43 |
44 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/bin/activate.template:
--------------------------------------------------------------------------------
1 | # This file must be used with "source bin/activate" *from bash*
2 | # you cannot run it directly
3 |
4 | deactivate () {
5 | # reset old environment variables
6 | if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
7 | PATH="$_OLD_VIRTUAL_PATH"
8 | export PATH
9 | unset _OLD_VIRTUAL_PATH
10 | fi
11 | if [ -n "$_OLD_VIRTUAL_PYTHONPATH" ] ; then
12 | PYTHONPATH="$_OLD_VIRTUAL_PYTHONPATH"
13 | export PYTHONPATH
14 | unset _OLD_VIRTUAL_PYTHONPATH
15 | fi
16 | if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then
17 | PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
18 | export PYTHONHOME
19 | unset _OLD_VIRTUAL_PYTHONHOME
20 | fi
21 |
22 | # This should detect bash and zsh, which have a hash command that must
23 | # be called to get it to forget past commands. Without forgetting
24 | # past commands the $PATH changes we made may not be respected
25 | if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
26 | hash -r
27 | fi
28 |
29 | if [ -n "$_OLD_VIRTUAL_PS1" ] ; then
30 | PS1="$_OLD_VIRTUAL_PS1"
31 | export PS1
32 | unset _OLD_VIRTUAL_PS1
33 | fi
34 |
35 | unset VIRTUAL_ENV
36 | if [ ! "$1" = "nondestructive" ] ; then
37 | # Self destruct!
38 | unset -f deactivate
39 | [ "$PYTHONPATH" = ":" ] && unset PYTHONPATH
40 | fi
41 | }
42 |
43 | # unset irrelavent variables
44 | deactivate nondestructive
45 |
46 | VIRTUAL_ENV="__VIRTUAL_ENV__"
47 | export VIRTUAL_ENV
48 |
49 | _OLD_VIRTUAL_PATH="$PATH"
50 | PATH="$VIRTUAL_ENV/__BIN_NAME__:$PATH"
51 | export PATH
52 |
53 | [ $PYTHONPATH ] || PYTHONPATH=:
54 | _OLD_VIRTUAL_PYTHONPATH="$PYTHONPATH"
55 | PYTHONPATH="$VIRTUAL_ENV:$PYTHONPATH"
56 | export PYTHONPATH
57 |
58 | # unset PYTHONHOME if set
59 | # this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
60 | # could use `if (set -u; : $PYTHONHOME) ;` in bash
61 | if [ -n "$PYTHONHOME" ] ; then
62 | _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
63 | unset PYTHONHOME
64 | fi
65 |
66 | if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then
67 | _OLD_VIRTUAL_PS1="$PS1"
68 | if [ "x__VIRTUAL_PROMPT__" != x ] ; then
69 | PS1="__VIRTUAL_PROMPT__$PS1"
70 | else
71 | if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
72 | # special case for Aspen magic directories
73 | # see http://www.zetadev.com/software/aspen/
74 | PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
75 | else
76 | PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
77 | fi
78 | fi
79 | export PS1
80 | fi
81 |
82 | # This should detect bash and zsh, which have a hash command that must
83 | # be called to get it to forget past commands. Without forgetting
84 | # past commands the $PATH changes we made may not be respected
85 | if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
86 | hash -r
87 | fi
88 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/bin/deactivate.bat:
--------------------------------------------------------------------------------
1 |
2 | @echo off
3 |
4 | "%~dp0\activate.py" "%~dp0\deactivate.bat.template" "%~dp0\_deactivate.bat"
5 | call "%~dp0\_deactivate.bat"
6 |
7 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/bin/deactivate.bat.template:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | if defined _OLD_VIRTUAL_PROMPT (
4 | set PROMPT=%_OLD_VIRTUAL_PROMPT%
5 | )
6 | set _OLD_VIRTUAL_PROMPT=
7 |
8 | if defined _OLD_VIRTUAL_PYTHONHOME (
9 | set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%
10 | set _OLD_VIRTUAL_PYTHONHOME=
11 | )
12 |
13 | if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%
14 |
15 | set _OLD_VIRTUAL_PATH=
16 |
17 | :END
18 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/bin/getpythondist.py:
--------------------------------------------------------------------------------
1 | import sys
2 | print(sys.executable)
3 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/bin/python:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | p=`dirname $0`
4 | path=`cd $p; pwd`
5 | exec ${path}/python.py "$@"
6 |
7 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/bin/python.bat:
--------------------------------------------------------------------------------
1 |
2 | @echo off
3 |
4 | for /f "tokens=*" %%i in ('%~dp0\getpythondist.py') do set python=%%i
5 | call "%python%" "%~dp0\python.py" %*
6 |
7 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/bin/python.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | '''
4 | use this file directly, or just set PYTHONPATH to your virtualenv directory
5 | and run system wide python instance
6 | '''
7 |
8 | import os, sys
9 | from os import path
10 | from os.path import join, dirname, pardir, abspath
11 |
12 |
13 | def get_this_path():
14 | '''
15 | we do expect scripts are installed just one level deeper from venv
16 | '''
17 | base = dirname(__file__)
18 | thispath = abspath(join(base, pardir))
19 | return thispath
20 |
21 | def inject_pythonpath():
22 | '''
23 | insert virtualevn path into pythonpath
24 | '''
25 | pypath = os.environ.get('PYTHONPATH', '').split(path.pathsep)
26 | thispath = get_this_path()
27 | try:
28 | pypath.remove('')
29 | pypath.remove(thispath)
30 | except ValueError:
31 | pass
32 | pypath.insert(0, thispath)
33 | os.environ['PYTHONPATH'] = path.pathsep.join(pypath)
34 |
35 | def prepare_argv(argv=[]):
36 | '''
37 | prepare argv to run
38 | * windows platform needs add quotes around arguments with spaces
39 | '''
40 | def q(s):
41 | return '"%s"' % s.replace('"', '\\"')
42 | if sys.platform == 'win32':
43 | argv = map(q, argv)
44 | return tuple(argv)
45 |
46 | def run(argv):
47 | os.execvp(sys.executable, argv)
48 |
49 | def main(argv=None):
50 | if argv is None:
51 | argv = sys.argv
52 | inject_pythonpath()
53 | run(prepare_argv(argv))
54 |
55 | if __name__ == '__main__':
56 | main()
57 |
58 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/rvirtualenvkeep.py:
--------------------------------------------------------------------------------
1 | """
2 | congratulations, it seems, you are inside
3 | python relocatable virtual environment
4 | """
5 |
--------------------------------------------------------------------------------
/rvirtualenv/template/inst/setup.py:
--------------------------------------------------------------------------------
1 | import os
2 | from os import path
3 | import sys
4 | from distutils.core import setup
5 |
6 | scripts = (
7 | 'bin/python.py',
8 | 'bin/activate.py',
9 | )
10 |
11 | if sys.platform == 'win32':
12 | scripts += (
13 | 'bin/getpythondist.py',
14 | 'bin/python.bat',
15 | 'bin/activate.bat',
16 | 'bin/activate.bat.template',
17 | 'bin/deactivate.bat',
18 | 'bin/deactivate.bat.template',
19 | )
20 | else:
21 | scripts += (
22 | 'bin/python',
23 | 'bin/activate',
24 | 'bin/activate.template',
25 | )
26 |
27 | os.chdir(path.abspath(path.dirname(__file__)))
28 | setup(
29 | name='rvirtualenvkeep',
30 | version='0.1',
31 | py_modules=['rvirtualenvkeep'],
32 | scripts=scripts,
33 | )
34 |
35 |
--------------------------------------------------------------------------------
/rvirtualenv/template/venv/pythonrc.py:
--------------------------------------------------------------------------------
1 |
2 | scheme = 'custom'
3 | sitepackages = True
4 | #prompt = '[CUSTOM]' # set your custom prompt prefix (see -p option)
5 | #extra_paths = ['/path/to/inheriting/site-packages/',] # add some if you need access to other venvs
6 |
7 |
--------------------------------------------------------------------------------
/rvirtualenv/template/venv/rvirtualenvinstall.egg-info/PKG-INFO:
--------------------------------------------------------------------------------
1 | Metadata-Version: 1.0
2 | Name: rvirtualenvinstall
3 | Version: 0.1
4 | Summary: UNKNOWN
5 | Home-page: UNKNOWN
6 | Author: UNKNOWN
7 | Author-email: UNKNOWN
8 | License: UNKNOWN
9 | Description: UNKNOWN
10 | Platform: UNKNOWN
11 |
--------------------------------------------------------------------------------
/rvirtualenv/template/venv/rvirtualenvinstall.egg-info/entry_points.txt:
--------------------------------------------------------------------------------
1 | [distutils.commands]
2 | developp = rvirtualenvinstall.develop:develop
3 |
--------------------------------------------------------------------------------
/rvirtualenv/template/venv/site.py:
--------------------------------------------------------------------------------
1 | def __boot():
2 | import sys, imp, os, os.path
3 | sys.__rvirtualenv_prev_path = list(sys.path)
4 | PYTHONPATH = os.environ.get('PYTHONPATH')
5 | if PYTHONPATH is None or (sys.platform=='win32' and not PYTHONPATH):
6 | PYTHONPATH = []
7 | else:
8 | PYTHONPATH = PYTHONPATH.split(os.pathsep)
9 |
10 | pic = getattr(sys,'path_importer_cache',{})
11 | stdpath = sys.path[len(PYTHONPATH):]
12 | mydir = os.path.dirname(__file__)
13 | #print "searching",stdpath,sys.path
14 |
15 | for item in stdpath:
16 | if item==mydir or not item:
17 | continue # skip if current dir. on Windows, or my own directory
18 | importer = pic.get(item)
19 | if importer is not None:
20 | loader = importer.find_module('site')
21 | if loader is not None:
22 | # This should actually reload the current module
23 | loader.load_module('site')
24 | break
25 | else:
26 | try:
27 | stream, path, descr = imp.find_module('site',[item])
28 | except ImportError:
29 | continue
30 | if stream is None:
31 | continue
32 | try:
33 | # This should actually reload the current module
34 | imp.load_module('site',stream,path,descr)
35 | finally:
36 | stream.close()
37 | break
38 | else:
39 | raise ImportError("Couldn't find the real 'site' module")
40 |
41 | #print "loaded", __file__
42 |
43 | known_paths = dict([(makepath(item)[1],1) for item in sys.path]) # 2.2 comp
44 |
45 | oldpos = getattr(sys,'__egginsert',0) # save old insertion position
46 | sys.__egginsert = 0 # and reset the current one
47 |
48 | for item in PYTHONPATH:
49 | addsitedir(item)
50 |
51 | sys.__egginsert += oldpos # restore effective old position
52 |
53 | d,nd = makepath(stdpath[0])
54 | insert_at = None
55 | new_path = []
56 |
57 | for item in sys.path:
58 | p,np = makepath(item)
59 |
60 | if np==nd and insert_at is None:
61 | # We've hit the first 'system' path entry, so added entries go here
62 | insert_at = len(new_path)
63 |
64 | if np in known_paths or insert_at is None:
65 | new_path.append(item)
66 | else:
67 | # new path after the insert point, back-insert it
68 | new_path.insert(insert_at, item)
69 | insert_at += 1
70 |
71 | sys.path[:] = new_path
72 |
73 | import rvirtualenvinstall.boot
74 | rvirtualenvinstall.boot.boot()
75 |
76 |
77 | if __name__=='site':
78 | __boot()
79 | del __boot
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 | from os import path
3 |
4 |
5 | VERSION = (0, 3, 2)
6 | __version__ = VERSION
7 | __versionstr__ = '.'.join(map(str, VERSION))
8 |
9 | f = open(path.join(path.dirname(__file__), 'README.rst'))
10 | long_description = f.read().strip()
11 | f.close()
12 |
13 |
14 | setup(
15 | name = 'RVirtualEnv',
16 | description = "relocatable python virtual environment",
17 | url = "http://github.com/kvbik/rvirtualenv",
18 | long_description = long_description,
19 | version = __versionstr__,
20 | author = "Jakub Vysoky",
21 | author_email = "jakub@borka.cz",
22 | license = "BSD",
23 | packages = ['rvirtualenv'],
24 | entry_points = {
25 | 'console_scripts': [
26 | 'rvirtualenv = rvirtualenv:main',
27 | ],
28 | },
29 | zip_safe = False,
30 | include_package_data = True,
31 | test_suite = "tests.test_all.runtests",
32 | classifiers = [
33 | "Development Status :: 4 - Beta",
34 | "Programming Language :: Python",
35 | "Programming Language :: Python :: 2",
36 | "Programming Language :: Python :: 3",
37 | "Intended Audience :: Developers",
38 | "License :: OSI Approved :: BSD License",
39 | "Operating System :: OS Independent",
40 | ]
41 | )
42 |
43 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kvbik/rvirtualenv/aaacde2171144bc3c1d8ab8668e36a0dbc29bf3d/tests/__init__.py
--------------------------------------------------------------------------------
/tests/helpers.py:
--------------------------------------------------------------------------------
1 |
2 | import os
3 | from os import path
4 | from shutil import rmtree
5 | from unittest import TestCase
6 | from tempfile import mkdtemp
7 |
8 | import rvirtualenv
9 |
10 |
11 | class InTempTestCase(TestCase):
12 | def setUp(self):
13 | # unittest limit
14 | self.maxDiff = None
15 |
16 | # store curr path
17 | self.oldcwd = os.getcwd()
18 |
19 | # create test dir structure
20 | self.directory = mkdtemp(prefix='test_rvirtualenv_')
21 |
22 | # new rvirtualenv
23 | self.virtualenv = path.join(self.directory, 'PY')
24 |
25 | # store base dir
26 | self.base = path.join(path.dirname(rvirtualenv.__file__), path.pardir)
27 |
28 | def tearDown(self):
29 | # go back
30 | os.chdir(self.oldcwd)
31 |
32 | # dir cleanup
33 | rmtree(self.directory, True)
34 |
35 | def store_directory_structure(mypath, content=None):
36 | '''
37 | recursivelly traverse directory and store it in format:
38 | (
39 | (mypath, None),
40 | (mypath/to, None),
41 | (mypath/to/dir, None),
42 | (mypath/to/dir/file.txt, {{ file's content }}),
43 | )
44 | '''
45 | d = {}
46 | for base, dirs, files in os.walk(mypath):
47 | d[base] = None
48 | for i in files:
49 | fn = path.join(base, i)
50 | if content is not None:
51 | d[fn] = content
52 | continue
53 | f = open(fn, 'rb')
54 | d[fn] = f.read()
55 | f.close()
56 | return d.items()
57 |
58 | def relpath(p, start):
59 | "os.path.relpath dummy replacement"
60 | return p.replace(path.join(start, ''), '', 1)
61 |
62 |
--------------------------------------------------------------------------------
/tests/installs/venvtest-distutils/setup.py:
--------------------------------------------------------------------------------
1 | from distutils.core import setup
2 |
3 | setup(
4 | name='VEnvTest',
5 | version='0.1.0',
6 | py_modules=['venvtest'],
7 | )
8 |
9 |
--------------------------------------------------------------------------------
/tests/installs/venvtest-distutils/venvtest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | __versionstr__ = '0.1.0'
4 |
5 | def main():
6 | print('venvtest')
7 |
8 | if __name__ == '__main__':
9 | main()
10 |
11 |
--------------------------------------------------------------------------------
/tests/installs/venvtest-setuptools/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 | setup(
4 | name='VEnvTest',
5 | version='0.1.0',
6 | py_modules=['venvtest'],
7 | zip_safe=True,
8 | )
9 |
10 |
--------------------------------------------------------------------------------
/tests/installs/venvtest-setuptools/venvtest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | __versionstr__ = '0.1.0'
4 |
5 | def main():
6 | print('venvtest')
7 |
8 | if __name__ == '__main__':
9 | main()
10 |
11 |
--------------------------------------------------------------------------------
/tests/scripts/print.py:
--------------------------------------------------------------------------------
1 |
2 | import sys
3 |
4 | if len(sys.argv) > 1:
5 | print(sys.argv[1:])
6 |
7 |
--------------------------------------------------------------------------------
/tests/test_all.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | '''
4 | poor man's nosetests
5 | '''
6 |
7 | import sys
8 | from os import path
9 | import unittest
10 |
11 |
12 | def runtests():
13 | base = path.abspath(path.join(path.dirname(__file__), path.pardir))
14 |
15 | # hack pythonpath to contain dir to load proper module for testing
16 | oldpath = sys.path[:]
17 | if base in sys.path:
18 | sys.path.remove(base)
19 | sys.path.insert(0, base)
20 |
21 | r = unittest.TextTestRunner()
22 | l = unittest.TestLoader()
23 |
24 | m = [
25 | 'tests.test_copy',
26 | 'tests.test_generate',
27 | 'tests.test_rvirtualenv',
28 | ]
29 |
30 | result = r.run(l.loadTestsFromNames(m))
31 | sys.exit(not result.wasSuccessful())
32 |
33 | if __name__ == '__main__':
34 | runtests()
35 |
36 |
--------------------------------------------------------------------------------
/tests/test_copy.py:
--------------------------------------------------------------------------------
1 |
2 | import os
3 | from os import path
4 |
5 | from tests.helpers import InTempTestCase, store_directory_structure
6 |
7 | import rvirtualenv
8 | from rvirtualenv.copy import copy, ignore, remove_ignored
9 |
10 |
11 | class TestCopy(InTempTestCase):
12 | def test_ignore(self):
13 | names = [
14 | 'abc.txt',
15 | 'koko/koko.pyc',
16 | 'keke/__pycache__',
17 | 'def.py',
18 | ]
19 | expected = set([
20 | 'koko/koko.pyc',
21 | 'keke/__pycache__',
22 | ])
23 | self.failUnlessEqual(expected, ignore(None, names))
24 |
25 | def test_remove_ignored(self):
26 | # create some dummy dir structures
27 | for i in ('FROM', 'TO'):
28 | os.makedirs(path.join(self.directory, i))
29 | os.makedirs(path.join(self.directory, i, '__pycache__'))
30 | f = open(path.join(self.directory, i, 'test.pyc'), 'w'); f.close()
31 | f = open(path.join(self.directory, i, 'test.py'), 'w'); f.close()
32 | # call our logic
33 | remove_ignored(path.join(self.directory, 'FROM'), path.join(self.directory, 'TO'), ignore)
34 | # some files should be removed
35 | self.assertFalse(path.exists(path.join(self.directory, 'TO', '__pycache__')))
36 | self.assertFalse(path.exists(path.join(self.directory, 'TO', 'test.pyc')))
37 | # other should stay
38 | self.assertTrue(path.exists(path.join(self.directory, 'TO', 'test.py')))
39 | # and originals must not be touched
40 | self.assertTrue(path.exists(path.join(self.directory, 'FROM', '__pycache__')))
41 | self.assertTrue(path.exists(path.join(self.directory, 'FROM', 'test.pyc')))
42 | self.assertTrue(path.exists(path.join(self.directory, 'FROM', 'test.py')))
43 |
44 | def test_whole_copy(self):
45 | base = path.dirname(rvirtualenv.__file__)
46 |
47 | os.chdir(path.join(base, 'template', 'venv'))
48 | a = list(store_directory_structure('.'))
49 |
50 | os.chdir(base)
51 | b = store_directory_structure('.')
52 | # filter only rvirtualenvinstall
53 | b = [ i for i in b if 'rvirtualenvinstall' in i[0] ]
54 | # extract not wanted
55 | b = [ i for i in b if 'template' not in i[0] ]
56 |
57 | os.chdir(path.join(base, 'template'))
58 | c = store_directory_structure('.')
59 | patrn = path.join('.', 'inst')
60 | repl = path.join('.', 'src', 'rvirtualenvkeep')
61 | c = [ (i.replace(patrn, repl),j) for (i,j) in c if patrn in i ]
62 |
63 | d = [(path.join('.', 'src'), None)]
64 |
65 | expected = sorted(a+b+c+d)
66 | # extract not wanted - aka those that are ignored
67 | expected = [ i for i in expected if '__pycache__' not in i[0] ]
68 | expected = [ i for i in expected if not i[0].endswith('pyc') ]
69 |
70 | copy(self.virtualenv)
71 |
72 | os.chdir(self.virtualenv)
73 | x = store_directory_structure('.')
74 | x = [ i for i in x if '__pycache__' not in i[0] ]
75 | got = sorted(x)
76 |
77 | self.failUnlessEqual([i for (i,j) in expected], [i for (i,j) in got])
78 | self.failUnlessEqual(expected, got)
79 |
80 |
--------------------------------------------------------------------------------
/tests/test_generate.py:
--------------------------------------------------------------------------------
1 |
2 | from os import path
3 |
4 | from tests.helpers import InTempTestCase, store_directory_structure
5 |
6 | import rvirtualenv
7 | from rvirtualenv.generate import generate
8 | from rvirtualenv.copy import copy
9 | from rvirtualenv.rvirtualenvinstall.scheme import get_scheme, guess_scheme
10 |
11 |
12 | class TestGenerate(InTempTestCase):
13 | def test_whole_generate(self, layout=None):
14 | copy(self.virtualenv)
15 | generate(self.virtualenv, layout=layout)
16 | structure = store_directory_structure(self.virtualenv, content='')
17 |
18 | if layout is None:
19 | layout = guess_scheme()
20 |
21 | paths = set((i for i,j in structure))
22 | vars = {'base': self.virtualenv}
23 | self.assertTrue(get_scheme(layout, 'purelib', vars=vars) in paths)
24 | self.assertTrue(get_scheme(layout, 'scripts', vars=vars) in paths)
25 |
26 | pybin = path.join(get_scheme(layout, 'scripts', vars=vars), 'python.py')
27 | self.assertTrue(path.exists(pybin))
28 |
29 | pyrc = path.join(self.virtualenv, 'pythonrc.py')
30 | self.assertTrue(path.exists(pyrc))
31 |
32 | content = open(pyrc, 'r').read()
33 | self.assertFalse("scheme = 'custom'" in content)
34 |
35 |
--------------------------------------------------------------------------------
/tests/test_rvirtualenv.py:
--------------------------------------------------------------------------------
1 |
2 | import sys
3 | import os
4 | from os import path
5 | from subprocess import Popen, PIPE
6 | import textwrap
7 | import logging
8 |
9 | from tests.helpers import InTempTestCase, relpath
10 |
11 | from rvirtualenv import main
12 | from rvirtualenv.rvirtualenvinstall.scheme import get_scheme, guess_scheme
13 |
14 |
15 | class TestRVirtualEnv(InTempTestCase):
16 | def setUp(self):
17 | super(TestRVirtualEnv, self).setUp()
18 |
19 | vars = {'base': self.virtualenv}
20 | self.python = path.join(get_scheme(guess_scheme(), 'scripts', vars=vars), 'python.py')
21 |
22 | def install_venv_in_isolation(self, virtualenv=None, sitepackages=True, prompt=None):
23 | '''
24 | install rvirtualenv itself, but do it in subprocess,
25 | because of possible interaction with other imported libraries
26 | (eg: setuptools and its monkeypatching)
27 | '''
28 | if virtualenv is None:
29 | virtualenv = self.virtualenv
30 | cmd = ('''%s -c "import sys; sys.path.insert(0, %r); '''
31 | '''from rvirtualenv import create; create(%r, %s, %r)"''') % \
32 | (sys.executable, self.base, virtualenv, sitepackages, prompt)
33 | stdout, stderr = self.run_command(cmd)
34 | self.failUnlessEqual('', stdout.strip())
35 | self.failUnlessEqual('', stderr.strip())
36 |
37 | def install_venv(self, args=[], virtualenv=None):
38 | if virtualenv is None:
39 | virtualenv = self.virtualenv
40 | argv = [None, virtualenv]
41 | argv[1:1] = args
42 | main(argv)
43 |
44 | def run_rvirtualenv_command(self, virtualenv):
45 | os.chdir(self.directory)
46 | self.install_venv_in_isolation(virtualenv)
47 |
48 | pythonrc = path.join(virtualenv, 'pythonrc.py')
49 | self.assertTrue(path.exists(pythonrc))
50 |
51 | self.assertTrue(path.exists(self.python))
52 |
53 | def test_rvirtualenv_command_creates_distdirs_given_absolute(self):
54 | self.run_rvirtualenv_command(self.virtualenv)
55 |
56 | def test_rvirtualenv_command_creates_distdirs_given_relative(self):
57 | self.run_rvirtualenv_command('PY')
58 |
59 | def run_command(self, cmd):
60 | shell = sys.platform != 'win32'
61 | p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=shell)
62 | return map(lambda b: b.decode(sys.stdout.encoding or 'UTF-8'), p.communicate())
63 |
64 | def test_python_itself(self):
65 | self.install_venv()
66 |
67 | cmd = '%s %s -c "print(128)"' % (sys.executable, self.python)
68 | stdout, stderr = self.run_command(cmd)
69 | self.failUnlessEqual('128', stdout.strip())
70 |
71 | def test_venv_without_site_packages(self):
72 | '''
73 | setuptools installed system-wide is needed for this test
74 | '''
75 | v1 = path.join(self.directory, 'PY1')
76 | py1 = path.join(get_scheme(guess_scheme(), 'scripts', vars={'base': v1}), 'python.py')
77 | self.install_venv(args=[], virtualenv=v1)
78 | cmd = '%s %s -c "import setuptools"' % (sys.executable, py1)
79 | stdout, stderr = self.run_command(cmd)
80 | self.failUnlessEqual('', stderr.strip())
81 | self.failUnlessEqual('', stdout.strip())
82 |
83 | v2 = path.join(self.directory, 'PY2')
84 | py2 = path.join(get_scheme(guess_scheme(), 'scripts', vars={'base': v2}), 'python.py')
85 | self.install_venv(args=['--no-site-packages'], virtualenv=v2)
86 | cmd = '%s %s -c "import setuptools"' % (sys.executable, py2)
87 | stdout, stderr = self.run_command(cmd)
88 | self.assertTrue('ImportError: No module named setuptools' in stderr)
89 |
90 | def test_run_python_script(self):
91 | self.install_venv()
92 |
93 | script = path.join(self.base, 'tests', 'scripts','print.py')
94 | cmd = '%s %s %s' % (sys.executable, self.python, script)
95 | stdout, stderr = self.run_command(cmd)
96 | self.failUnlessEqual('', stdout)
97 |
98 | def test_run_python_script_with_args(self):
99 | self.install_venv()
100 |
101 | script = path.join(self.base, 'tests', 'scripts','print.py')
102 | cmd = '%s %s %s a b c' % (sys.executable, self.python, script)
103 | stdout, stderr = self.run_command(cmd)
104 | self.failUnlessEqual("['a', 'b', 'c']", stdout.strip())
105 |
106 | def install_some_way(self, inst_type, inst_command='install'):
107 | self.install_venv()
108 |
109 | os.chdir(path.join(self.base, 'tests', 'installs',
110 | 'venvtest-%s' % inst_type))
111 | inst = '%s %s setup.py %s' % \
112 | (sys.executable, self.python, inst_command)
113 | stdout, stderr = self.run_command(inst)
114 | os.chdir(self.oldcwd)
115 |
116 | logging.info('stdout:')
117 | logging.info(stdout)
118 | logging.info('stderr:')
119 | logging.info(stderr)
120 |
121 | self.failUnlessEqual('', stderr)
122 |
123 | cmd = '%s %s -c "import venvtest; print(venvtest.__versionstr__)"' % \
124 | (sys.executable, self.python)
125 | stdout, stderr = self.run_command(cmd)
126 | expected = '0.1.0'
127 | self.failUnlessEqual(expected, stdout.strip())
128 |
129 | cmd = '%s %s -c "import venvtest; print(venvtest.__file__)"' % \
130 | (sys.executable, self.python)
131 | stdout, stderr = self.run_command(cmd)
132 | a = len(self.virtualenv)
133 | b = -len('venvtest.pyX')
134 | env = stdout.strip()[:a]
135 | mod = stdout.strip()[b:]
136 | pth = stdout.strip()[a:b]
137 |
138 | logging.info(pth)
139 |
140 | self.failUnlessEqual(self.virtualenv, env)
141 | # it could be *.py or *.pyc - depending on distro
142 | self.failUnlessEqual('venvtest.py', mod.strip(r'\c/'))
143 |
144 | def test_install_distutils_way(self):
145 | self.install_some_way('distutils')
146 |
147 | def test_install_setuptools_way(self):
148 | '''
149 | this test should skip if you don't have setuptools
150 | but other tests could fail too..
151 | '''
152 | inst_command = ('install'
153 | ' --single-version-externally-managed'
154 | ' --record %s' % path.join(self.directory, 'record.log'))
155 | self.install_some_way('setuptools', inst_command=inst_command)
156 |
157 | def activate_command_unix(self):
158 | scripts = relpath(path.dirname(self.python), self.directory)
159 | activate = 'source %s' % path.join(scripts, 'activate')
160 | deactivate = 'deactivate'
161 | run_command = 'bash run'
162 | run_file = 'run'
163 | shebang = '#!/bin/sh'
164 | self.activate_command(activate, deactivate,
165 | run_command, run_file, shebang)
166 |
167 | def activate_command_win(self):
168 | scripts = relpath(path.dirname(self.python), self.directory)
169 | activate = 'call %s' % path.join(scripts, 'activate.bat')
170 | deactivate = 'call deactivate.bat'
171 | run_command = 'run.bat'
172 | run_file = 'run.bat'
173 | shebang = '@echo off'
174 | out_filter = lambda x: x.lower()
175 | self.activate_command(activate, deactivate,
176 | run_command, run_file, shebang, out_filter)
177 |
178 | def activate_command(self, activate, deactivate,
179 | run_command, run_file, shebang, out_filter=lambda x:x):
180 | os.chdir(self.directory)
181 | self.install_venv()
182 | f = open(run_file, 'w')
183 | f.write(textwrap.dedent('''
184 | %s
185 | %s
186 | python -c "import rvirtualenvkeep; print(rvirtualenvkeep.__file__)"
187 | %s
188 | ''' % (shebang, activate, deactivate)).strip())
189 | f.close()
190 | stdout, stderr = self.run_command(run_command)
191 | stdout = out_filter(stdout)
192 |
193 | '''
194 | from shutil import copytree, rmtree
195 | tempdir = path.join(self.base, 'TSTPY')
196 | rmtree(tempdir, True)
197 | copytree(self.directory, tempdir)
198 | '''
199 |
200 | self.failUnlessEqual(stderr.strip(), '')
201 | self.assertTrue(stdout.strip().startswith(path.realpath(self.directory)))
202 | self.assertTrue(
203 | stdout.strip().endswith('rvirtualenvkeep.pyo') or \
204 | stdout.strip().endswith('rvirtualenvkeep.pyc') or \
205 | stdout.strip().endswith('rvirtualenvkeep.py')
206 | )
207 |
208 | def test_activate_command(self):
209 | if sys.platform == 'win32':
210 | self.activate_command_win()
211 | else:
212 | self.activate_command_unix()
213 |
214 | def something_is_bad_on_win32_and_subprocess(self, py, command=None):
215 | replace_command = command
216 |
217 | if sys.platform == 'win32':
218 | name = 'pokus.bat'
219 | command = name
220 | bat = ('@echo off', '"%s" pokus.py' % sys.executable,)
221 | else:
222 | name = 'pokus.sh'
223 | command = 'sh pokus.sh'
224 | bat = ('#!/bin/sh', 'python pokus.py',)
225 |
226 | if replace_command is not None:
227 | command = replace_command
228 |
229 | write = '\n'.join(py)
230 | f = open('pokus.py', 'w'); f.write(write); f.close()
231 |
232 | write = '\n'.join(bat)
233 | f = open(name, 'w'); f.write(write); f.close()
234 |
235 | shell = True
236 | p = Popen(command, stdout=PIPE, stderr=PIPE, shell=shell)
237 | stdout, stderr = map(
238 | lambda b: b.decode(sys.stdout.encoding or 'UTF-8'), p.communicate())
239 | self.failUnlessEqual('128', stdout.strip())
240 |
241 | def test_something_is_bad_on_win32_and_os_system(self):
242 | py = ('import os', 'os.system("echo 128")')
243 | self.something_is_bad_on_win32_and_subprocess(py)
244 |
245 | def test_something_is_bad_on_win32_and_popen(self):
246 | py = (
247 | 'from subprocess import Popen, PIPE',
248 | 'p = Popen("echo 128", shell=True)',
249 | 'p.communicate()',
250 | )
251 | self.something_is_bad_on_win32_and_subprocess(py)
252 |
253 | def test_something_is_bad_on_win32_but_this_works(self):
254 | py = ('import os', 'os.system("echo 128")')
255 | #command = 'call pokus.bat' # this doesn't work either
256 | command = '"%s" pokus.py' % sys.executable
257 | self.something_is_bad_on_win32_and_subprocess(py, command)
258 |
259 |
--------------------------------------------------------------------------------