Example #1
0
def test_convert_dependencies():
    package = Package('foo', '1.2.3')
    result = SdistBuilder.convert_dependencies(package, [
        get_dependency('A', '^1.0'),
        get_dependency('B', '~1.0'),
        get_dependency('C', '1.2.3'),
    ])
    main = [
        'A (>=1.0.0.0,<2.0.0.0)',
        'B (>=1.0.0.0,<1.1.0.0)',
        'C (==1.2.3.0)',
    ]
    extras = {}

    assert result == (main, extras)

    package = Package('foo', '1.2.3')
    package.extras = {'bar': [get_dependency('A')]}

    result = SdistBuilder.convert_dependencies(package, [
        get_dependency('A', '>=1.2', optional=True),
        get_dependency('B', '~1.0'),
        get_dependency('C', '1.2.3'),
    ])
    main = [
        'B (>=1.0.0.0,<1.1.0.0)',
        'C (==1.2.3.0)',
    ]
    extras = {'bar': ['A (>=1.2.0.0)']}

    assert result == (main, extras)
Example #2
0
    def load(cls, env):  # type: (Env) -> InstalledRepository
        """
        Load installed packages.

        For now, it uses the pip "freeze" command.
        """
        repo = cls()

        freeze_output = env.run_pip("freeze")
        for line in freeze_output.split("\n"):
            if "==" in line:
                name, version = re.split("={2,3}", line)
                repo.add_package(Package(name, version, version))
            elif line.startswith("-e "):
                line = line[3:].strip()
                if line.startswith("git+"):
                    url = line.lstrip("git+")
                    if "@" in url:
                        url, rev = url.rsplit("@", 1)
                    else:
                        rev = "master"

                    name = url.split("/")[-1].rstrip(".git")
                    if "#egg=" in rev:
                        rev, name = rev.split("#egg=")

                    package = Package(name, "0.0.0")
                    package.source_type = "git"
                    package.source_url = url
                    package.source_reference = rev

                    repo.add_package(package)

        return repo
Example #3
0
def test_convert_dependencies():
    package = Package("foo", "1.2.3")
    result = SdistBuilder.convert_dependencies(
        package,
        [
            get_dependency("A", "^1.0"),
            get_dependency("B", "~1.0"),
            get_dependency("C", "1.2.3"),
        ],
    )
    main = ["A>=1.0,<2.0", "B>=1.0,<1.1", "C==1.2.3"]
    extras = {}

    assert result == (main, extras)

    package = Package("foo", "1.2.3")
    package.extras = {"bar": [get_dependency("A")]}

    result = SdistBuilder.convert_dependencies(
        package,
        [
            get_dependency("A", ">=1.2", optional=True),
            get_dependency("B", "~1.0"),
            get_dependency("C", "1.2.3"),
        ],
    )
    main = ["B>=1.0,<1.1", "C==1.2.3"]
    extras = {"bar": ["A>=1.2"]}

    assert result == (main, extras)

    c = get_dependency("C", "1.2.3")
    c.python_versions = "~2.7 || ^3.6"
    d = get_dependency("D", "3.4.5", optional=True)
    d.python_versions = "~2.7 || ^3.4"

    package.extras = {"baz": [get_dependency("D")]}

    result = SdistBuilder.convert_dependencies(
        package,
        [
            get_dependency("A", ">=1.2", optional=True),
            get_dependency("B", "~1.0"),
            c,
            d,
        ],
    )
    main = ["B>=1.0,<1.1"]

    extra_python = (
        ':python_version >= "2.7" and python_version < "2.8" '
        'or python_version >= "3.6" and python_version < "4.0"'
    )
    extra_d_dependency = (
        'baz:python_version >= "2.7" and python_version < "2.8" '
        'or python_version >= "3.4" and python_version < "4.0"'
    )
    extras = {extra_python: ["C==1.2.3"], extra_d_dependency: ["D==3.4.5"]}

    assert result == (main, extras)
Example #4
0
def test_convert_dependencies():
    package = Package('foo', '1.2.3')
    result = SdistBuilder.convert_dependencies(package, [
        get_dependency('A', '^1.0'),
        get_dependency('B', '~1.0'),
        get_dependency('C', '1.2.3'),
    ])
    main = [
        'A>=1.0.0.0,<2.0.0.0',
        'B>=1.0.0.0,<1.1.0.0',
        'C==1.2.3.0',
    ]
    extras = {}

    assert result == (main, extras)

    package = Package('foo', '1.2.3')
    package.extras = {'bar': [get_dependency('A')]}

    result = SdistBuilder.convert_dependencies(package, [
        get_dependency('A', '>=1.2', optional=True),
        get_dependency('B', '~1.0'),
        get_dependency('C', '1.2.3'),
    ])
    main = [
        'B>=1.0.0.0,<1.1.0.0',
        'C==1.2.3.0',
    ]
    extras = {'bar': ['A>=1.2.0.0']}

    assert result == (main, extras)

    c = get_dependency('C', '1.2.3')
    c.python_versions = '~2.7 || ^3.6'
    d = get_dependency('D', '3.4.5', optional=True)
    d.python_versions = '~2.7 || ^3.4'

    package.extras = {'baz': [get_dependency('D')]}

    result = SdistBuilder.convert_dependencies(package, [
        get_dependency('A', '>=1.2', optional=True),
        get_dependency('B', '~1.0'), c, d
    ])
    main = [
        'B>=1.0.0.0,<1.1.0.0',
    ]

    extra_python = (
        ':(python_version >= "2.7.0.0" and python_version < "2.8.0.0") '
        'or (python_version >= "3.6.0.0" and python_version < "4.0.0.0")')
    extra_d_dependency = (
        'baz:(python_version >= "2.7.0.0" and python_version < "2.8.0.0") '
        'or (python_version >= "3.4.0.0" and python_version < "4.0.0.0")')
    extras = {
        extra_python: ['C==1.2.3.0'],
        extra_d_dependency: ['D==3.4.5.0'],
    }

    assert result == (main, extras)
Example #5
0
    def package(self,
                name: str,
                version: str,
                extras: Union[list, None] = None) -> Package:
        try:
            index = self._packages.index(Package(name, version, version))

            return self._packages[index]
        except ValueError:
            if extras is None:
                extras = []

            release_info = self.get_release_info(name, version)
            package = Package(name, version, version)
            requires_dist = release_info['requires_dist'] or []
            for req in requires_dist:
                try:
                    dependency = dependency_from_pep_508(req)
                except InvalidMarker:
                    # Invalid marker
                    # We strip the markers hoping for the best
                    req = req.split(';')[0]

                    dependency = dependency_from_pep_508(req)

                if dependency.extras:
                    for extra in dependency.extras:
                        if extra not in package.extras:
                            package.extras[extra] = []

                        package.extras[extra].append(dependency)

                if not dependency.is_optional():
                    package.requires.append(dependency)

            # Adding description
            package.description = release_info.get('summary', '')

            # Adding hashes information
            package.hashes = release_info['digests']

            # Activate extra dependencies
            for extra in extras:
                if extra in package.extras:
                    for dep in package.extras[extra]:
                        dep.activate()

                    package.requires += package.extras[extra]

            self._packages.append(package)

            return package
Example #6
0
    def specs_from_fixtures(cls, fixture_name):
        if fixture_name in cls._specs_from_fixtures:
            return cls._specs_from_fixtures[fixture_name]

        packages_by_name = {}
        with open(os.path.join(FIXTURE_INDEX_DIR,
                               fixture_name + '.json')) as fd:
            content = json.load(fd)

            for name, releases in content.items():
                packages_by_name[name] = []

                for release in releases:
                    package = Package(name, release['version'],
                                      release['version'])

                    for dependency_name, requirements in release[
                            'dependencies'].items():
                        package.requires.append(
                            Dependency(dependency_name, requirements))

                    packages_by_name[name].append(package)

                packages_by_name[name].sort(
                    key=cmp_to_key(lambda x, y: 0 if x.version[1] == y.version[
                        1] else -1 * int(less_than(x[1], y[1]) or -1)))

        return packages_by_name
Example #7
0
    def get_package_from_file(cls, file_path):  # type: (Path) -> Package
        if file_path.suffix == ".whl":
            meta = pkginfo.Wheel(str(file_path))
        else:
            # Assume sdist
            meta = pkginfo.SDist(str(file_path))

        package = Package(meta.name, meta.version)
        package.source_type = "file"
        package.source_url = file_path.as_posix()

        package.description = meta.summary
        for req in meta.requires_dist:
            dep = dependency_from_pep_508(req)
            for extra in dep.in_extras:
                if extra not in package.extras:
                    package.extras[extra] = []

                package.extras[extra].append(dep)

            if not dep.is_optional():
                package.requires.append(dep)

        if meta.requires_python:
            package.python_versions = meta.requires_python

        return package
Example #8
0
def test_accepts_fails_with_python_versions_mismatch():
    dependency = Dependency('A', '^1.0')
    dependency.python_versions = '^3.6'
    package = Package('B', '1.4')
    package.python_versions = '~3.5'

    assert not dependency.accepts(package)
Example #9
0
    def search(self, query):
        results = []

        search = {"q": query}

        response = session().get(self._url + "search", params=search)
        content = parse(response.content, namespaceHTMLElements=False)
        for result in content.findall(".//*[@class='package-snippet']"):
            name = result.find("h3/*[@class='package-snippet__name']").text
            version = result.find(
                "h3/*[@class='package-snippet__version']").text

            if not name or not version:
                continue

            description = result.find(
                "p[@class='package-snippet__description']").text
            if not description:
                description = ""

            try:
                result = Package(name, version, description)
                result.description = to_str(description.strip())
                results.append(result)
            except ParseVersionError:
                self._log(
                    'Unable to parse version "{}" for the {} package, skipping'
                    .format(version, name),
                    level="debug",
                )

        return results
Example #10
0
def test_accepts_python_versions():
    dependency = Dependency('A', '^1.0')
    dependency.python_versions = '^3.6'
    package = Package('A', '1.4')
    package.python_versions = '~3.6'

    assert dependency.accepts(package)
def test_accepts_python_versions():
    dependency = Dependency("A", "^1.0")
    dependency.python_versions = "^3.6"
    package = Package("A", "1.4")
    package.python_versions = "~3.6"

    assert dependency.accepts(package)
Example #12
0
    def find_packages(
        self,
        name,  # type: str
        constraint=None,  # type: Union[Constraint, str, None]
        extras=None  # type: Union[list, None]
    ):  # type: (...) -> List[Package]
        """
        Find packages on the remote server.
        """
        packages = []

        if constraint is not None and not isinstance(constraint,
                                                     BaseConstraint):
            version_parser = VersionParser()
            constraint = version_parser.parse_constraints(constraint)

        info = self.get_package_info(name)

        versions = []

        for version, release in info['releases'].items():
            if (not constraint or
                (constraint and constraint.matches(Constraint('=', version)))):
                versions.append(version)

        for version in versions:
            packages.append(Package(name, version, version))

        return packages
def test_accepts_fails_with_python_versions_mismatch():
    dependency = Dependency("A", "^1.0")
    dependency.python_versions = "^3.6"
    package = Package("B", "1.4")
    package.python_versions = "~3.5"

    assert not dependency.accepts(package)
Example #14
0
def test_package_add_dependency_vcs_category_default_main():
    package = Package("foo", "0.1.0")

    dependency = package.add_dependency(
        "poetry",
        constraint={"git": "https://github.com/python-poetry/poetry.git"})
    assert dependency.category == "main"
Example #15
0
    def search(self, query, mode=0):
        results = []

        search = {"name": query}

        if mode == self.SEARCH_FULLTEXT:
            search["summary"] = query

        client = ServerProxy("https://pypi.python.org/pypi")
        hits = client.search(search, "or")

        for hit in hits:
            try:
                result = Package(hit["name"], hit["version"], hit["version"])
                result.description = to_str(hit["summary"])
                results.append(result)
            except ParseVersionError:
                self._log(
                    'Unable to parse version "{}" for the {} package, skipping'.format(
                        hit["version"], hit["name"]
                    ),
                    level="debug",
                )

        return results
Example #16
0
    def get_package_from_file(cls, file_path):  # type: (Path) -> Package
        info = Inspector().inspect(file_path)
        if not info["name"]:
            raise RuntimeError(
                "Unable to determine the package name of {}".format(file_path))

        package = Package(info["name"], info["version"])
        package.source_type = "file"
        package.source_url = file_path.as_posix()

        package.description = info["summary"]
        for req in info["requires_dist"]:
            dep = dependency_from_pep_508(req)
            for extra in dep.in_extras:
                if extra not in package.extras:
                    package.extras[extra] = []

                package.extras[extra].append(dep)

            if not dep.is_optional():
                package.requires.append(dep)

        if info["requires_python"]:
            package.python_versions = info["requires_python"]

        return package
Example #17
0
    def create(cls, pac_file: Path, modified=False):

        local_config = TomlFile(pac_file.as_posix()).read()
        if "package" not in local_config:
            raise RuntimeError("[package] section not found in {}".format(
                pac_file.name))
        # Checking validity
        cls.check(local_config)

        name = str(pac_file.parent).replace("/", ".")
        version = local_config["package"]["version"]

        if not modified:
            package = Package(name, version)
        else:
            old_version = _get_old_version(pac_file)
            package = ModifiedPackage(name, version, old_version)

        package.root_dir = pac_file.parent

        if "dependencies" in local_config:
            for name, constraint in local_config["dependencies"].items():
                package.add_dependency(name, constraint)

        if "dev-dependencies" in local_config:
            for name, constraint in local_config["dev-dependencies"].items():
                package.add_dependency(name, constraint, category="dev")

        return cls(pac_file, local_config, package)
