Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit582be48

Browse files
committed
Implement sys._set_exception() instead of using ctypes
1 parentc80e42b commit582be48

File tree

4 files changed

+154
-10
lines changed

4 files changed

+154
-10
lines changed

‎Lib/contextlib.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@
1515
"chdir"]
1616

1717

18-
_PyErr_SetHandledException=ctypes.pythonapi.PyErr_SetHandledException
19-
_PyErr_SetHandledException.argtypes= [ctypes.py_object]
20-
def_set_current_exception(exc):
21-
ifexcisnotNoneandnotisinstance(exc,BaseException):
22-
raiseTypeError(f"{exc!r} is not an exception")
23-
_PyErr_SetHandledException(exc)
24-
25-
2618
classAbstractContextManager(abc.ABC):
2719

2820
"""An abstract base class for context managers."""
@@ -178,7 +170,7 @@ def __exit__(self, typ, value, traceback):
178170
# context here. In order to make the context manager behave
179171
# like a normal function we set the current exception context
180172
# to what it was during the context manager's __enter__
181-
_set_current_exception(exc_context)
173+
sys._set_exception(exc_context)
182174
self.gen.throw(value)
183175
exceptStopIterationasexc:
184176
# Suppress StopIteration *unless* it's the same exception that

‎Lib/test/test_sys.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,71 @@ def f():
142142
self.assertIsInstance(e,ValueError)
143143
self.assertIs(exc,e)
144144

145+
classSetExceptionTests(unittest.TestCase):
146+
147+
deftearDown(self):
148+
# make sure we don't leave the global exception set
149+
sys._set_exception(None);
150+
151+
deftest_set_exc_invalid_values(self):
152+
forxin (0,"1",b"2"):
153+
withself.assertRaises(TypeError):
154+
sys._set_exception(x);
155+
156+
deftest_clear_exc(self):
157+
try:
158+
raiseValueError()
159+
exceptValueError:
160+
self.assertIsInstance(sys.exception(),ValueError)
161+
sys._set_exception(None)
162+
self.assertIsNone(sys.exception())
163+
164+
deftest_set_exc(self):
165+
exc=ValueError()
166+
self.assertIsNone(sys.exception())
167+
sys._set_exception(exc)
168+
self.assertIs(sys.exception(),exc)
169+
170+
deftest_set_exc_replaced_by_new_exception_and_restored(self):
171+
exc=ValueError()
172+
sys._set_exception(exc)
173+
self.assertIs(sys.exception(),exc)
174+
try:
175+
raiseTypeError()
176+
exceptTypeError:
177+
self.assertIsInstance(sys.exception(),TypeError)
178+
self.assertIs(sys.exception().__context__,exc)
179+
180+
self.assertIs(sys.exception(),exc)
181+
182+
deftest_set_exc_popped_on_exit_except(self):
183+
exc=ValueError()
184+
try:
185+
raiseTypeError()
186+
exceptTypeError:
187+
self.assertIsInstance(sys.exception(),TypeError)
188+
sys._set_exception(exc)
189+
self.assertIs(sys.exception(),exc)
190+
self.assertIsNone(sys.exception())
191+
192+
deftest_cleared_exc_overridden_and_restored(self):
193+
try:
194+
raiseValueError()
195+
exceptValueError:
196+
try:
197+
raiseTypeError()
198+
exceptTypeError:
199+
self.assertIsInstance(sys.exception(),TypeError)
200+
sys._set_exception(None)
201+
self.assertIsNone(sys.exception())
202+
try:
203+
raiseIndexError()
204+
exceptIndexError:
205+
self.assertIsInstance(sys.exception(),IndexError)
206+
self.assertIsNone(sys.exception().__context__)
207+
self.assertIsNone(sys.exception())
208+
self.assertIsInstance(sys.exception(),ValueError)
209+
self.assertIsNone(sys.exception())
145210

146211
classExceptHookTest(unittest.TestCase):
147212

‎Python/clinic/sysmodule.c.h

Lines changed: 61 additions & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎Python/sysmodule.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,32 @@ sys_exception_impl(PyObject *module)
824824
Py_RETURN_NONE;
825825
}
826826

827+
/*[clinic input]
828+
sys._set_exception
829+
exception: object
830+
831+
Set the current exception.
832+
833+
Subsequent calls to sys.exception()/sys.exc_info() will return
834+
the provided exception until another exception is raised in the
835+
current thread or the execution stack returns to a frame where
836+
another exception is being handled.
837+
[clinic start generated code]*/
838+
839+
staticPyObject*
840+
sys__set_exception_impl(PyObject*module,PyObject*exception)
841+
/*[clinic end generated code: output=39e119ee6b747085 input=46da3b45313a1cfa]*/
842+
{
843+
if (!Py_IsNone(exception)&& !PyExceptionInstance_Check(exception)){
844+
PyErr_String(
845+
PyExc_TypeError,
846+
"must be an exception/None"
847+
);
848+
returnNULL;
849+
}
850+
PyErr_SetHandledException(exception);
851+
Py_RETURN_NONE;
852+
}
827853

828854
/*[clinic input]
829855
sys.exc_info
@@ -2400,6 +2426,7 @@ static PyMethodDef sys_methods[] = {
24002426
SYS__CURRENT_EXCEPTIONS_METHODDEF
24012427
SYS_DISPLAYHOOK_METHODDEF
24022428
SYS_EXCEPTION_METHODDEF
2429+
SYS__SET_EXCEPTION_METHODDEF
24032430
SYS_EXC_INFO_METHODDEF
24042431
SYS_EXCEPTHOOK_METHODDEF
24052432
SYS_EXIT_METHODDEF

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp