Skip to content

Commit 4c96de6

Browse files
committed
Merge pull request #576 from qwcode/userscheme_pt5
--user fixes part5: reset_env option for adding patches to sitecustomize
2 parents 1c13812 + faee69b commit 4c96de6

File tree

3 files changed

+114
-11
lines changed

3 files changed

+114
-11
lines changed

tests/test_pip.py

+44-9
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,22 @@ def install_setuptools(env):
102102
env = None
103103

104104

105-
def reset_env(environ=None, use_distribute=None, system_site_packages=False):
105+
def reset_env(environ=None, use_distribute=None, system_site_packages=False, sitecustomize=None):
106+
"""Return a test environment.
107+
108+
Keyword arguments:
109+
environ: an environ object to use.
110+
use_distribute: use distribute, not setuptools.
111+
system_site_packages: create a virtualenv that simulates --system-site-packages.
112+
sitecustomize: a string containing python code to add to sitecustomize.py.
113+
"""
114+
106115
global env
107116
# FastTestPipEnv reuses env, not safe if use_distribute specified
108117
if use_distribute is None and not system_site_packages:
109-
env = FastTestPipEnvironment(environ)
118+
env = FastTestPipEnvironment(environ, sitecustomize=sitecustomize)
110119
else:
111-
env = TestPipEnvironment(environ, use_distribute=use_distribute)
120+
env = TestPipEnvironment(environ, use_distribute=use_distribute, sitecustomize=sitecustomize)
112121

113122
if system_site_packages:
114123
#testing often occurs starting from a private virtualenv (e.g. with tox)
@@ -270,7 +279,7 @@ class TestPipEnvironment(TestFileEnvironment):
270279

271280
verbose = False
272281

273-
def __init__(self, environ=None, use_distribute=None):
282+
def __init__(self, environ=None, use_distribute=None, sitecustomize=None):
274283

275284
self.root_path = Path(tempfile.mkdtemp('-piptest'))
276285

@@ -346,7 +355,12 @@ def __init__(self, environ=None, use_distribute=None):
346355

347356
# Install this version instead
348357
self.run('python', 'setup.py', 'install', cwd=src_folder, expect_stderr=True)
358+
359+
#create sitecustomize.py and add patches
360+
self._create_empty_sitecustomize()
349361
self._use_cached_pypi_server()
362+
if sitecustomize:
363+
self._add_to_sitecustomize(sitecustomize)
350364

351365
def _ignore_file(self, fn):
352366
if fn.endswith('__pycache__') or fn.endswith(".pyc"):
@@ -374,21 +388,36 @@ def _use_cached_pypi_server(self):
374388
# 'import pypi_server' ultimately imports pkg_resources (which intializes pkg_resources.working_set based on the current state of sys.path)
375389
# pkg_resources.get_distribution (used in pip.req) requires an accurate pkg_resources.working_set
376390
# therefore, 'import pypi_server' shouldn't occur in a pth file.
391+
392+
patch = """
393+
import sys
394+
sys.path.insert(0, %r)
395+
import pypi_server
396+
pypi_server.PyPIProxy.setup()
397+
sys.path.remove(%r)""" % (str(here), str(here))
398+
self._add_to_sitecustomize(patch)
399+
400+
def _create_empty_sitecustomize(self):
401+
"Create empty sitecustomize.py."
377402
sitecustomize_path = self.lib_path / 'sitecustomize.py'
378403
sitecustomize = open(sitecustomize_path, 'w')
379-
sitecustomize.write('import sys; ')
380-
sitecustomize.write('sys.path.insert(0, %r); ' % str(here))
381-
sitecustomize.write('import pypi_server; pypi_server.PyPIProxy.setup(); ')
382-
sitecustomize.write('sys.path.remove(%r); ' % str(here))
383404
sitecustomize.close()
384405

406+
def _add_to_sitecustomize(self, snippet):
407+
"Adds a python code snippet to sitecustomize.py."
408+
sitecustomize_path = self.lib_path / 'sitecustomize.py'
409+
sitecustomize = open(sitecustomize_path, 'a')
410+
sitecustomize.write(textwrap.dedent('''
411+
%s
412+
''' %snippet))
413+
sitecustomize.close()
385414

386415
fast_test_env_root = here / 'tests_cache' / 'test_ws'
387416
fast_test_env_backup = here / 'tests_cache' / 'test_ws_backup'
388417

