Args: cpu: A WindowsCpu instance. If None, we use whatever we are running on. version: Two-digit Python version as a string such as `3.8`. If None we use current Python's version. verbose:
( self, cpu=None, version=None, verbose=True)
| 306 | ''' |
| 307 | |
| 308 | def __init__( self, cpu=None, version=None, verbose=True): |
| 309 | ''' |
| 310 | Args: |
| 311 | |
| 312 | cpu: |
| 313 | A WindowsCpu instance. If None, we use whatever we are running |
| 314 | on. |
| 315 | version: |
| 316 | Two-digit Python version as a string such as `3.8`. If None we |
| 317 | use current Python's version. |
| 318 | verbose: |
| 319 | If true we show diagnostics. |
| 320 | ''' |
| 321 | if cpu is None: |
| 322 | cpu = WindowsCpu(_cpu_name()) |
| 323 | if version is None: |
| 324 | version = '.'.join(platform.python_version().split('.')[:2]) |
| 325 | _log(f'Looking for Python {version=} {cpu.bits=}.') |
| 326 | |
| 327 | if '.'.join(platform.python_version().split('.')[:2]) == version: |
| 328 | # Current python matches, so use it directly. This avoids problems |
| 329 | # on Github where experimental python-3.13 was not available via |
| 330 | # `py`, and is kept here in case a similar problems happens with |
| 331 | # future Python versions. |
| 332 | _log(f'{cpu=} {version=}: using {sys.executable=}.') |
| 333 | self.path = sys.executable |
| 334 | self.version = version |
| 335 | self.cpu = cpu |
| 336 | self.include = sysconfig.get_path('include') |
| 337 | |
| 338 | else: |
| 339 | command = 'py -0p' |
| 340 | if verbose: |
| 341 | _log(f'{cpu=} {version=}: Running: {command}') |
| 342 | text = subprocess.check_output( command, shell=True, text=True) |
| 343 | for line in text.split('\n'): |
| 344 | #_log( f' {line}') |
| 345 | if m := re.match( '^ *-V:([0-9.]+)(-32)? ([*])? +(.+)$', line): |
| 346 | version2 = m.group(1) |
| 347 | bits = 32 if m.group(2) else 64 |
| 348 | current = m.group(3) |
| 349 | path = m.group(4).strip() |
| 350 | elif m := re.match( '^ *-([0-9.]+)-((32)|(64)) +(.+)$', line): |
| 351 | version2 = m.group(1) |
| 352 | bits = int(m.group(2)) |
| 353 | path = m.group(5).strip() |
| 354 | else: |
| 355 | if verbose: |
| 356 | _log( f'No match for {line=}') |
| 357 | continue |
| 358 | if verbose: |
| 359 | _log( f'{version2=} {bits=} {path=} from {line=}.') |
| 360 | if bits != cpu.bits or version2 != version: |
| 361 | continue |
| 362 | root = os.path.dirname(path) |
| 363 | if not os.path.exists(path): |
| 364 | # Sometimes it seems that the specified .../python.exe does not exist, |
| 365 | # and we have to change it to .../python<version>.exe. |
nothing calls this directly
no test coverage detected