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

Commit2f9cb7e

Browse files
authored
gh-81137: deprecate assignment of code object to a function of a mismatched type (#111823)
1 parent178861b commit2f9cb7e

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

‎Doc/whatsnew/3.13.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,12 @@ Deprecated
401401
(as has always been the case for an executing frame).
402402
(Contributed by Irit Katriel in:gh:`79932`.)
403403

404+
* Assignment to a function's ``__code__`` attribute where the new code
405+
object's type does not match the function's type, is deprecated. The
406+
different types are: plain function, generator, async generator and
407+
coroutine.
408+
(Contributed by Irit Katriel in:gh:`81137`.)
409+
404410

405411
Pending Removal in Python 3.14
406412
------------------------------

‎Lib/test/test_funcattrs.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
importtypes
33
importtyping
44
importunittest
5+
importwarnings
56

67

78
defglobal_function():
@@ -70,6 +71,27 @@ def test(): pass
7071
test.__code__=self.b.__code__
7172
self.assertEqual(test(),3)# self.b always returns 3, arbitrarily
7273

74+
deftest_invalid___code___assignment(self):
75+
defA():pass
76+
defB():yield
77+
asyncdefC():yield
78+
asyncdefD(x):awaitx
79+
80+
forsrcin [A,B,C,D]:
81+
fordstin [A,B,C,D]:
82+
ifsrc==dst:
83+
continue
84+
85+
assertsrc.__code__.co_flags!=dst.__code__.co_flags
86+
prev=dst.__code__
87+
try:
88+
withself.assertWarnsRegex(DeprecationWarning,'code object of non-matching type'):
89+
dst.__code__=src.__code__
90+
finally:
91+
withwarnings.catch_warnings():
92+
warnings.filterwarnings('ignore','',DeprecationWarning)
93+
dst.__code__=prev
94+
7395
deftest___globals__(self):
7496
self.assertIs(self.b.__globals__,globals())
7597
self.cannot_set_attr(self.b,'__globals__',2,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Deprecate assignment to a function's ``__code__`` field when the new code
2+
object is of a mismatched type (e.g., from a generator to a plain function).

‎Objects/funcobject.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,20 @@ func_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
557557
nclosure,nfree);
558558
return-1;
559559
}
560+
561+
PyObject*func_code=PyFunction_GET_CODE(op);
562+
intold_flags= ((PyCodeObject*)func_code)->co_flags;
563+
intnew_flags= ((PyCodeObject*)value)->co_flags;
564+
intmask=CO_GENERATOR |CO_COROUTINE |CO_ASYNC_GENERATOR;
565+
if ((old_flags&mask)!= (new_flags&mask)) {
566+
if (PyErr_Warn(PyExc_DeprecationWarning,
567+
"Assigning a code object of non-matching type is deprecated "
568+
"(e.g., from a generator to a plain function)")<0)
569+
{
570+
return-1;
571+
}
572+
}
573+
560574
handle_func_event(PyFunction_EVENT_MODIFY_CODE,op,value);
561575
_PyFunction_SetVersion(op,0);
562576
Py_XSETREF(op->func_code,Py_NewRef(value));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp