Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Include/internal/pycore_ast_state.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add the _field_types attribute to the base AST class and its subclasses. The
default value is an empty dict. Patch by Hunter Hogan.
32 changes: 24 additions & 8 deletions Parser/asdl_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def emit(s, depth=depth):
# rudimentary attribute handling
type = str(field.type)
assert type in asdl.builtin_types, type
emit("%s %s;" % (type, field.name), depth + 1);
emit("%s %s;" % (type, field.name), depth + 1)
emit("};")
emit("")

Expand Down Expand Up @@ -332,7 +332,7 @@ def visitProduct(self, product, name, depth):
# rudimentary attribute handling
type = str(field.type)
assert type in asdl.builtin_types, type
self.emit("%s %s;" % (type, field.name), depth + 1);
self.emit("%s %s;" % (type, field.name), depth + 1)
self.emit("};", depth)
self.emit("", depth)

Expand Down Expand Up @@ -434,7 +434,7 @@ def emit(s, depth=0, reflow=True):
emit('return NULL;', 2)
emit('}', 1)

emit("p = (%s)_PyArena_Malloc(arena, sizeof(*p));" % ctype, 1);
emit("p = (%s)_PyArena_Malloc(arena, sizeof(*p));" % ctype, 1)
emit("if (!p)", 1)
emit("return NULL;", 2)
if union:
Expand Down Expand Up @@ -1734,6 +1734,17 @@ def visitModule(self, mod):
state->__module__,
state->ast,
state->__doc__, doc);
if (result) {
PyObject *empty_dict = PyDict_New();
if (!empty_dict ||
PyObject_SetAttr(result, state->_field_types, empty_dict) < 0) {
Py_XDECREF(empty_dict);
Py_DECREF(result);
Py_DECREF(fnames);
return NULL;
}
Py_DECREF(empty_dict);
}
Py_DECREF(fnames);
return result;
}
Expand Down Expand Up @@ -1860,16 +1871,20 @@ def visitModule(self, mod):

static int add_ast_fields(struct ast_state *state)
{
PyObject *empty_tuple;
PyObject *empty_tuple, *empty_dict;
empty_tuple = PyTuple_New(0);
if (!empty_tuple ||
empty_dict = PyDict_New();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is technically unsafe: if PyTuple_New raised an exception, we can't generally call other C API functions with an exception set. Safer to have a separate if statement for the dict.

if (!empty_tuple || !empty_dict ||
PyObject_SetAttrString(state->AST_type, "_fields", empty_tuple) < 0 ||
PyObject_SetAttrString(state->AST_type, "_field_types", empty_dict) < 0 ||
PyObject_SetAttrString(state->AST_type, "__match_args__", empty_tuple) < 0 ||
PyObject_SetAttrString(state->AST_type, "_attributes", empty_tuple) < 0) {
Py_XDECREF(empty_tuple);
Py_XDECREF(empty_dict);
return -1;
}
Py_DECREF(empty_tuple);
Py_DECREF(empty_dict);
return 0;
}

Expand Down Expand Up @@ -2089,13 +2104,13 @@ def simpleSum(self, sum, name):
self.emit("case %s:" % t.name, 2)
self.emit("return Py_NewRef(state->%s_singleton);" % t.name, 3)
self.emit("}", 1)
self.emit("Py_UNREACHABLE();", 1);
self.emit("Py_UNREACHABLE();", 1)
self.emit("}", 0)

def visitProduct(self, prod, name):
self.func_begin(name)
self.emit("tp = (PyTypeObject *)state->%s_type;" % name, 1)
self.emit("result = PyType_GenericNew(tp, NULL, NULL);", 1);
self.emit("result = PyType_GenericNew(tp, NULL, NULL);", 1)
self.emit("if (!result) return NULL;", 1)
for field in prod.fields:
self.visitField(field, name, 1, True)
Expand All @@ -2110,7 +2125,7 @@ def visitProduct(self, prod, name):
def visitConstructor(self, cons, enum, name):
self.emit("case %s_kind:" % cons.name, 1)
self.emit("tp = (PyTypeObject *)state->%s_type;" % cons.name, 2)
self.emit("result = PyType_GenericNew(tp, NULL, NULL);", 2);
self.emit("result = PyType_GenericNew(tp, NULL, NULL);", 2)
self.emit("if (!result) goto failed;", 2)
for f in cons.fields:
self.visitField(f, cons.name, 2, False)
Expand Down Expand Up @@ -2272,6 +2287,7 @@ def generate_module_def(mod, metadata, f, internal_h):
state_strings = {
"ast",
"_fields",
"_field_types",
"__match_args__",
"__doc__",
"__dict__",
Expand Down
21 changes: 19 additions & 2 deletions Python/Python-ast.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading