about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_working_set.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/pkg_resources/tests/test_working_set.py')
-rw-r--r--.venv/lib/python3.12/site-packages/pkg_resources/tests/test_working_set.py505
1 files changed, 505 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_working_set.py b/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_working_set.py
new file mode 100644
index 00000000..ed20c59d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/pkg_resources/tests/test_working_set.py
@@ -0,0 +1,505 @@
+import functools
+import inspect
+import re
+import textwrap
+
+import pytest
+
+import pkg_resources
+
+from .test_resources import Metadata
+
+
+def strip_comments(s):
+    return '\n'.join(
+        line
+        for line in s.split('\n')
+        if line.strip() and not line.strip().startswith('#')
+    )
+
+
+def parse_distributions(s):
+    """
+    Parse a series of distribution specs of the form:
+    {project_name}-{version}
+       [optional, indented requirements specification]
+
+    Example:
+
+        foo-0.2
+        bar-1.0
+          foo>=3.0
+          [feature]
+          baz
+
+    yield 2 distributions:
+        - project_name=foo, version=0.2
+        - project_name=bar, version=1.0,
+          requires=['foo>=3.0', 'baz; extra=="feature"']
+    """
+    s = s.strip()
+    for spec in re.split(r'\n(?=[^\s])', s):
+        if not spec:
+            continue
+        fields = spec.split('\n', 1)
+        assert 1 <= len(fields) <= 2
+        name, version = fields.pop(0).rsplit('-', 1)
+        if fields:
+            requires = textwrap.dedent(fields.pop(0))
+            metadata = Metadata(('requires.txt', requires))
+        else:
+            metadata = None
+        dist = pkg_resources.Distribution(
+            project_name=name, version=version, metadata=metadata
+        )
+        yield dist
+
+
+class FakeInstaller:
+    def __init__(self, installable_dists) -> None:
+        self._installable_dists = installable_dists
+
+    def __call__(self, req):
+        return next(
+            iter(filter(lambda dist: dist in req, self._installable_dists)), None
+        )
+
+
+def parametrize_test_working_set_resolve(*test_list):
+    idlist = []
+    argvalues = []
+    for test in test_list:
+        (
+            name,
+            installed_dists,
+            installable_dists,
+            requirements,
+            expected1,
+            expected2,
+        ) = (
+            strip_comments(s.lstrip())
+            for s in textwrap.dedent(test).lstrip().split('\n\n', 5)
+        )
+        installed_dists = list(parse_distributions(installed_dists))
+        installable_dists = list(parse_distributions(installable_dists))
+        requirements = list(pkg_resources.parse_requirements(requirements))
+        for id_, replace_conflicting, expected in (
+            (name, False, expected1),
+            (name + '_replace_conflicting', True, expected2),
+        ):
+            idlist.append(id_)
+            expected = strip_comments(expected.strip())
+            if re.match(r'\w+$', expected):
+                expected = getattr(pkg_resources, expected)
+                assert issubclass(expected, Exception)
+            else:
+                expected = list(parse_distributions(expected))
+            argvalues.append(
+                pytest.param(
+                    installed_dists,
+                    installable_dists,
+                    requirements,
+                    replace_conflicting,
+                    expected,
+                )
+            )
+    return pytest.mark.parametrize(
+        (
+            "installed_dists",
+            "installable_dists",
+            "requirements",
+            "replace_conflicting",
+            "resolved_dists_or_exception",
+        ),
+        argvalues,
+        ids=idlist,
+    )
+
+
+@parametrize_test_working_set_resolve(
+    """
+    # id
+    noop
+
+    # installed
+
+    # installable
+
+    # wanted
+
+    # resolved
+
+    # resolved [replace conflicting]
+    """,
+    """
+    # id
+    already_installed
+
+    # installed
+    foo-3.0
+
+    # installable
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    foo-3.0
+
+    # resolved [replace conflicting]
+    foo-3.0
+    """,
+    """
+    # id
+    installable_not_installed
+
+    # installed
+
+    # installable
+    foo-3.0
+    foo-4.0
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    foo-3.0
+
+    # resolved [replace conflicting]
+    foo-3.0
+    """,
+    """
+    # id
+    not_installable
+
+    # installed
+
+    # installable
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    DistributionNotFound
+
+    # resolved [replace conflicting]
+    DistributionNotFound
+    """,
+    """
+    # id
+    no_matching_version
+
+    # installed
+
+    # installable
+    foo-3.1
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    DistributionNotFound
+
+    # resolved [replace conflicting]
+    DistributionNotFound
+    """,
+    """
+    # id
+    installable_with_installed_conflict
+
+    # installed
+    foo-3.1
+
+    # installable
+    foo-3.5
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    foo-3.5
+    """,
+    """
+    # id
+    not_installable_with_installed_conflict
+
+    # installed
+    foo-3.1
+
+    # installable
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    DistributionNotFound
+    """,
+    """
+    # id
+    installed_with_installed_require
+
+    # installed
+    foo-3.9
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # installable
+
+    # wanted
+    baz
+
+    # resolved
+    foo-3.9
+    baz-0.1
+
+    # resolved [replace conflicting]
+    foo-3.9
+    baz-0.1
+    """,
+    """
+    # id
+    installed_with_conflicting_installed_require
+
+    # installed
+    foo-5
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # installable
+
+    # wanted
+    baz
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    DistributionNotFound
+    """,
+    """
+    # id
+    installed_with_installable_conflicting_require
+
+    # installed
+    foo-5
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # installable
+    foo-2.9
+
+    # wanted
+    baz
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    baz-0.1
+    foo-2.9
+    """,
+    """
+    # id
+    installed_with_installable_require
+
+    # installed
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # installable
+    foo-3.9
+
+    # wanted
+    baz
+
+    # resolved
+    foo-3.9
+    baz-0.1
+
+    # resolved [replace conflicting]
+    foo-3.9
+    baz-0.1
+    """,
+    """
+    # id
+    installable_with_installed_require
+
+    # installed
+    foo-3.9
+
+    # installable
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # wanted
+    baz
+
+    # resolved
+    foo-3.9
+    baz-0.1
+
+    # resolved [replace conflicting]
+    foo-3.9
+    baz-0.1
+    """,
+    """
+    # id
+    installable_with_installable_require
+
+    # installed
+
+    # installable
+    foo-3.9
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # wanted
+    baz
+
+    # resolved
+    foo-3.9
+    baz-0.1
+
+    # resolved [replace conflicting]
+    foo-3.9
+    baz-0.1
+    """,
+    """
+    # id
+    installable_with_conflicting_installable_require
+
+    # installed
+    foo-5
+
+    # installable
+    foo-2.9
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # wanted
+    baz
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    baz-0.1
+    foo-2.9
+    """,
+    """
+    # id
+    conflicting_installables
+
+    # installed
+
+    # installable
+    foo-2.9
+    foo-5.0
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+    foo>=4
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    VersionConflict
+    """,
+    """
+    # id
+    installables_with_conflicting_requires
+
+    # installed
+
+    # installable
+    foo-2.9
+        dep==1.0
+    baz-5.0
+        dep==2.0
+    dep-1.0
+    dep-2.0
+
+    # wanted
+    foo
+    baz
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    VersionConflict
+    """,
+    """
+    # id
+    installables_with_conflicting_nested_requires
+
+    # installed
+
+    # installable
+    foo-2.9
+        dep1
+    dep1-1.0
+        subdep<1.0
+    baz-5.0
+        dep2
+    dep2-1.0
+        subdep>1.0
+    subdep-0.9
+    subdep-1.1
+
+    # wanted
+    foo
+    baz
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    VersionConflict
+    """,
+    """
+    # id
+    wanted_normalized_name_installed_canonical
+
+    # installed
+    foo.bar-3.6
+
+    # installable
+
+    # wanted
+    foo-bar==3.6
+
+    # resolved
+    foo.bar-3.6
+
+    # resolved [replace conflicting]
+    foo.bar-3.6
+    """,
+)
+def test_working_set_resolve(
+    installed_dists,
+    installable_dists,
+    requirements,
+    replace_conflicting,
+    resolved_dists_or_exception,
+):
+    ws = pkg_resources.WorkingSet([])
+    list(map(ws.add, installed_dists))
+    resolve_call = functools.partial(
+        ws.resolve,
+        requirements,
+        installer=FakeInstaller(installable_dists),
+        replace_conflicting=replace_conflicting,
+    )
+    if inspect.isclass(resolved_dists_or_exception):
+        with pytest.raises(resolved_dists_or_exception):
+            resolve_call()
+    else:
+        assert sorted(resolve_call()) == sorted(resolved_dists_or_exception)