From 9c8acda7512b1329b8efe3acc7e89f9e84f74fb0 Mon Sep 17 00:00:00 2001 From: stonebig Date: Wed, 21 Apr 2021 23:43:08 +0200 Subject: [PATCH] PyPy comptability preparation --- winpython/__init__.py | 2 +- winpython/utils.py | 37 +++++++++++++++++++++++++++++++------ winpython/wppm.py | 43 ++++++++++++++++++++++++++++--------------- 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/winpython/__init__.py b/winpython/__init__.py index 24980df8..c7416471 100644 --- a/winpython/__init__.py +++ b/winpython/__init__.py @@ -28,6 +28,6 @@ OTHER DEALINGS IN THE SOFTWARE. """ -__version__ = '4.1.20210417' +__version__ = '4.2.20210422' __license__ = __doc__ __project_url__ = 'http://winpython.github.io/' diff --git a/winpython/utils.py b/winpython/utils.py index ad23969d..077be87d 100644 --- a/winpython/utils.py +++ b/winpython/utils.py @@ -28,6 +28,23 @@ # Local imports from winpython.py3compat import winreg +def get_python_executable(path = None): + """return the python executable""" + my_path = sys.executable if path == None else path # default = current one + my_path = path if osp.isdir(path) else osp.dirname(path) + exec_py = os.path.join(path, 'python.exe') + exec_pypy = os.path.join(path, 'pypy3.exe') # PyPy ! + python_executable = exec_pypy if osp.isfile(exec_pypy) else exec_py + return python_executable + +def get_site_packages_path(path = None): + """return the python site-packages""" + my_path = sys.executable if path == None else path # default = current one + my_path = path if osp.isdir(path) else osp.dirname(path) + site_py = os.path.join(path, 'Lib', 'site-packages') + site_pypy = os.path.join(path, 'site-packages') # PyPy !! + site_packages_path = site_pypy if osp.isfile(site_pypy) else site_py + return site_packages_path def onerror(function, path, excinfo): """Error handler for `shutil.rmtree`. @@ -264,9 +281,9 @@ def print_box(text): def is_python_distribution(path): """Return True if path is a Python distribution""" # XXX: This test could be improved but it seems to be sufficient - return osp.isfile( - osp.join(path, 'python.exe') - ) and osp.isdir(osp.join(path, 'Lib', 'site-packages')) + has_exec = osp.isfile(get_python_executable(path)) + has_site = osp.isdir(get_site_packages_path(path)) + return has_exec and has_site # ============================================================================= @@ -349,9 +366,8 @@ def get_pandoc_version(path): def python_query(cmd, path): """Execute Python command using the Python interpreter located in *path*""" - return exec_shell_cmd( - 'python -c "%s"' % cmd, path - ).splitlines()[0] + the_exe = get_python_executable(path) + return exec_shell_cmd('%s -c "%s"' % (the_exe, cmd), path).splitlines()[0] def get_python_infos(path): @@ -417,6 +433,11 @@ def patch_shebang_line( shebang_line = re.compile( b"(#!.*pythonw?\.exe)" ) # Python3+ + if 'pypy3' in sys.executable: + shebang_line = re.compile( + b"(#!.*pypy3w?\.exe)" + ) # Pypy3+ + target_dir = target_dir.encode('utf-8') with open(fname, 'rb') as fh: initial_content = fh.read() @@ -461,11 +482,15 @@ def patch_shebang_line_py( return if to_movable: exec_path = '#!.\python.exe' + if 'pypy3' in sys.executable: # PyPy ! + exec_path = '#!.\pypy3.exe' else: exec_path = '#!' + sys.executable for line in fileinput.input(fname, inplace=True): if re.match('^#\!.*python\.exe$', line) is not None: print(exec_path) + elif re.match('^#\!.*pypy3\.exe$', line) is not None:# PyPy ! + print(exec_path) else: print(line, end='') diff --git a/winpython/wppm.py b/winpython/wppm.py index f2934e40..1fadfc26 100644 --- a/winpython/wppm.py +++ b/winpython/wppm.py @@ -9,7 +9,7 @@ Created on Fri Aug 03 14:32:26 2012 """ - +# pypy3 to patch from 'python' to 'pypy3': 379 493 497 627 692 696 743 767 785 from __future__ import print_function import os @@ -376,7 +376,7 @@ def get_installed_packages(self, update=False): else: # indirect way: we interrogate something else cmdx = [ - osp.join(self.target, 'python.exe'), + utils.get_python_executable(self.target), # PyPy ! '-c', "import pip;from pip._internal.utils.misc import get_installed_distributions as pip_get_installed_distributions ;print('+!+'.join(['%s@+@%s@+@' % (i.key,i.version) for i in pip_get_installed_distributions()]))", ] @@ -490,11 +490,13 @@ def do_pip_action( '/D', self.target, r'&&', - osp.join(self.target, 'python.exe'), + utils.get_python_executable(self.target), + # Before PyPy: osp.join(self.target, 'python.exe') ] complement += ['-m', 'pip'] else: - executing = osp.join(self.target, 'python.exe') + executing = utils.get_python_executable(self.target) + # Before PyPy: osp.join(self.target, 'python.exe') complement = ['-m', 'pip'] try: fname = utils.do_script( @@ -525,6 +527,10 @@ def patch_standard_packages( origin = self.target + ( r"\Lib\site-packages\pywin32_system32" ) + if 'pypy3' in sys.executable: + origin = self.target + ( + r"\site-packages\pywin32_system32" + ) destin = self.target if osp.isdir(origin): for name in os.listdir(origin): @@ -548,29 +554,34 @@ def patch_standard_packages( sheb_fix = " executable = get_executable()" sheb_mov1 = " executable = os.path.join(os.path.basename(get_executable()))" sheb_mov2 = " executable = os.path.join('..',os.path.basename(get_executable()))" + if 'pypy3' in sys.executable: + the_place=r"\site-packages\pip\_vendor\distlib\scripts.py" + else: + the_place=r"\Lib\site-packages\pip\_vendor\distlib\scripts.py" + print(the_place) if to_movable: utils.patch_sourcefile( self.target - + r"\Lib\site-packages\pip\_vendor\distlib\scripts.py", + + the_place, sheb_fix, sheb_mov1, ) utils.patch_sourcefile( self.target - + r"\Lib\site-packages\pip\_vendor\distlib\scripts.py", + + the_place, sheb_mov2, sheb_mov1, ) else: utils.patch_sourcefile( self.target - + r"\Lib\site-packages\pip\_vendor\distlib\scripts.py", + + the_place, sheb_mov1, sheb_fix, ) utils.patch_sourcefile( self.target - + r"\Lib\site-packages\pip\_vendor\distlib\scripts.py", + + the_place, sheb_mov2, sheb_fix, ) @@ -686,6 +697,11 @@ def handle_specific_packages(self, package): tmp_string = r'''@echo off if "%WINPYDIR%"=="" call "%~dp0..\..\scripts\env.bat" "%WINPYDIR%\python.exe" "%WINPYDIR%\Lib\site-packages\package.name\uic\pyuic.py" %1 %2 %3 %4 %5 %6 %7 %8 %9''' + + # PyPy adaption: python.exe or pypy3.exe + my_exec = osp.basename(utils.get_python_executable(self.target)) + tmp_string = tmp_string.replace('python.exe', my_exec) + self.create_file( package, 'pyuic%s.bat' % package.name[-1], @@ -730,9 +746,10 @@ def uninstall(self, package): if not package.name == 'pip': # trick to get true target (if not current) this_executable_path = self.target + this_exec = utils.get_python_executable(self.target) # PyPy ! subprocess.call( [ - this_executable_path + r'\python.exe', + this_exec, '-m', 'pip', 'uninstall', @@ -755,9 +772,7 @@ def install_bdist_direct( try: fname = utils.direct_pip_install( package.fname, - python_exe=osp.join( - self.target, 'python.exe' - ), + python_exe=utils.get_python_executable(self.target), # PyPy ! architecture=self.architecture, verbose=self.verbose, install_options=install_options, @@ -773,9 +788,7 @@ def install_script(self, script, install_options=None): try: fname = utils.do_script( script, - python_exe=osp.join( - self.target, 'python.exe' - ), + python_exe=utils.get_python_executable(self.target), # PyPy3 ! architecture=self.architecture, verbose=self.verbose, install_options=install_options,