]>
crepu.dev Git - config.git/blob - djavu-asus/elpy/rpc-venv/lib/python3.11/site-packages/packaging/utils.py
1 # This file is dual licensed under the terms of the Apache License, Version
2 # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3 # for complete details.
6 from typing
import FrozenSet
, NewType
, Tuple
, Union
, cast
8 from .tags
import Tag
, parse_tag
9 from .version
import InvalidVersion
, Version
11 BuildTag
= Union
[Tuple
[()], Tuple
[int, str]]
12 NormalizedName
= NewType("NormalizedName", str)
15 class InvalidName(ValueError):
17 An invalid distribution name; users should refer to the packaging user guide.
21 class InvalidWheelFilename(ValueError):
23 An invalid wheel filename was found, users should refer to PEP 427.
27 class InvalidSdistFilename(ValueError):
29 An invalid sdist filename was found, users should refer to the packaging user guide.
33 # Core metadata spec for `Name`
34 _validate_regex
= re
.compile(
35 r
"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re
.IGNORECASE
37 _canonicalize_regex
= re
.compile(r
"[-_.]+")
38 _normalized_regex
= re
.compile(r
"^([a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9])$")
39 # PEP 427: The build number must start with a digit.
40 _build_tag_regex
= re
.compile(r
"(\d+)(.*)")
43 def canonicalize_name(name
: str, *, validate
: bool = False) -> NormalizedName
:
44 if validate
and not _validate_regex
.match(name
):
45 raise InvalidName(f
"name is invalid: {name!r}")
46 # This is taken from PEP 503.
47 value
= _canonicalize_regex
.sub("-", name
).lower()
48 return cast(NormalizedName
, value
)
51 def is_normalized_name(name
: str) -> bool:
52 return _normalized_regex
.match(name
) is not None
55 def canonicalize_version(
56 version
: Union
[Version
, str], *, strip_trailing_zero
: bool = True
59 This is very similar to Version.__str__, but has one subtle difference
60 with the way it handles the release segment.
62 if isinstance(version
, str):
64 parsed
= Version(version
)
65 except InvalidVersion
:
66 # Legacy versions cannot be normalized
75 parts
.append(f
"{parsed.epoch}!")
78 release_segment
= ".".join(str(x
) for x
in parsed
.release
)
79 if strip_trailing_zero
:
80 # NB: This strips trailing '.0's to normalize
81 release_segment
= re
.sub(r
"(\.0)+$", "", release_segment
)
82 parts
.append(release_segment
)
85 if parsed
.pre
is not None:
86 parts
.append("".join(str(x
) for x
in parsed
.pre
))
89 if parsed
.post
is not None:
90 parts
.append(f
".post{parsed.post}")
93 if parsed
.dev
is not None:
94 parts
.append(f
".dev{parsed.dev}")
96 # Local version segment
97 if parsed
.local
is not None:
98 parts
.append(f
"+{parsed.local}")
100 return "".join(parts
)
103 def parse_wheel_filename(
105 ) -> Tuple
[NormalizedName
, Version
, BuildTag
, FrozenSet
[Tag
]]:
106 if not filename
.endswith(".whl"):
107 raise InvalidWheelFilename(
108 f
"Invalid wheel filename (extension must be '.whl'): {filename}"
111 filename
= filename
[:-4]
112 dashes
= filename
.count("-")
113 if dashes
not in (4, 5):
114 raise InvalidWheelFilename(
115 f
"Invalid wheel filename (wrong number of parts): {filename}"
118 parts
= filename
.split("-", dashes
- 2)
120 # See PEP 427 for the rules on escaping the project name.
121 if "__" in name_part
or re
.match(r
"^[\w\d._]*$", name_part
, re
.UNICODE
) is None:
122 raise InvalidWheelFilename(f
"Invalid project name: {filename}")
123 name
= canonicalize_name(name_part
)
126 version
= Version(parts
[1])
127 except InvalidVersion
as e
:
128 raise InvalidWheelFilename(
129 f
"Invalid wheel filename (invalid version): {filename}"
133 build_part
= parts
[2]
134 build_match
= _build_tag_regex
.match(build_part
)
135 if build_match
is None:
136 raise InvalidWheelFilename(
137 f
"Invalid build number: {build_part} in '{filename}'"
139 build
= cast(BuildTag
, (int(build_match
.group(1)), build_match
.group(2)))
142 tags
= parse_tag(parts
[-1])
143 return (name
, version
, build
, tags
)
146 def parse_sdist_filename(filename
: str) -> Tuple
[NormalizedName
, Version
]:
147 if filename
.endswith(".tar.gz"):
148 file_stem
= filename
[: -len(".tar.gz")]
149 elif filename
.endswith(".zip"):
150 file_stem
= filename
[: -len(".zip")]
152 raise InvalidSdistFilename(
153 f
"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):"
157 # We are requiring a PEP 440 version, which cannot contain dashes,
158 # so we split on the last dash.
159 name_part
, sep
, version_part
= file_stem
.rpartition("-")
161 raise InvalidSdistFilename(f
"Invalid sdist filename: {filename}")
163 name
= canonicalize_name(name_part
)
166 version
= Version(version_part
)
167 except InvalidVersion
as e
:
168 raise InvalidSdistFilename(
169 f
"Invalid sdist filename (invalid version): {filename}"
172 return (name
, version
)