1from __future__ import absolute_import, unicode_literals 2 3import abc 4import logging 5import os 6 7from six import add_metaclass 8 9from virtualenv.create.describe import PosixSupports, WindowsSupports 10from virtualenv.create.via_global_ref.builtin.ref import PathRefToDest 11from virtualenv.util.path import Path 12 13from ..python2.python2 import Python2 14from .common import PyPy 15 16 17@add_metaclass(abc.ABCMeta) 18class PyPy2(PyPy, Python2): 19 """""" 20 21 @classmethod 22 def exe_stem(cls): 23 return "pypy" 24 25 @classmethod 26 def sources(cls, interpreter): 27 for src in super(PyPy2, cls).sources(interpreter): 28 yield src 29 # include folder needed on Python 2 as we don't have pyenv.cfg 30 host_include_marker = cls.host_include_marker(interpreter) 31 if host_include_marker.exists(): 32 yield PathRefToDest(host_include_marker.parent, dest=lambda self, _: self.include) 33 34 @classmethod 35 def needs_stdlib_py_module(cls): 36 return True 37 38 @classmethod 39 def host_include_marker(cls, interpreter): 40 return Path(interpreter.system_include) / "PyPy.h" 41 42 @property 43 def include(self): 44 return self.dest / self.interpreter.distutils_install["headers"] 45 46 @classmethod 47 def modules(cls): 48 # pypy2 uses some modules before the site.py loads, so we need to include these too 49 return super(PyPy2, cls).modules() + [ 50 "os", 51 "copy_reg", 52 "genericpath", 53 "linecache", 54 "stat", 55 "UserDict", 56 "warnings", 57 ] 58 59 @property 60 def lib_pypy(self): 61 return self.dest / "lib_pypy" 62 63 def ensure_directories(self): 64 dirs = super(PyPy2, self).ensure_directories() 65 dirs.add(self.lib_pypy) 66 host_include_marker = self.host_include_marker(self.interpreter) 67 if host_include_marker.exists(): 68 dirs.add(self.include.parent) 69 else: 70 logging.debug("no include folders as can't find include marker %s", host_include_marker) 71 return dirs 72 73 @property 74 def skip_rewrite(self): 75 """ 76 PyPy2 built-in imports are handled by this path entry, don't overwrite to not disable it 77 see: https://github.com/pypa/virtualenv/issues/1652 78 """ 79 return 'or path.endswith("lib_pypy{}__extensions__") # PyPy2 built-in import marker'.format(os.sep) 80 81 82class PyPy2Posix(PyPy2, PosixSupports): 83 """PyPy 2 on POSIX""" 84 85 @classmethod 86 def modules(cls): 87 return super(PyPy2Posix, cls).modules() + ["posixpath"] 88 89 @classmethod 90 def _shared_libs(cls): 91 return ["libpypy-c.so", "libpypy-c.dylib"] 92 93 @property 94 def lib(self): 95 return self.dest / "lib" 96 97 @classmethod 98 def sources(cls, interpreter): 99 for src in super(PyPy2Posix, cls).sources(interpreter): 100 yield src 101 host_lib = Path(interpreter.system_prefix) / "lib" 102 if host_lib.exists(): 103 yield PathRefToDest(host_lib, dest=lambda self, _: self.lib) 104 105 106class Pypy2Windows(PyPy2, WindowsSupports): 107 """PyPy 2 on Windows""" 108 109 @classmethod 110 def modules(cls): 111 return super(Pypy2Windows, cls).modules() + ["ntpath"] 112 113 @classmethod 114 def _shared_libs(cls): 115 return ["libpypy-c.dll"] 116 117 @classmethod 118 def sources(cls, interpreter): 119 for src in super(Pypy2Windows, cls).sources(interpreter): 120 yield src 121 yield PathRefToDest(Path(interpreter.system_prefix) / "libs", dest=lambda self, s: self.dest / s.name) 122