Example #18
0
    def find_packages(self,
                      name,
                      constraint=None,
                      extras=None,
                      allow_prereleases=False):
        packages = []

        if constraint is None:
            constraint = "*"

        if not isinstance(constraint, VersionConstraint):
            constraint = parse_constraint(constraint)

        if isinstance(constraint, VersionRange):
            if (constraint.max is not None and constraint.max.is_prerelease()
                    or constraint.min is not None
                    and constraint.min.is_prerelease()):
                allow_prereleases = True

        key = name
        if not constraint.is_any():
            key = "{}:{}".format(key, str(constraint))

        if self._cache.store("matches").has(key):
            versions = self._cache.store("matches").get(key)
        else:
            page = self._get("/{}/".format(
                canonicalize_name(name).replace(".", "-")))
            if page is None:
                return []

            versions = []
            for version in page.versions:
                if version.is_prerelease() and not allow_prereleases:
                    continue

                if constraint.allows(version):
                    versions.append(version)

            self._cache.store("matches").put(key, versions, 5)

        for version in versions:
            package = Package(name, version)
            package.source_type = "legacy"
            package.source_reference = self.name
            package.source_url = self._url

            if extras is not None:
                package.requires_extras = extras

            packages.append(package)

        self._log(
            "{} packages found for {} {}".format(len(packages), name,
                                                 str(constraint)),
            level="debug",
        )

        return packages
Example #19
0
def add_to_repo(repository, name, version, deps=None):
    package = Package(name, version)

    if deps:
        for dep_name, dep_constraint in deps.items():
            package.add_dependency(dep_name, dep_constraint)

    repository.add_package(package)
Example #20
0
    def load(cls, env):  # type: (Env) -> InstalledRepository
        """
        Load installed packages.

        For now, it uses the pip "freeze" command.
        """
        repo = cls()
        seen = set()

        for entry in env.sys_path:
            for distribution in sorted(
                    metadata.distributions(path=[entry]),
                    key=lambda d: str(d._path),
            ):
                name = distribution.metadata["name"]
                version = distribution.metadata["version"]
                package = Package(name, version, version)
                package.description = distribution.metadata.get("summary", "")

                if package.name in seen:
                    continue

                seen.add(package.name)

                repo.add_package(package)

                path = Path(str(distribution._path))
                is_standard_package = True
                try:
                    path.relative_to(env.site_packages)
                except ValueError:
                    is_standard_package = False

                if is_standard_package:
                    continue

                src_path = env.path / "src"

                # A VCS dependency should have been installed
                # in the src directory. If not, it's a path dependency
                try:
                    path.relative_to(src_path)

                    from poetry.vcs.git import Git

                    git = Git()
                    revision = git.rev_parse("HEAD",
                                             src_path / package.name).strip()
                    url = git.remote_url(src_path / package.name)

                    package.source_type = "git"
                    package.source_url = url
                    package.source_reference = revision
                except ValueError:
                    package.source_type = "directory"
                    package.source_url = str(path.parent)

        return repo
Example #21
0
def test_package_authors():
    package = Package('foo', '0.1.0')

    package.authors.append('Sébastien Eustace <*****@*****.**>')
    assert package.author_name == 'Sébastien Eustace'
    assert package.author_email == '*****@*****.**'

    package.authors.insert(0, 'John Doe')
    assert package.author_name == 'John Doe'
    assert package.author_email is None
Example #22
0
def test_package_authors():
    package = Package("foo", "0.1.0")

    package.authors.append("Sébastien Eustace <*****@*****.**>")
    assert package.author_name == "Sébastien Eustace"
    assert package.author_email == "*****@*****.**"

    package.authors.insert(0, "John Doe")
    assert package.author_name == "John Doe"
    assert package.author_email is None
