Exemple #1
0
    def get_include_path(self):
        # type: () -> Optional[Dict[str, str]]
        """Get the include path for the environment

        :return: The python include path for the environment
        :rtype: Dict[str, str]
        """
        tmpfile = vistir.path.create_tracked_tempfile(suffix=".json")
        tmpfile.close()
        tmpfile_path = make_posix(tmpfile.name)
        py_command = (
            "import distutils.sysconfig, io, json, sys; paths = {{u'include': "
            "u'{{0}}'.format(distutils.sysconfig.get_python_inc(plat_specific=0)), "
            "u'platinclude': u'{{0}}'.format(distutils.sysconfig.get_python_inc("
            "plat_specific=1)) }}; value = u'{{0}}'.format(json.dumps(paths));"
            "fh = io.open('{0}', 'w'); fh.write(value); fh.close()")
        command = [self.python, "-c", py_command.format(tmpfile_path)]
        c = subprocess_run(command)
        if c.returncode == 0:
            paths = []
            with open(tmpfile_path, "r", encoding="utf-8") as fh:
                paths = json.load(fh)
            for key in ("include", "platinclude"):
                if key in paths:
                    paths[key] = make_posix(paths[key])
            return paths
        else:
            vistir.misc.echo(f"Failed to load paths: {c.stderr}", fg="yellow")
            vistir.misc.echo(f"Output: {c.stdout}", fg="yellow")
        return None
Exemple #2
0
    def get_paths(self):
        # type: () -> Optional[Dict[str, str]]
        """
        Get the paths for the environment by running a subcommand

        :return: The python paths for the environment
        :rtype: Dict[str, str]
        """
        tmpfile = vistir.path.create_tracked_tempfile(suffix=".json")
        tmpfile.close()
        tmpfile_path = make_posix(tmpfile.name)
        py_command = self.build_command(python_lib=True,
                                        python_inc=True,
                                        scripts=True,
                                        py_version=True)
        command = [self.python, "-c", py_command.format(tmpfile_path)]
        c = subprocess_run(command)
        if c.returncode == 0:
            paths = {}
            with open(tmpfile_path, "r", encoding="utf-8") as fh:
                paths = json.load(fh)
            if "purelib" in paths:
                paths["libdir"] = paths["purelib"] = make_posix(
                    paths["purelib"])
            for key in ("platlib", "scripts", "platstdlib", "stdlib",
                        "include", "platinclude"):
                if key in paths:
                    paths[key] = make_posix(paths[key])
            return paths
        else:
            vistir.misc.echo(f"Failed to load paths: {c.stderr}", fg="yellow")
            vistir.misc.echo(f"Output: {c.stdout}", fg="yellow")
        return None
Exemple #3
0
    def get_lib_paths(self):
        # type: () -> Dict[str, str]
        """Get the include path for the environment

        :return: The python include path for the environment
        :rtype: Dict[str, str]
        """
        tmpfile = vistir.path.create_tracked_tempfile(suffix=".json")
        tmpfile.close()
        tmpfile_path = make_posix(tmpfile.name)
        py_command = self.build_command(python_lib=True)
        command = [self.python, "-c", py_command.format(tmpfile_path)]
        c = subprocess_run(command)
        paths = None
        if c.returncode == 0:
            paths = {}
            with open(tmpfile_path, "r", encoding="utf-8") as fh:
                paths = json.load(fh)
            if "purelib" in paths:
                paths["libdir"] = paths["purelib"] = make_posix(
                    paths["purelib"])
            for key in ("platlib", "platstdlib", "stdlib"):
                if key in paths:
                    paths[key] = make_posix(paths[key])
            return paths
        else:
            vistir.misc.echo(f"Failed to load paths: {c.stderr}", fg="yellow")
            vistir.misc.echo(f"Output: {c.stdout}", fg="yellow")
        if not paths:
            if not self.prefix.joinpath("lib").exists():
                return {}
            stdlib_path = next(
                iter([
                    p for p in self.prefix.joinpath("lib").iterdir()
                    if p.name.startswith("python")
                ]), None)
            lib_path = None
            if stdlib_path:
                lib_path = next(
                    iter([
                        p.as_posix() for p in stdlib_path.iterdir()
                        if p.name == "site-packages"
                    ]))
                paths = {"stdlib": stdlib_path.as_posix()}
                if lib_path:
                    paths["purelib"] = lib_path
                return paths
        return {}
Exemple #4
0
 def script_basedir(self):
     # type: () -> str
     """Path to the environment scripts dir"""
     prefix = make_posix(self.prefix.as_posix())
     install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix'
     paths = get_paths(install_scheme,
                       vars={
                           'base': prefix,
                           'platbase': prefix,
                       })
     return paths["scripts"]
Exemple #5
0
 def dist_is_in_project(self, dist):
     # type: (pkg_resources.Distribution) -> bool
     """Determine whether the supplied distribution is in the environment."""
     from .environments import normalize_pipfile_path as _normalized
     prefixes = [
         _normalized(prefix)
         for prefix in self.base_paths["libdirs"].split(os.pathsep)
         if _normalized(prefix).startswith(
             _normalized(self.prefix.as_posix()))
     ]
     location = self.locate_dist(dist)
     if not location:
         return False
     location = _normalized(make_posix(location))
     return any(location.startswith(prefix) for prefix in prefixes)
Exemple #6
0
    def base_paths(self):
        # type: () -> Dict[str, str]
        """
        Returns the context appropriate paths for the environment.

        :return: A dictionary of environment specific paths to be used for installation operations
        :rtype: dict

        .. note:: The implementation of this is borrowed from a combination of pip and
           virtualenv and is likely to change at some point in the future.

        >>> from pipenv.core import project
        >>> from pipenv.environment import Environment
        >>> env = Environment(prefix=project.virtualenv_location, is_venv=True, sources=project.sources)
        >>> import pprint
        >>> pprint.pprint(env.base_paths)
        {'PATH': '/home/hawk/.virtualenvs/pipenv-MfOPs1lW/bin::/bin:/usr/bin',
        'PYTHONPATH': '/home/hawk/.virtualenvs/pipenv-MfOPs1lW/lib/python3.7/site-packages',
        'data': '/home/hawk/.virtualenvs/pipenv-MfOPs1lW',
        'include': '/home/hawk/.pyenv/versions/3.7.1/include/python3.7m',
        'libdir': '/home/hawk/.virtualenvs/pipenv-MfOPs1lW/lib/python3.7/site-packages',
        'platinclude': '/home/hawk/.pyenv/versions/3.7.1/include/python3.7m',
        'platlib': '/home/hawk/.virtualenvs/pipenv-MfOPs1lW/lib/python3.7/site-packages',
        'platstdlib': '/home/hawk/.virtualenvs/pipenv-MfOPs1lW/lib/python3.7',
        'prefix': '/home/hawk/.virtualenvs/pipenv-MfOPs1lW',
        'purelib': '/home/hawk/.virtualenvs/pipenv-MfOPs1lW/lib/python3.7/site-packages',
        'scripts': '/home/hawk/.virtualenvs/pipenv-MfOPs1lW/bin',
        'stdlib': '/home/hawk/.pyenv/versions/3.7.1/lib/python3.7'}
        """

        prefix = make_posix(self.prefix.as_posix())
        paths = {}
        if self._base_paths:
            paths = self._base_paths.copy()
        else:
            try:
                paths = self.get_paths()
            except Exception:
                install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix'
                paths = get_paths(install_scheme,
                                  vars={
                                      'base': prefix,
                                      'platbase': prefix,
                                  })
                current_version = get_python_version()
                try:
                    for k in list(paths.keys()):
                        if not os.path.exists(paths[k]):
                            paths[k] = self._replace_parent_version(
                                paths[k], current_version)
                except OSError:
                    # Sometimes virtualenvs are made using virtualenv interpreters and there is no
                    # include directory, which will cause this approach to fail. This failsafe
                    # will make sure we fall back to the shell execution to find the real include path
                    paths = self.get_include_path()
                    paths.update(self.get_lib_paths())
                    paths["scripts"] = self.script_basedir
        if not paths:
            install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix'
            paths = get_paths(install_scheme,
                              vars={
                                  'base': prefix,
                                  'platbase': prefix,
                              })
        if not os.path.exists(paths["purelib"]) and not os.path.exists(
                paths["platlib"]):
            lib_paths = self.get_lib_paths()
            paths.update(lib_paths)
        paths["PATH"] = paths["scripts"] + os.pathsep + os.defpath
        if "prefix" not in paths:
            paths["prefix"] = prefix
        purelib = paths["purelib"] = make_posix(paths["purelib"])
        platlib = paths["platlib"] = make_posix(paths["platlib"])
        if purelib == platlib:
            lib_dirs = purelib
        else:
            lib_dirs = purelib + os.pathsep + platlib
        paths["libdir"] = purelib
        paths['PYTHONPATH'] = os.pathsep.join(["", ".", lib_dirs])
        paths["libdirs"] = lib_dirs
        return paths