1import py, os, sys, shutil 2import subprocess 3from testing.udir import udir 4 5if sys.platform == 'win32': 6 py.test.skip('snippets do not run on win32') 7if sys.version_info < (2, 7): 8 py.test.skip('fails e.g. on a Debian/Ubuntu which patches virtualenv' 9 ' in a non-2.6-friendly way') 10 11def create_venv(name): 12 tmpdir = udir.join(name) 13 try: 14 subprocess.check_call(['virtualenv', 15 #'--never-download', <= could be added, but causes failures 16 # in random cases on random machines 17 '-p', os.path.abspath(sys.executable), 18 str(tmpdir)]) 19 except OSError as e: 20 py.test.skip("Cannot execute virtualenv: %s" % (e,)) 21 22 site_packages = None 23 for dirpath, dirnames, filenames in os.walk(str(tmpdir)): 24 if os.path.basename(dirpath) == 'site-packages': 25 site_packages = dirpath 26 break 27 paths = "" 28 if site_packages: 29 try: 30 from cffi import _pycparser 31 modules = ('cffi', '_cffi_backend') 32 except ImportError: 33 modules = ('cffi', '_cffi_backend', 'pycparser') 34 try: 35 import ply 36 except ImportError: 37 pass 38 else: 39 modules += ('ply',) # needed for older versions of pycparser 40 paths = [] 41 for module in modules: 42 target = __import__(module, None, None, []) 43 if not hasattr(target, '__file__'): # for _cffi_backend on pypy 44 continue 45 src = os.path.abspath(target.__file__) 46 for end in ['__init__.pyc', '__init__.pyo', '__init__.py']: 47 if src.lower().endswith(end): 48 src = src[:-len(end)-1] 49 break 50 paths.append(os.path.dirname(src)) 51 paths = os.pathsep.join(paths) 52 return tmpdir, paths 53 54SNIPPET_DIR = py.path.local(__file__).join('..', 'snippets') 55 56def really_run_setup_and_program(dirname, venv_dir_and_paths, python_snippet): 57 venv_dir, paths = venv_dir_and_paths 58 def remove(dir): 59 dir = str(SNIPPET_DIR.join(dirname, dir)) 60 shutil.rmtree(dir, ignore_errors=True) 61 remove('build') 62 remove('__pycache__') 63 for basedir in os.listdir(str(SNIPPET_DIR.join(dirname))): 64 remove(os.path.join(basedir, '__pycache__')) 65 olddir = os.getcwd() 66 python_f = udir.join('x.py') 67 python_f.write(py.code.Source(python_snippet)) 68 try: 69 os.chdir(str(SNIPPET_DIR.join(dirname))) 70 if os.name == 'nt': 71 bindir = 'Scripts' 72 else: 73 bindir = 'bin' 74 vp = str(venv_dir.join(bindir).join('python')) 75 env = os.environ.copy() 76 env['PYTHONPATH'] = paths 77 subprocess.check_call((vp, 'setup.py', 'clean'), env=env) 78 subprocess.check_call((vp, 'setup.py', 'install'), env=env) 79 subprocess.check_call((vp, str(python_f)), env=env) 80 finally: 81 os.chdir(olddir) 82 83def run_setup_and_program(dirname, python_snippet): 84 venv_dir = create_venv(dirname + '-cpy') 85 really_run_setup_and_program(dirname, venv_dir, python_snippet) 86 # 87 sys._force_generic_engine_ = True 88 try: 89 venv_dir = create_venv(dirname + '-gen') 90 really_run_setup_and_program(dirname, venv_dir, python_snippet) 91 finally: 92 del sys._force_generic_engine_ 93 # the two files lextab.py and yacctab.py are created by not-correctly- 94 # installed versions of pycparser. 95 assert not os.path.exists(str(SNIPPET_DIR.join(dirname, 'lextab.py'))) 96 assert not os.path.exists(str(SNIPPET_DIR.join(dirname, 'yacctab.py'))) 97 98class TestZIntegration(object): 99 def teardown_class(self): 100 if udir.isdir(): 101 udir.remove(ignore_errors=True) 102 udir.ensure(dir=1) 103 104 def test_infrastructure(self): 105 run_setup_and_program('infrastructure', ''' 106 import snip_infrastructure 107 assert snip_infrastructure.func() == 42 108 ''') 109 110 def test_distutils_module(self): 111 run_setup_and_program("distutils_module", ''' 112 import snip_basic_verify 113 p = snip_basic_verify.C.getpwuid(0) 114 assert snip_basic_verify.ffi.string(p.pw_name) == b"root" 115 ''') 116 117 def test_distutils_package_1(self): 118 run_setup_and_program("distutils_package_1", ''' 119 import snip_basic_verify1 120 p = snip_basic_verify1.C.getpwuid(0) 121 assert snip_basic_verify1.ffi.string(p.pw_name) == b"root" 122 ''') 123 124 def test_distutils_package_2(self): 125 run_setup_and_program("distutils_package_2", ''' 126 import snip_basic_verify2 127 p = snip_basic_verify2.C.getpwuid(0) 128 assert snip_basic_verify2.ffi.string(p.pw_name) == b"root" 129 ''') 130 131 def test_setuptools_module(self): 132 run_setup_and_program("setuptools_module", ''' 133 import snip_setuptools_verify 134 p = snip_setuptools_verify.C.getpwuid(0) 135 assert snip_setuptools_verify.ffi.string(p.pw_name) == b"root" 136 ''') 137 138 def test_setuptools_package_1(self): 139 run_setup_and_program("setuptools_package_1", ''' 140 import snip_setuptools_verify1 141 p = snip_setuptools_verify1.C.getpwuid(0) 142 assert snip_setuptools_verify1.ffi.string(p.pw_name) == b"root" 143 ''') 144 145 def test_setuptools_package_2(self): 146 run_setup_and_program("setuptools_package_2", ''' 147 import snip_setuptools_verify2 148 p = snip_setuptools_verify2.C.getpwuid(0) 149 assert snip_setuptools_verify2.ffi.string(p.pw_name) == b"root" 150 ''') 151 152 def test_set_py_limited_api(self): 153 from cffi.setuptools_ext import _set_py_limited_api 154 try: 155 import setuptools 156 except ImportError as e: 157 py.test.skip(str(e)) 158 orig_version = setuptools.__version__ 159 expecting_limited_api = not hasattr(sys, 'gettotalrefcount') 160 try: 161 setuptools.__version__ = '26.0.0' 162 from setuptools import Extension 163 164 kwds = _set_py_limited_api(Extension, {}) 165 assert kwds.get('py_limited_api', False) == expecting_limited_api 166 167 setuptools.__version__ = '25.0' 168 kwds = _set_py_limited_api(Extension, {}) 169 assert kwds.get('py_limited_api', False) == False 170 171 setuptools.__version__ = 'development' 172 kwds = _set_py_limited_api(Extension, {}) 173 assert kwds.get('py_limited_api', False) == expecting_limited_api 174 175 finally: 176 setuptools.__version__ = orig_version 177