Example #23
0
    def find_packages(
            self,
            name,  # type: str
            constraint=None,  # type: Union[VersionConstraint, str, None]
            extras=None,  # type: Union[list, None]
            allow_prereleases=False,  # type: bool
    ):  # type: (...) -> List[Package]
        """
        Find packages on the remote server.
        """
        if constraint is None:
            constraint = "*"

        if not isinstance(constraint, VersionConstraint):
            constraint = parse_constraint(constraint)

        if isinstance(constraint, VersionRange):
            if (constraint.max is not None and constraint.max.is_prerelease()
                    or constraint.min is not None
                    and constraint.min.is_prerelease()):
                allow_prereleases = True

        info = self.get_package_info(name)

        packages = []

        for version, release in info["releases"].items():
            if not release:
                # Bad release
                self._log(
                    "No release information found for {}-{}, skipping".format(
                        name, version),
                    level="debug",
                )
                continue

            package = Package(name, version)

            if package.is_prerelease() and not allow_prereleases:
                continue

            if not constraint or (constraint
                                  and constraint.allows(package.version)):
                if extras is not None:
                    package.requires_extras = extras

                packages.append(package)

        self._log(
            "{} packages found for {} {}".format(len(packages), name,
                                                 str(constraint)),
            level="debug",
        )

        return packages
Example #24
0
def test_package_authors_invalid():
    package = Package("foo", "0.1.0")

    package.authors.insert(0, "<John Doe")
    with pytest.raises(ValueError) as e:
        package.author_name

    assert (
        str(e.value) ==
        "Invalid author string. Must be in the format: John Smith <*****@*****.**>"
    )
Example #25
0
def test_package_url_category_optional(category, optional):
    package = Package("foo", "0.1.0")

    dependency = package.add_dependency(
        "poetry",
        constraint={
            "url":
            "https://github.com/python-poetry/poetry/releases/download/1.0.5/poetry-1.0.5-linux.tar.gz",
            "optional": optional,
        },
        category=category,
    )
    assert dependency.category == category
    assert dependency.is_optional() == optional
Example #26
0
    def find_packages(self,
                      name,                    # type: str
                      constraint=None,         # type: Union[Constraint, str, None]
                      extras=None,             # type: Union[list, None]
                      allow_prereleases=False  # type: bool
                      ):  # type: (...) -> List[Package]
        """
        Find packages on the remote server.
        """
        if constraint is not None and not isinstance(constraint, BaseConstraint):
            version_parser = VersionParser()
            constraint = version_parser.parse_constraints(constraint)

        info = self.get_package_info(name)

        packages = []

        for version, release in info['releases'].items():
            if not release:
                # Bad release
                self._log(
                    'No release information found for {}-{}, skipping'.format(
                        name, version
                    ),
                    level='debug'
                )
                continue

            package = Package(name, version)

            if package.is_prerelease() and not allow_prereleases:
                continue

            if (
                not constraint
                or (constraint and constraint.matches(Constraint('=', version)))
            ):
                if extras is not None:
                    package.requires_extras = extras

                packages.append(package)

        self._log(
            '{} packages found for {} {}'.format(
                len(packages), name, str(constraint)
            ),
            level='debug'
        )

        return packages
Example #27
0
    def load(cls, venv):  # type: (Venv) -> InstalledRepository
        """
        Load installed packages.

        For now, it uses the pip "freeze" command.
        """
        repo = cls()

        freeze_output = venv.run('pip', 'freeze')
        for line in freeze_output.split('\n'):
            if '==' in line:
                name, version = line.split('==')
                repo.add_package(Package(name, version, version))

        return repo
Example #28
0
    def load(cls, env):  # type: (Env) -> InstalledRepository
        """
        Load installed packages.

        For now, it uses the pip "freeze" command.
        """
        repo = cls()

        freeze_output = env.run("pip", "freeze")
        for line in freeze_output.split("\n"):
            if "==" in line:
                name, version = line.split("==")
                repo.add_package(Package(name, version, version))

        return repo
Example #29
0
    def search(self, query, mode=0):
        results = []

        search = {"name": query}

        if mode == self.SEARCH_FULLTEXT:
            search["summary"] = query

        client = ServerProxy("https://pypi.python.org/pypi")
        hits = client.search(search, "or")

        for hit in hits:
            result = Package(hit["name"], hit["version"], hit["version"])
            result.description = to_str(hit["summary"])
            results.append(result)

        return results
Example #30
0
    def search(self, query, mode=0):
        results = []

        search = {'name': query}

        if mode == self.SEARCH_FULLTEXT:
            search['summary'] = query

        client = ServerProxy('https://pypi.python.org/pypi')
        hits = client.search(search, 'or')

        for hit in hits:
            result = Package(hit['name'], hit['version'], hit['version'])
            result.description = to_str(hit['summary'])
            results.append(result)

        return results