77function with a ``-`` to obtain the format name and vice versa.
88"""
99
10- import builtins
10+ from __future__ import annotations
11+
12+ import keyword
1113import logging
1214import os
1315import re
1618from itertools import chain as _chain
1719
1820if typing .TYPE_CHECKING :
21+ import builtins
22+
1923 from typing_extensions import Literal
2024
2125_logger = logging .getLogger (__name__ )
5458 (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
5559"""
5660
57- VERSION_REGEX = re .compile (r"^\s*" + VERSION_PATTERN + r"\s*$" , re .X | re .I )
61+ VERSION_REGEX = re .compile (
62+ r"^\s*" + VERSION_PATTERN + r"\s*$" , re .VERBOSE | re .IGNORECASE
63+ )
5864
5965
6066def pep440 (version : str ) -> bool :
@@ -68,7 +74,7 @@ def pep440(version: str) -> bool:
6874# PEP 508
6975
7076PEP508_IDENTIFIER_PATTERN = r"([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])"
71- PEP508_IDENTIFIER_REGEX = re .compile (f"^{ PEP508_IDENTIFIER_PATTERN } $" , re .I )
77+ PEP508_IDENTIFIER_REGEX = re .compile (f"^{ PEP508_IDENTIFIER_PATTERN } $" , re .IGNORECASE )
7278
7379
7480def pep508_identifier (name : str ) -> bool :
@@ -93,9 +99,9 @@ def pep508(value: str) -> bool:
9399 """
94100 try :
95101 _req .Requirement (value )
96- return True
97102 except _req .InvalidRequirement :
98103 return False
104+ return True
99105
100106except ImportError : # pragma: no cover
101107 _logger .warning (
@@ -104,7 +110,7 @@ def pep508(value: str) -> bool:
104110 "To enforce validation, please install `packaging`."
105111 )
106112
107- def pep508 (value : str ) -> bool :
113+ def pep508 (value : str ) -> bool : # noqa: ARG001
108114 return True
109115
110116
@@ -163,7 +169,7 @@ class _TroveClassifier:
163169 option (classifiers will be validated anyway during the upload to PyPI).
164170 """
165171
166- downloaded : typing . Union [ None , " Literal[False]" , typing . Set [str ] ]
172+ downloaded : None | Literal [False ] | set [str ]
167173 """
168174 None => not cached yet
169175 False => unavailable
@@ -200,7 +206,7 @@ def __call__(self, value: str) -> bool:
200206 _logger .debug (msg )
201207 try :
202208 self .downloaded = set (_download_classifiers ().splitlines ())
203- except Exception :
209+ except Exception : # noqa: BLE001
204210 self .downloaded = False
205211 _logger .debug ("Problem with download, skipping validation" )
206212 return True
@@ -253,21 +259,23 @@ def url(value: str) -> bool:
253259 "`scheme` prefix in your URL (e.g. 'http://'). "
254260 f"Given value: { value } "
255261 )
256- if not (value .startswith ("/" ) or value . startswith ( "\\ " ) or "@" in value ):
262+ if not (value .startswith (( "/" , "\\ " ) ) or "@" in value ):
257263 parts = urlparse (f"http://{ value } " )
258264
259265 return bool (parts .scheme and parts .netloc )
260- except Exception :
266+ except Exception : # noqa: BLE001
261267 return False
262268
263269
264270# https://packaging.python.org/specifications/entry-points/
265271ENTRYPOINT_PATTERN = r"[^\[\s=]([^=]*[^\s=])?"
266- ENTRYPOINT_REGEX = re .compile (f"^{ ENTRYPOINT_PATTERN } $" , re .I )
272+ ENTRYPOINT_REGEX = re .compile (f"^{ ENTRYPOINT_PATTERN } $" , re .IGNORECASE )
267273RECOMMEDED_ENTRYPOINT_PATTERN = r"[\w.-]+"
268- RECOMMEDED_ENTRYPOINT_REGEX = re .compile (f"^{ RECOMMEDED_ENTRYPOINT_PATTERN } $" , re .I )
274+ RECOMMEDED_ENTRYPOINT_REGEX = re .compile (
275+ f"^{ RECOMMEDED_ENTRYPOINT_PATTERN } $" , re .IGNORECASE
276+ )
269277ENTRYPOINT_GROUP_PATTERN = r"\w+(\.\w+)*"
270- ENTRYPOINT_GROUP_REGEX = re .compile (f"^{ ENTRYPOINT_GROUP_PATTERN } $" , re .I )
278+ ENTRYPOINT_GROUP_REGEX = re .compile (f"^{ ENTRYPOINT_GROUP_PATTERN } $" , re .IGNORECASE )
271279
272280
273281def python_identifier (value : str ) -> bool :
@@ -368,11 +376,41 @@ def uint16(value: builtins.int) -> bool:
368376 return 0 <= value < 2 ** 16
369377
370378
371- def uint (value : builtins .int ) -> bool :
379+ def uint32 (value : builtins .int ) -> bool :
380+ r"""Unsigned 32-bit integer (:math:`0 \leq x < 2^{32}`)"""
381+ return 0 <= value < 2 ** 32
382+
383+
384+ def uint64 (value : builtins .int ) -> bool :
372385 r"""Unsigned 64-bit integer (:math:`0 \leq x < 2^{64}`)"""
373386 return 0 <= value < 2 ** 64
374387
375388
389+ def uint (value : builtins .int ) -> bool :
390+ r"""Signed 64-bit integer (:math:`0 \leq x < 2^{64}`)"""
391+ return 0 <= value < 2 ** 64
392+
393+
394+ def int8 (value : builtins .int ) -> bool :
395+ r"""Signed 8-bit integer (:math:`-2^{7} \leq x < 2^{7}`)"""
396+ return - (2 ** 7 ) <= value < 2 ** 7
397+
398+
399+ def int16 (value : builtins .int ) -> bool :
400+ r"""Signed 16-bit integer (:math:`-2^{15} \leq x < 2^{15}`)"""
401+ return - (2 ** 15 ) <= value < 2 ** 15
402+
403+
404+ def int32 (value : builtins .int ) -> bool :
405+ r"""Signed 32-bit integer (:math:`-2^{31} \leq x < 2^{31}`)"""
406+ return - (2 ** 31 ) <= value < 2 ** 31
407+
408+
409+ def int64 (value : builtins .int ) -> bool :
410+ r"""Signed 64-bit integer (:math:`-2^{63} \leq x < 2^{63}`)"""
411+ return - (2 ** 63 ) <= value < 2 ** 63
412+
413+
376414def int (value : builtins .int ) -> bool :
377415 r"""Signed 64-bit integer (:math:`-2^{63} \leq x < 2^{63}`)"""
378416 return - (2 ** 63 ) <= value < 2 ** 63
@@ -387,9 +425,9 @@ def SPDX(value: str) -> bool:
387425 """
388426 try :
389427 _licenses .canonicalize_license_expression (value )
390- return True
391428 except _licenses .InvalidLicenseExpression :
392429 return False
430+ return True
393431
394432except ImportError : # pragma: no cover
395433 _logger .warning (
@@ -398,5 +436,29 @@ def SPDX(value: str) -> bool:
398436 "To enforce validation, please install `packaging>=24.2`."
399437 )
400438
401- def SPDX (value : str ) -> bool :
439+ def SPDX (value : str ) -> bool : # noqa: ARG001
402440 return True
441+
442+
443+ VALID_IMPORT_NAME = re .compile (
444+ r"""
445+ ^ # start of string
446+ [A-Za-z_][A-Za-z_0-9]+ # a valid Python identifier
447+ (?:\.[A-Za-z_][A-Za-z_0-9]*)* # optionally followed by .identifier's
448+ (?:\s*;\s*private)? # optionally followed by ; private
449+ $ # end of string
450+ """ ,
451+ re .VERBOSE ,
452+ )
453+
454+
455+ def import_name (value : str ) -> bool :
456+ """This is a valid import name. It has to be series of python identifiers
457+ (not keywords), separated by dots, optionally followed by a semicolon and
458+ the keyword "private".
459+ """
460+ if VALID_IMPORT_NAME .match (value ) is None :
461+ return False
462+
463+ idents , _ , _ = value .partition (";" )
464+ return all (not keyword .iskeyword (ident ) for ident in idents .rstrip ().split ("." ))
0 commit comments