pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/4c71d51a4b7989fc8754ba512c40e21666f9db0d

5097560d244c08.css" /> gh-117266: Fix crashes on user-created AST subclasses (GH-117276) · python/cpython@4c71d51 · GitHub
Skip to content

Commit 4c71d51

Browse files
gh-117266: Fix crashes on user-created AST subclasses (GH-117276)
Fix crashes on user-created AST subclasses
1 parent 8cb7d7f commit 4c71d51

File tree

4 files changed

+69
-4
lines changed

4 files changed

+69
-4
lines changed

Lib/test/test_ast.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2916,6 +2916,47 @@ def test_FunctionDef(self):
29162916
self.assertEqual(node.name, 'foo')
29172917
self.assertEqual(node.decorator_list, [])
29182918

2919+
def test_custom_subclass(self):
2920+
class NoInit(ast.AST):
2921+
pass
2922+
2923+
obj = NoInit()
2924+
self.assertIsInstance(obj, NoInit)
2925+
self.assertEqual(obj.__dict__, {})
2926+
2927+
class Fields(ast.AST):
2928+
_fields = ('a',)
2929+
2930+
with self.assertWarnsRegex(DeprecationWarning,
2931+
r"Fields provides _fields but not _field_types."):
2932+
obj = Fields()
2933+
with self.assertRaises(AttributeError):
2934+
obj.a
2935+
obj = Fields(a=1)
2936+
self.assertEqual(obj.a, 1)
2937+
2938+
class FieldsAndTypes(ast.AST):
2939+
_fields = ('a',)
2940+
_field_types = {'a': int | None}
2941+
a: int | None = None
2942+
2943+
obj = FieldsAndTypes()
2944+
self.assertIs(obj.a, None)
2945+
obj = FieldsAndTypes(a=1)
2946+
self.assertEqual(obj.a, 1)
2947+
2948+
class FieldsAndTypesNoDefault(ast.AST):
2949+
_fields = ('a',)
2950+
_field_types = {'a': int}
2951+
2952+
with self.assertWarnsRegex(DeprecationWarning,
2953+
r"FieldsAndTypesNoDefault\.__init__ missing 1 required positional argument: 'a'\."):
2954+
obj = FieldsAndTypesNoDefault()
2955+
with self.assertRaises(AttributeError):
2956+
obj.a
2957+
obj = FieldsAndTypesNoDefault(a=1)
2958+
self.assertEqual(obj.a, 1)
2959+
29192960

29202961
@support.cpython_only
29212962
class ModuleStateTests(unittest.TestCase):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crashes for certain user-created subclasses of :class:`ast.AST`. Such
2+
classes are now expected to set the ``_field_types`` attribute.

Parser/asdl_c.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -973,11 +973,22 @@ def visitModule(self, mod):
973973
Py_ssize_t size = PySet_Size(remaining_fields);
974974
PyObject *field_types = NULL, *remaining_list = NULL;
975975
if (size > 0) {
976-
if (!PyObject_GetOptionalAttr((PyObject*)Py_TYPE(self), &_Py_ID(_field_types),
977-
&field_types)) {
976+
if (PyObject_GetOptionalAttr((PyObject*)Py_TYPE(self), &_Py_ID(_field_types),
977+
&field_types) < 0) {
978978
res = -1;
979979
goto cleanup;
980980
}
981+
if (field_types == NULL) {
982+
if (PyErr_WarnFormat(
983+
PyExc_DeprecationWarning, 1,
984+
"%.400s provides _fields but not _field_types. "
985+
"This will become an error in Python 3.15.",
986+
Py_TYPE(self)->tp_name
987+
) < 0) {
988+
res = -1;
989+
}
990+
goto cleanup;
991+
}
981992
remaining_list = PySequence_List(remaining_fields);
982993
if (!remaining_list) {
983994
goto set_remaining_cleanup;

Python/Python-ast.c

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy