Esempio n. 1
0
    def handle_specific_packages(self, package):
        """Packages requiring additional configuration"""
        if package.name.lower() in (
                'pyqt4',
                'pyqt5',
                'pyside2',
        ):
            # Qt configuration file (where to find Qt)
            name = 'qt.conf'
            contents = """[Paths]
Prefix = .
Binaries = ."""
            self.create_file(
                package,
                name,
                osp.join('Lib', 'site-packages', package.name),
                contents,
            )
            self.create_file(
                package,
                name,
                '.',
                contents.replace(
                    '.',
                    './Lib/site-packages/%s' % package.name,
                ),
            )
            # pyuic script
            if package.name.lower() == 'pyqt5':
                # see http://code.activestate.com/lists/python-list/666469/
                tmp_string = r'''@echo off
if "%WINPYDIR%"=="" call "%~dp0..\..\scripts\env.bat"
"%WINPYDIR%\python.exe" -m PyQt5.uic.pyuic %1 %2 %3 %4 %5 %6 %7 %8 %9'''
            else:
                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],
                'Scripts',
                tmp_string.replace('package.name', package.name),
            )
            # Adding missing __init__.py files (fixes Issue 8)
            uic_path = osp.join('Lib', 'site-packages', package.name, 'uic')
            for dirname in ('Loader', 'port_v2', 'port_v3'):
                self.create_file(
                    package,
                    '__init__.py',
                    osp.join(uic_path, dirname),
                    '',
                )
Esempio n. 2
0
 def do_pip_action(
     self, actions=None, install_options=None
 ):
     """Do pip action in a distribution"""
     my_list = install_options
     if my_list is None:
         my_list = []
     my_actions = actions
     if my_actions is None:
         my_actions = []
     executing = osp.join(
         self.target, '..', 'scripts', 'env.bat'
     )
     if osp.isfile(executing):
         complement = [
             r'&&',
             'cd',
             '/D',
             self.target,
             r'&&',
             utils.get_python_executable(self.target), 
             # Before PyPy: osp.join(self.target, 'python.exe')
         ]
         complement += ['-m', 'pip']
     else:
         executing = utils.get_python_executable(self.target)
         # Before PyPy: osp.join(self.target, 'python.exe')
         complement = ['-m', 'pip']
     try:
         fname = utils.do_script(
             this_script=None,
             python_exe=executing,
             architecture=self.architecture,
             verbose=self.verbose,
             install_options=complement
             + my_actions
             + my_list,
         )
     except RuntimeError:
         if not self.verbose:
             print("Failed!")
             raise
Esempio n. 3
0
 def install_script(self, script, install_options=None):
     try:
         fname = utils.do_script(
             script,
             python_exe=utils.get_python_executable(self.target),  # PyPy3 !
             architecture=self.architecture,
             verbose=self.verbose,
             install_options=install_options,
         )
     except RuntimeError:
         if not self.verbose:
             print("Failed!")
             raise
Esempio n. 4
0
    def __init__(self, target=None, verbose=False, indent=False):
        self.target = target
        self.verbose = verbose
        self.indent = indent

        # if no target path given, take the current python interpreter one
        if self.target is None:
            self.target = os.path.dirname(sys.executable)
        self.to_be_removed = ([])  # list of directories to be removed later

        self.version, self.architecture = utils.get_python_infos(target)
        # name of the exe (python.exe or pypy3;exe)
        self.short_exe = osp.basename(utils.get_python_executable(self.target))
Esempio n. 5
0
    def get_installed_packages(self, update=False):
        """Return installed packages"""

        # Include package installed via pip (not via WPPM)
        wppm = []
        try:
            if (os.path.dirname(sys.executable) == self.target):
                #  direct way: we interrogate ourself, using official API
                import pkg_resources, importlib

                importlib.reload(pkg_resources)
                pip_list = [(i.key, i.version)
                            for i in pkg_resources.working_set]
            else:
                #  indirect way: we interrogate something else
                cmdx = [
                    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()]))",
                ]
                p = subprocess.Popen(
                    cmdx,
                    shell=True,
                    stdout=subprocess.PIPE,
                    cwd=self.target,
                )
                stdout, stderr = p.communicate()
                start_at = (2 if sys.version_info >= (3, 0) else 0)
                pip_list = [
                    line.split("@+@")[:2]
                    for line in ("%s" % stdout)[start_at:].split("+!+")
                ]
            # there are only Packages installed with pip now
            # create pip package list
            wppm = [
                Package('%s-%s-py2.py3-none-any.whl' %
                        (i[0].replace('-', '_').lower(), i[1]),
                        update=update) for i in pip_list
            ]
        except:
            pass
        return sorted(wppm, key=lambda tup: tup.name.lower())
Esempio n. 6
0
 def install_bdist_direct(self, package, install_options=None):
     """Install a package directly !"""
     self._print(
         package,
         "Installing %s" % package.fname.split(".")[-1],
     )
     try:
         fname = utils.direct_pip_install(
             package.fname,
             python_exe=utils.get_python_executable(self.target),  # PyPy !
             architecture=self.architecture,
             verbose=self.verbose,
             install_options=install_options,
         )
     except RuntimeError:
         if not self.verbose:
             print("Failed!")
             raise
     package = Package(fname)
     self._print_done()
Esempio n. 7
0
 def uninstall(self, package):
     """Uninstall package from distribution"""
     self._print(package, "Uninstalling")
     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_exec,
                 '-m',
                 'pip',
                 'uninstall',
                 package.name,
                 '-y',
             ],
             cwd=this_executable_path,
         )
         # no more legacy, no package are installed by old non-pip means
     self._print_done()
Esempio n. 8
0
    def get_installed_packages(self, update=False):
        """Return installed packages"""

        # Include package installed via pip (not via WPPM)
        wppm = []
        try:
            if (
                os.path.dirname(sys.executable)
                == self.target
            ):
                #  win pip 22.2, we can use pip inspect API
                pip = piptree.pipdata()
                pip_list = pip.pip_list()
            else:
                #  indirect way: we use pip list (for now)
                cmdx = [
                    utils.get_python_executable(self.target), # PyPy !
                    '-m',
                    "pip", "list",
                ]
                pip_list_raw = utils.exec_run_cmd(cmdx).splitlines()
                # pip list gives 2 lines of titles to ignore
                pip_list = [ l.split()  for l in pip_list_raw[2:] ]
            # there are only Packages installed with pip now
            # create pip package list
            wppm = [
                Package(
                    '%s-%s-py2.py3-none-any.whl'
                    % (i[0].replace('-', '_').lower(), i[1])
                , update=update)
                for i in pip_list
            ]
        except:
            pass
        return sorted(
            wppm, key=lambda tup: tup.name.lower()
        )
Esempio n. 9
0
    def patch_standard_packages(self, package_name='', to_movable=True):
        """patch Winpython packages in need"""
        import filecmp

        # Adpating to PyPy
        if 'pypy3' in osp.basename(utils.get_python_executable(self.target)):
            site_package_place = "\\site-packages\\"
        else:
            site_package_place = "\\Lib\\site-packages\\"

        # 'pywin32' minimal post-install (pywin32_postinstall.py do too much)
        if (package_name.lower() == "pywin32" or package_name == ''):
            origin = self.target + site_package_place + "pywin32_system32"

            destin = self.target
            if osp.isdir(origin):
                for name in os.listdir(origin):
                    here, there = (
                        osp.join(origin, name),
                        osp.join(destin, name),
                    )
                    if not os.path.exists(there) or not filecmp.cmp(
                            here, there):
                        shutil.copyfile(here, there)
        # 'pip' to do movable launchers (around line 100) !!!!
        # rational: https://github.com/pypa/pip/issues/2328
        if (package_name.lower() == "pip" or package_name == ''):
            # ensure pip will create movable launchers
            # sheb_mov1 = classic way up to WinPython 2016-01
            # sheb_mov2 = tried  way, but doesn't work for pip (at least)
            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()))"

            # Adpating to PyPy
            the_place = site_package_place + r"pip\_vendor\distlib\scripts.py"
            print(the_place)
            if to_movable:
                utils.patch_sourcefile(
                    self.target + the_place,
                    sheb_fix,
                    sheb_mov1,
                )
                utils.patch_sourcefile(
                    self.target + the_place,
                    sheb_mov2,
                    sheb_mov1,
                )
            else:
                utils.patch_sourcefile(
                    self.target + the_place,
                    sheb_mov1,
                    sheb_fix,
                )
                utils.patch_sourcefile(
                    self.target + the_place,
                    sheb_mov2,
                    sheb_fix,
                )
            # ensure pip wheel will register relative PATH in 'RECORD' files
            # will be in standard pip 8.0.3
            utils.patch_sourcefile(
                self.target + (site_package_place + r"pip\wheel.py"),
                " writer.writerow((f, h, l))",
                " writer.writerow((normpath(f, lib_dir), h, l))",
            )

            # create movable launchers for previous package installations
            self.patch_all_shebang(to_movable=to_movable)
        if (package_name.lower() == "spyder" or package_name == ''):
            # spyder don't goes on internet without I ask
            utils.patch_sourcefile(
                self.target +
                (site_package_place + r"spyderlib\config\main.py"),
                "'check_updates_on_startup': True,",
                "'check_updates_on_startup': False,",
            )
            utils.patch_sourcefile(
                self.target + (site_package_place + r"spyder\config\main.py"),
                "'check_updates_on_startup': True,",
                "'check_updates_on_startup': False,",
            )
        # workaround bad installers
        if package_name.lower() == "numba":
            self.create_pybat(['numba', 'pycc'])
        else:
            self.create_pybat(package_name.lower())
def register(target, current=True):
    """Register a Python distribution in Windows registry"""
    root = (winreg.HKEY_CURRENT_USER if current else winreg.HKEY_LOCAL_MACHINE)

    # Extensions
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".py"),
        "",
        0,
        winreg.REG_SZ,
        "Python.File",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".pyw"),
        "",
        0,
        winreg.REG_SZ,
        "Python.NoConFile",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".pyc"),
        "",
        0,
        winreg.REG_SZ,
        "Python.CompiledFile",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".pyo"),
        "",
        0,
        winreg.REG_SZ,
        "Python.CompiledFile",
    )

    # MIME types
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".py"),
        "Content Type",
        0,
        winreg.REG_SZ,
        "text/plain",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".pyw"),
        "Content Type",
        0,
        winreg.REG_SZ,
        "text/plain",
    )

    # Verbs
    python = utils.get_python_executable(target)  # PyPy !
    pythonw = python[:-4] + 'w.exe'
    spyder = osp.abspath(osp.join(target, os.pardir, 'Spyder.exe'))
    if not osp.isfile(spyder):
        spyder = '%s" "%s\Scripts\spyder' % (
            pythonw,
            target,
        )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("", "open")),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%%1" %%*' % python,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("NoCon", "open")),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%%1" %%*' % pythonw,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("Compiled", "open")),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%%1" %%*' % python,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("", EWI)),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%s\Lib\idlelib\idle.pyw" -n -e "%%1"' % (pythonw, target),
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("NoCon", EWI)),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%s\Lib\idlelib\idle.pyw" -n -e "%%1"' % (pythonw, target),
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("", EWS)),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%%1"' % spyder,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("NoCon", EWS)),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%%1"' % spyder,
    )

    # Drop support
    handler = "{60254CA5-953B-11CF-8C96-00AA00B8708C}"
    for ftype in ("", "NoCon", "Compiled"):
        winreg.SetValueEx(
            winreg.CreateKey(root, KEY_DROP1 % ftype),
            "",
            0,
            winreg.REG_SZ,
            handler,
        )
    # Icons
    dlls = osp.join(target, 'DLLs')
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_I % ""),
        "",
        0,
        winreg.REG_SZ,
        r'%s\py.ico' % dlls,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_I % "NoCon"),
        "",
        0,
        winreg.REG_SZ,
        r'%s\py.ico' % dlls,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_I % "Compiled"),
        "",
        0,
        winreg.REG_SZ,
        r'%s\pyc.ico' % dlls,
    )

    # Descriptions
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_D % ""),
        "",
        0,
        winreg.REG_SZ,
        "Python File",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_D % "NoCon"),
        "",
        0,
        winreg.REG_SZ,
        "Python File (no console)",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_D % "Compiled"),
        "",
        0,
        winreg.REG_SZ,
        "Compiled Python File",
    )

    # PythonCore entries
    short_version = utils.get_python_infos(target)[0]
    long_version = utils.get_python_long_version(target)
    key_core = (KEY_S1 % short_version) + r'\%s'
    winreg.SetValueEx(
        winreg.CreateKey(root, key_core % 'InstallPath'),
        "",
        0,
        winreg.REG_SZ,
        target,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, key_core % r'InstallPath\InstallGroup'),
        "",
        0,
        winreg.REG_SZ,
        "Python %s" % short_version,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, key_core % 'Modules'),
        "",
        0,
        winreg.REG_SZ,
        "",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, key_core % 'PythonPath'),
        "",
        0,
        winreg.REG_SZ,
        r"%s\Lib;%s\DLLs" % (target, target),
    )
    winreg.SetValueEx(
        winreg.CreateKey(
            root,
            key_core % r'Help\Main Python Documentation',
        ),
        "",
        0,
        winreg.REG_SZ,
        r"%s\Doc\python%s.chm" % (target, long_version),
    )

    # Create start menu entries for all WinPython launchers
    for path, desc, fname in _get_shortcut_data(target, current=current):
        utils.create_shortcut(path, desc, fname)
    # Register the Python ActiveX Scripting client (requires pywin32)
    axscript = osp.join(
        target,
        'Lib',
        'site-packages',
        'win32comext',
        'axscript',
        'client',
        'pyscript.py',
    )
    if osp.isfile(axscript):
        subprocess.call('"%s" "%s"' % (python, axscript), cwd=target)
    else:
        print(
            'Unable to register ActiveX: please install pywin32',
            file=sys.stderr,
        )