python-discovery 1.4.3__py3-none-any.whl → 1.4.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -481,6 +481,8 @@ class PythonInfo: # noqa: PLR0904
481
481
  return False
482
482
  if spec.free_threaded is not None and spec.free_threaded != self.free_threaded:
483
483
  return False
484
+ if spec.debug is not None and spec.debug != self.debug_build:
485
+ return False
484
486
  if spec.version_specifier is not None and not self._satisfies_version_specifier(spec):
485
487
  return False
486
488
  return all(
@@ -717,7 +719,7 @@ class PythonInfo: # noqa: PLR0904
717
719
  info = self.from_exe(exe_path, cache, resolve_to_host=False, raise_on_error=False, env=env)
718
720
  if info is None: # ignore if for some reason we can't query
719
721
  return None
720
- for item in ["implementation", "architecture", "machine", "version_info"]:
722
+ for item in ["implementation", "architecture", "machine", "version_info", "free_threaded", "debug_build"]:
721
723
  found = getattr(info, item)
722
724
  searched = getattr(self, item)
723
725
  if found != searched:
@@ -772,7 +774,9 @@ class PythonInfo: # noqa: PLR0904
772
774
  def _find_possible_exe_names(self) -> list[str]:
773
775
  name_candidate = OrderedDict()
774
776
  mods = ["", "t"] if self.free_threaded else [""]
775
- debug_suffixes = ["_d", ""] if self.debug_build else [""]
777
+ # _d (Windows python_d.exe), -dbg (Debian's own name), d (the abiflags form used by
778
+ # upstream/Fedora and also shipped by Debian, so pythonX.Yd / pythonX.Ytd resolve too)
779
+ debug_suffixes = ["_d", "-dbg", "d", ""] if self.debug_build else [""]
776
780
  archs = [f"-{self.architecture}", ""]
777
781
  for name in self._possible_base():
778
782
  for at in (3, 2, 1, 0):
@@ -16,6 +16,7 @@ PATTERN = re.compile(
16
16
  (?P<impl>[a-zA-Z]+)? # implementation (e.g. cpython, pypy)
17
17
  (?P<version>[0-9.]+)? # version (e.g. 3.12, 3.12.1)
18
18
  (?P<threaded>t)? # free-threaded flag
19
+ (?P<debug>d|(?:-dbg|-debug)(?=-|$))? # debug build flag (d, -dbg or -debug)
19
20
  (?:-(?P<arch>32|64))? # architecture bitness
20
21
  (?:-(?P<machine>[a-zA-Z0-9_.]+))? # ISA (e.g. arm64, x86_64, i86pc.64bit)
21
22
  $
@@ -68,6 +69,7 @@ def _parse_spec_pattern(string_spec: str) -> PythonSpec | None:
68
69
  groups = match.groupdict()
69
70
  version = groups["version"]
70
71
  major, minor, micro, threaded = None, None, None, None
72
+ debug = True if groups["debug"] else None # unconstrained unless an explicit d/-dbg/-debug marker is present
71
73
  if version is not None:
72
74
  try:
73
75
  major, minor, micro = _parse_version_parts(version)
@@ -83,7 +85,9 @@ def _parse_spec_pattern(string_spec: str) -> PythonSpec | None:
83
85
  machine = groups.get("machine")
84
86
  if machine is not None:
85
87
  machine = normalize_isa(machine)
86
- return PythonSpec(string_spec, impl, major, minor, micro, arch, None, free_threaded=threaded, machine=machine)
88
+ return PythonSpec(
89
+ string_spec, impl, major, minor, micro, arch, None, free_threaded=threaded, machine=machine, debug=debug
90
+ )
87
91
 
88
92
 
89
93
  def _parse_specifier(string_spec: str) -> PythonSpec | None:
@@ -117,6 +121,7 @@ class PythonSpec:
117
121
  :param path: filesystem path to a specific interpreter, or ``None``.
118
122
  :param free_threaded: whether a free-threaded build is required, or ``None`` for any.
119
123
  :param machine: required ISA (e.g. ``"arm64"``), or ``None`` for any.
124
+ :param debug: whether a debug (``Py_DEBUG``) build is required, or ``None`` for any.
120
125
  :param version_specifier:
121
126
  `version specifier <https://packaging.python.org/en/latest/specifications/version-specifiers/>`_
122
127
  constraints, or ``None``.
@@ -134,6 +139,7 @@ class PythonSpec:
134
139
  *,
135
140
  free_threaded: bool | None = None,
136
141
  machine: str | None = None,
142
+ debug: bool | None = None,
137
143
  version_specifier: SpecifierSet | None = None,
138
144
  ) -> None:
139
145
  self.str_spec = str_spec
@@ -144,6 +150,7 @@ class PythonSpec:
144
150
  self.free_threaded = free_threaded
145
151
  self.architecture = architecture
146
152
  self.machine = machine
153
+ self.debug = debug
147
154
  self.path = path
148
155
  self.version_specifier = version_specifier
149
156
 
@@ -181,10 +188,11 @@ class PythonSpec:
181
188
  else:
182
189
  impl = "python"
183
190
  mod = "t?" if self.free_threaded else ""
191
+ dbg = "(?:d|-dbg|-debug)?" if self.debug else ""
184
192
  suffix = r"\.exe" if windows else ""
185
193
  version_conditional = "?" if windows or self.major is None else ""
186
194
  return re.compile(
187
- rf"(?P<impl>{impl})(?P<v>{version}{mod}){version_conditional}{suffix}$",
195
+ rf"(?P<impl>{impl})(?P<v>{version}{mod}){version_conditional}{dbg}{suffix}$",
188
196
  flags=re.IGNORECASE,
189
197
  )
190
198
 
@@ -263,6 +271,7 @@ class PythonSpec:
263
271
  "machine",
264
272
  "path",
265
273
  "free_threaded",
274
+ "debug",
266
275
  "version_specifier",
267
276
  )
