• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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