mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
* Refresh canonical importlib and preserve native import callback Cache the original builtin __import__ callback so CPython 3.15 importlib's hierarchical locking uses the existing native parent-initialization path. Refresh the complete canonical importlib and related test/helper families from CPython d220409a13b77de7a6c30abe16ea90db01528edc through update_lib. Preserve both nondecorator importlib guards in the updater. Add explicit hash-pinned removal of reviewed obsolete canonical files, with full preflight, dry-run, idempotence and refusal tests. Preserve empty fixtures. Assisted-by: OpenAI Codex:model version unavailable * Complete canonical inspect and types closure for importlib metadata Refresh whole canonical inspect/types production and related test families through update_lib after hosted CI exposed stale __cached__ consumers. Add coroutine and async-generator state getters, with closed-state priority for reentrant frame-local finalizers, and expose the existing frame-locals proxy type with its CPython class documentation. Preserve the optional _datetime and unittest import blocks through a narrow migration adapter. Retain canonical assertions and existing guards; record the missing LazyImportType expectation before adding a conditional expected failure, and capability-skip only the two absent-_testcapi CLI fixtures. Assisted-by: OpenAI Codex:model version unavailable * Reject canonical removal junctions and read UTF-8 manifests Reject junctions alongside symlinks in the existing path-component preflight and revalidation. Decode removal manifests explicitly as UTF-8. Add regressions for whole-batch refusal, revalidation, and Unicode dry-run/apply/idempotence. Assisted-by: OpenAI Codex:model version unavailable
119 lines
2.6 KiB
Python
Vendored
119 lines
2.6 KiB
Python
Vendored
from __future__ import annotations
|
|
|
|
import functools
|
|
import operator
|
|
|
|
|
|
# from jaraco.context 6.1
|
|
class ExceptionTrap:
|
|
"""
|
|
A context manager that will catch certain exceptions and provide an
|
|
indication they occurred.
|
|
|
|
>>> with ExceptionTrap() as trap:
|
|
... raise Exception()
|
|
>>> bool(trap)
|
|
True
|
|
|
|
>>> with ExceptionTrap() as trap:
|
|
... pass
|
|
>>> bool(trap)
|
|
False
|
|
|
|
>>> with ExceptionTrap(ValueError) as trap:
|
|
... raise ValueError("1 + 1 is not 3")
|
|
>>> bool(trap)
|
|
True
|
|
>>> trap.value
|
|
ValueError('1 + 1 is not 3')
|
|
>>> trap.tb
|
|
<traceback object at ...>
|
|
|
|
>>> with ExceptionTrap(ValueError) as trap:
|
|
... raise Exception()
|
|
Traceback (most recent call last):
|
|
...
|
|
Exception
|
|
|
|
>>> bool(trap)
|
|
False
|
|
"""
|
|
|
|
exc_info = None, None, None
|
|
|
|
def __init__(self, exceptions=(Exception,)):
|
|
self.exceptions = exceptions
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
@property
|
|
def type(self):
|
|
return self.exc_info[0]
|
|
|
|
@property
|
|
def value(self):
|
|
return self.exc_info[1]
|
|
|
|
@property
|
|
def tb(self):
|
|
return self.exc_info[2]
|
|
|
|
def __exit__(self, *exc_info):
|
|
type = exc_info[0]
|
|
matches = type and issubclass(type, self.exceptions)
|
|
if matches:
|
|
self.exc_info = exc_info
|
|
return matches
|
|
|
|
def __bool__(self):
|
|
return bool(self.type)
|
|
|
|
def raises(self, func, *, _test=bool):
|
|
"""
|
|
Wrap func and replace the result with the truth
|
|
value of the trap (True if an exception occurred).
|
|
|
|
First, give the decorator an alias to support Python 3.8
|
|
Syntax.
|
|
|
|
>>> raises = ExceptionTrap(ValueError).raises
|
|
|
|
Now decorate a function that always fails.
|
|
|
|
>>> @raises
|
|
... def fail():
|
|
... raise ValueError('failed')
|
|
>>> fail()
|
|
True
|
|
"""
|
|
|
|
@functools.wraps(func)
|
|
def wrapper(*args, **kwargs):
|
|
with ExceptionTrap(self.exceptions) as trap:
|
|
func(*args, **kwargs)
|
|
return _test(trap)
|
|
|
|
return wrapper
|
|
|
|
def passes(self, func):
|
|
"""
|
|
Wrap func and replace the result with the truth
|
|
value of the trap (True if no exception).
|
|
|
|
First, give the decorator an alias to support Python 3.8
|
|
Syntax.
|
|
|
|
>>> passes = ExceptionTrap(ValueError).passes
|
|
|
|
Now decorate a function that always fails.
|
|
|
|
>>> @passes
|
|
... def fail():
|
|
... raise ValueError('failed')
|
|
|
|
>>> fail()
|
|
False
|
|
"""
|
|
return self.raises(func, _test=operator.not_)
|