268
277
  return f"{name}({', '.join(f'{k}={getattr(self, k)}' for k in params if getattr(self, k) is not None)})"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-discovery
3
- Version: 1.4.3
3
+ Version: 1.4.4
4
4
  Summary: Python interpreter discovery
5
5
  Project-URL: Changelog, https://github.com/tox-dev/python-discovery/releases
6
6
  Project-URL: Documentation, https://python-discovery.readthedocs.io
@@ -3,14 +3,14 @@ python_discovery/_cache.py,sha256=bG4fD-h2pdPmb4v9BldbXmJ5Tlt1boiH1Qrz8kp9Dds,50
3
3
  python_discovery/_cached_py_info.py,sha256=1AFEoc_-OaCi1PXmaFz9Iy_bEuqOhJdFSDFHljzD-EE,8540
4
4
  python_discovery/_compat.py,sha256=iqxGuhK9rPaiui80G1H1KrweoMJ16gyLYEmUrSXrp5c,709
5
5
  python_discovery/_discovery.py,sha256=cdo6xlktNMEwsQn2R8pn4T1VDE4LD2EJPUyCT7vlHnM,16830
6
- python_discovery/_py_info.py,sha256=7e4Ei810L2uS-JuqNdiCHvgyb-R4gj_5VrtN3yNtIAg,36647
7
- python_discovery/_py_spec.py,sha256=Kky0LXi8BU_ojfMdvvRhtDk6I4WPjovwXOu6E2QYHTo,10421
6
+ python_discovery/_py_info.py,sha256=fFhS-gZoYIJYscqM56h1RwFknJou8bgf3h8VXrqm5g8,36974
7
+ python_discovery/_py_spec.py,sha256=FN7nsWOkxdFpmd5st5hz5e2f7egbLzzbRiNiBndAYZc,10877
8
8
  python_discovery/_specifier.py,sha256=PTh6suNTC0hMnFSxFYF_vggdciFLnwxoh1YflSbgCXA,10368
9
9
  python_discovery/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  python_discovery/_windows/__init__.py,sha256=qthcyGh36b3WkeSbZ4ECRRYLbCOCaQu5X_DRZ98tXfk,315
11
11
  python_discovery/_windows/_pep514.py,sha256=zXxje07QIXfrCB3eYbZHOBgXcvAQQpZ-ZWun3_zrapA,7688
12
12
  python_discovery/_windows/_propose.py,sha256=iMJf6l0TU4SvuV8UsCHHINAe9L5dUT949xyeyMVdong,1565
13
- python_discovery-1.4.3.dist-info/METADATA,sha256=_9Cm3smElV4lgueLcYMDdHjFzo66tjO1tqH-K6KwkG0,5592
14
- python_discovery-1.4.3.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
15
- python_discovery-1.4.3.dist-info/licenses/LICENSE,sha256=kOJeH68qSq6o2V7o5_VziwUqGswMnFgGgQH5Mahr1Yg,1023
16
- python_discovery-1.4.3.dist-info/RECORD,,
13
+ python_discovery-1.4.4.dist-info/METADATA,sha256=15xJaaopcuujqLtLazKC4ZadMMCtHPWntqISeeYMFCQ,5592
14
+ python_discovery-1.4.4.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
15
+ python_discovery-1.4.4.dist-info/licenses/LICENSE,sha256=kOJeH68qSq6o2V7o5_VziwUqGswMnFgGgQH5Mahr1Yg,1023
16
+ python_discovery-1.4.4.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.30.1
2
+ Generator: hatchling 1.31.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any