Coverage for src/gitlabracadabra/packages/pip.py: 74%
19 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-10 14:45 +0100
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-10 14:45 +0100
1# Copyright (C) 2008-2021 The pip developers (see AUTHORS.txt file)
2#
3# Permission is hereby granted, free of charge, to any person obtaining
4# a copy of this software and associated documentation files (the
5# "Software"), to deal in the Software without restriction, including
6# without limitation the rights to use, copy, modify, merge, publish,
7# distribute, sublicense, and/or sell copies of the Software, and to
8# permit persons to whom the Software is furnished to do so, subject to
9# the following conditions:
10# .
11# The above copyright notice and this permission notice shall be
12# included in all copies or substantial portions of the Software.
13# .
14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23from packaging.utils import canonicalize_name
25# The functions below are copied from pip:
26# _internal/index/package_finder.py
29def _find_name_version_sep(fragment: str, canonical_name: str) -> int:
30 """Find the separator's index based on the package's canonical name.
32 :param fragment: A <package>+<version> filename "fragment" (stem) or
33 egg fragment.
34 :param canonical_name: The package's canonical name.
36 This function is needed since the canonicalized name does not necessarily
37 have the same length as the egg info's name part. An example::
39 >>> fragment = "foo__bar-1.0"
40 >>> canonical_name = "foo-bar"
41 >>> _find_name_version_sep(fragment, canonical_name)
42 8
43 """
44 # Project name and version must be separated by one single dash. Find all
45 # occurrences of dashes; if the string in front of it matches the canonical
46 # name, this is the one separating the name and version parts.
47 for i, c in enumerate(fragment): 47 ↛ 52line 47 didn't jump to line 52 because the loop on line 47 didn't complete
48 if c != "-":
49 continue
50 if canonicalize_name(fragment[:i]) == canonical_name:
51 return i
52 msg = f"{fragment} does not match {canonical_name}"
53 raise ValueError(msg)
56def _extract_version_from_fragment(fragment: str, canonical_name: str) -> str | None:
57 """Parse the version string from a <package>+<version> filename
58 "fragment" (stem) or egg fragment.
60 :param fragment: The string to parse. E.g. foo-2.1
61 :param canonical_name: The canonicalized name of the package this
62 belongs to.
63 """
64 try:
65 version_start = _find_name_version_sep(fragment, canonical_name) + 1
66 except ValueError:
67 return None
68 version = fragment[version_start:]
69 if not version: 69 ↛ 70line 69 didn't jump to line 70 because the condition on line 69 was never true
70 return None
71 return version
74extract_version_from_fragment = _extract_version_from_fragment