389418

390419
class FastTestPipEnvironment(TestPipEnvironment):
391-
def __init__(self, environ=None):
420+
def __init__(self, environ=None, sitecustomize=None):
392421
import virtualenv
393422

394423
self.root_path = fast_test_env_root
@@ -472,7 +501,13 @@ def __init__(self, environ=None):
472501
# Install this version instead
473502
self.run('python', 'setup.py', 'install', cwd=src_folder, expect_stderr=True)
474503
shutil.copytree(self.root_path, self.backup_path, True)
504+
505+
#create sitecustomize.py and add patches
506+
self._create_empty_sitecustomize()
475507
self._use_cached_pypi_server()
508+
if sitecustomize:
509+
self._add_to_sitecustomize(sitecustomize)
510+
476511
assert self.root_path.exists
477512

478513
def __del__(self):

tests/test_test.py

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
"""Test the test support."""
2+
3+
import sys
4+
import os
5+
from os.path import abspath, join, curdir, isdir, isfile
6+
from nose import SkipTest
7+
from tests.local_repos import local_checkout
8+
from tests.test_pip import here, reset_env, run_pip, pyversion
9+
10+
11+
patch_urlopen = """
12+
def mock_urlopen():
13+
pass
14+
import pip
15+
pip.backwardcompat.urllib2.urlopen = mock_urlopen
16+
"""
17+
18+
def test_pypiproxy_patch_applied():
19+
"""
20+
Test the PyPIProxy.setup() patch was applied, and sys.path returned to normal
21+
"""
22+
23+
env = reset_env()
24+
result = env.run('python', '-c', "import pip; print(pip.backwardcompat.urllib2.urlopen.__module__)")
25+
#if it were not patched, the result would be 'urllib2'
26+
assert "pypi_server"== result.stdout.strip(), result.stdout
27+
28+
#confirm the temporary sys.path adjustment is gone
29+
result = env.run('python', '-c', "import sys; print(sys.path)")
30+
paths = eval(result.stdout.strip())
31+
assert here not in paths, paths
32+
33+
34+
def test_add_patch_to_sitecustomize():
35+
"""
36+
Test adding monkey patch snippet to sitecustomize.py (using TestPipEnvironment)
37+
"""
38+
39+
env = reset_env(sitecustomize=patch_urlopen, use_distribute=True)
40+
result = env.run('python', '-c', "import pip; print(pip.backwardcompat.urllib2.urlopen.__module__)")
41+
assert "sitecustomize"== result.stdout.strip(), result.stdout
42+
43+
44+
def test_add_patch_to_sitecustomize_fast():
45+
"""
46+
Test adding monkey patch snippet to sitecustomize.py (using FastTestPipEnvironment)
47+
"""
48+
49+
env = reset_env(sitecustomize=patch_urlopen)
50+
result = env.run('python', '-c', "import pip; print(pip.backwardcompat.urllib2.urlopen.__module__)")
51+
assert "sitecustomize"== result.stdout.strip(), result.stdout
52+
53+
54+
def test_sitecustomize_not_growing_in_fast_environment():
55+
"""
56+
Test that the sitecustomize is not growing with redundant patches in the cached fast environment
57+
"""
58+
59+
patch = "fu = 'bar'"
60+
61+
env1 = reset_env(sitecustomize=patch)
62+
sc1 = env1.lib_path / 'sitecustomize.py'
63+
size1 = os.stat(sc1).st_size
64+
env2 = reset_env(sitecustomize=patch)
65+
sc2 = env2.lib_path / 'sitecustomize.py'
66+
size2 = os.stat(sc2).st_size
67+
assert size1==size2, "size before, %d != size after, %d" %(size1, size2)
68+

tests/test_uninstall.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ def test_simple_uninstall():
1414
1515
"""
1616
env = reset_env()
17-
result = run_pip('install', 'INITools==0.2', expect_error=True)
17+
result = run_pip('install', 'INITools==0.2')
1818
assert join(env.site_packages, 'initools') in result.files_created, sorted(result.files_created.keys())
19-
result2 = run_pip('uninstall', 'INITools', '-y', expect_error=True)
19+
result2 = run_pip('uninstall', 'INITools', '-y')
2020
assert_all_changes(result, result2, [env.venv/'build', 'cache'])
2121

2222

0 commit comments

Comments
 (0)