Given the path to a .pyc. file, return the path to its .py file. The .pyc file does not need to exist; this simply returns the path to the .py file calculated to correspond to the .pyc file. If path does not conform to PEP 3147/488 format, ValueError will be raised. If sys.implemen
(path)
| 308 | |
| 309 | |
| 310 | def source_from_cache(path): |
| 311 | """Given the path to a .pyc. file, return the path to its .py file. |
| 312 | |
| 313 | The .pyc file does not need to exist; this simply returns the path to |
| 314 | the .py file calculated to correspond to the .pyc file. If path does |
| 315 | not conform to PEP 3147/488 format, ValueError will be raised. If |
| 316 | sys.implementation.cache_tag is None then NotImplementedError is raised. |
| 317 | |
| 318 | """ |
| 319 | if sys.implementation.cache_tag is None: |
| 320 | raise NotImplementedError('sys.implementation.cache_tag is None') |
| 321 | path = _os.fspath(path) |
| 322 | head, pycache_filename = _path_split(path) |
| 323 | found_in_pycache_prefix = False |
| 324 | if sys.pycache_prefix is not None: |
| 325 | stripped_path = sys.pycache_prefix.rstrip(path_separators) |
| 326 | if head.startswith(stripped_path + path_sep): |
| 327 | head = head[len(stripped_path):] |
| 328 | found_in_pycache_prefix = True |
| 329 | if not found_in_pycache_prefix: |
| 330 | head, pycache = _path_split(head) |
| 331 | if pycache != _PYCACHE: |
| 332 | raise ValueError(f'{_PYCACHE} not bottom-level directory in ' |
| 333 | f'{path!r}') |
| 334 | dot_count = pycache_filename.count('.') |
| 335 | if dot_count not in {2, 3}: |
| 336 | raise ValueError(f'expected only 2 or 3 dots in {pycache_filename!r}') |
| 337 | elif dot_count == 3: |
| 338 | optimization = pycache_filename.rsplit('.', 2)[-2] |
| 339 | if not optimization.startswith(_OPT): |
| 340 | raise ValueError("optimization portion of filename does not start " |
| 341 | f"with {_OPT!r}") |
| 342 | opt_level = optimization[len(_OPT):] |
| 343 | if not opt_level.isalnum(): |
| 344 | raise ValueError(f"optimization level {optimization!r} is not an " |
| 345 | "alphanumeric value") |
| 346 | base_filename = pycache_filename.partition('.')[0] |
| 347 | return _path_join(head, base_filename + SOURCE_SUFFIXES[0]) |
| 348 | |
| 349 | |
| 350 | def _get_sourcefile(bytecode_path): |
no test coverage detected