| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Improve the :meth:`~object.__repr__` output of :class:`~ast.AST` nodes. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -1435,8 +1435,230 @@ def visitModule(self, mod): | |
| {NULL} | ||
| }; | ||
|
|
||
| static PyObject * | ||
| ast_repr_max_depth(AST_object *self, int depth); | ||
|
|
||
| /* Format list and tuple properties of AST nodes. | ||
| Note that, only the first and last elements are shown. | ||
| Anything in between is represented with an ellipsis ('...'). | ||
| For example, the list [1, 2, 3] is formatted as | ||
| 'List(elts=[Constant(1), ..., Constant(3)])'. */ | ||
| static PyObject * | ||
| ast_repr_list(PyObject *list, int depth) | ||
| { | ||
| assert(PyList_Check(list) || PyTuple_Check(list)); | ||
|
|
||
| struct ast_state *state = get_ast_state(); | ||
| if (state == NULL) { | ||
| return NULL; | ||
| } | ||
|
|
||
| Py_ssize_t length = PySequence_Size(list); | ||
| if (length < 0) { | ||
| return NULL; | ||
| } | ||
| else if (length == 0) { | ||
| return PyObject_Repr(list); | ||
| } | ||
|
|
||
| _PyUnicodeWriter writer; | ||
|
Comment thread
picnixz marked this conversation as resolved.
|
||
| _PyUnicodeWriter_Init(&writer); | ||
| writer.overallocate = 1; | ||
| PyObject *items[2] = {NULL, NULL}; | ||
|
|
||
| items[0] = PySequence_GetItem(list, 0); | ||
|
Comment thread
tomasr8 marked this conversation as resolved.
|
||
| if (!items[0]) { | ||
| goto error; | ||
| } | ||
| if (length > 1) { | ||
| items[1] = PySequence_GetItem(list, length - 1); | ||
| if (!items[1]) { | ||
| goto error; | ||
| } | ||
| } | ||
|
|
||
| bool is_list = PyList_Check(list); | ||
| if (_PyUnicodeWriter_WriteChar(&writer, is_list ? '[' : '(') < 0) { | ||
| goto error; | ||
| } | ||
|
|
||
| for (Py_ssize_t i = 0; i < Py_MIN(length, 2); i++) { | ||
| PyObject *item = items[i]; | ||
| PyObject *item_repr; | ||
|
|
||
| if (PyType_IsSubtype(Py_TYPE(item), (PyTypeObject *)state->AST_type)) { | ||
| item_repr = ast_repr_max_depth((AST_object*)item, depth - 1); | ||
| } else { | ||
| item_repr = PyObject_Repr(item); | ||
| } | ||
| if (!item_repr) { | ||
| goto error; | ||
| } | ||
| if (i > 0) { | ||
| if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) { | ||
| goto error; | ||
| } | ||
| } | ||
| if (_PyUnicodeWriter_WriteStr(&writer, item_repr) < 0) { | ||
| Py_DECREF(item_repr); | ||
| goto error; | ||
| } | ||
| if (i == 0 && length > 2) { | ||
| if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ...", 5) < 0) { | ||
| Py_DECREF(item_repr); | ||
| goto error; | ||
| } | ||
| } | ||
| Py_DECREF(item_repr); | ||
| } | ||
|
|
||
| if (_PyUnicodeWriter_WriteChar(&writer, is_list ? ']' : ')') < 0) { | ||
| goto error; | ||
| } | ||
|
|
||
| Py_XDECREF(items[0]); | ||
| Py_XDECREF(items[1]); | ||
| return _PyUnicodeWriter_Finish(&writer); | ||
|
|
||
| error: | ||
| Py_XDECREF(items[0]); | ||
| Py_XDECREF(items[1]); | ||
| _PyUnicodeWriter_Dealloc(&writer); | ||
| return NULL; | ||
| } | ||
|
|
||
| static PyObject * | ||
| ast_repr_max_depth(AST_object *self, int depth) | ||
| { | ||
| struct ast_state *state = get_ast_state(); | ||
| if (state == NULL) { | ||
| return NULL; | ||
| } | ||
|
|
||
| if (depth <= 0) { | ||
| return PyUnicode_FromFormat("%s(...)", Py_TYPE(self)->tp_name); | ||
| } | ||
|
|
||
| int status = Py_ReprEnter((PyObject *)self); | ||
| if (status != 0) { | ||
| if (status < 0) { | ||
| return NULL; | ||
| } | ||
| return PyUnicode_FromFormat("%s(...)", Py_TYPE(self)->tp_name); | ||
| } | ||
|
|
||
| PyObject *fields; | ||
| if (PyObject_GetOptionalAttr((PyObject *)Py_TYPE(self), state->_fields, &fields) < 0) { | ||
| Py_ReprLeave((PyObject *)self); | ||
| return NULL; | ||
| } | ||
|
|
||
| Py_ssize_t numfields = PySequence_Size(fields); | ||
|
Comment thread
tomasr8 marked this conversation as resolved.
|
||
| if (numfields < 0) { | ||
| Py_ReprLeave((PyObject *)self); | ||
| Py_DECREF(fields); | ||
| return NULL; | ||
| } | ||
|
|
||
| if (numfields == 0) { | ||
| Py_ReprLeave((PyObject *)self); | ||
| Py_DECREF(fields); | ||
| return PyUnicode_FromFormat("%s()", Py_TYPE(self)->tp_name); | ||
| } | ||
|
|
||
| const char* tp_name = Py_TYPE(self)->tp_name; | ||
| _PyUnicodeWriter writer; | ||
|
Comment thread
tomasr8 marked this conversation as resolved.
|
||
| _PyUnicodeWriter_Init(&writer); | ||
| writer.overallocate = 1; | ||
|
|
||
| if (_PyUnicodeWriter_WriteASCIIString(&writer, tp_name, strlen(tp_name)) < 0) { | ||
| goto error; | ||
| } | ||
| if (_PyUnicodeWriter_WriteChar(&writer, '(') < 0) { | ||
| goto error; | ||
| } | ||
|
|
||
| for (Py_ssize_t i = 0; i < numfields; i++) { | ||
| PyObject *name = PySequence_GetItem(fields, i); | ||
| if (!name) { | ||
| goto error; | ||
| } | ||
|
|
||
| PyObject *value = PyObject_GetAttr((PyObject *)self, name); | ||
| if (!value) { | ||
| Py_DECREF(name); | ||
| goto error; | ||
| } | ||
|
|
||
| PyObject *value_repr; | ||
| if (PyList_Check(value) || PyTuple_Check(value)) { | ||
| value_repr = ast_repr_list(value, depth); | ||
| } | ||
| else if (PyType_IsSubtype(Py_TYPE(value), (PyTypeObject *)state->AST_type)) { | ||
| value_repr = ast_repr_max_depth((AST_object*)value, depth - 1); | ||
| } | ||
| else { | ||
| value_repr = PyObject_Repr(value); | ||
| } | ||
|
|
||
| Py_DECREF(value); | ||
|
|
||
| if (!value_repr) { | ||
| Py_DECREF(name); | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityYou can DECREF name and value earlier so you don't have to repeat this. Looks like value is no longer needed after line 1602, so you could DECREF it there. name could be DECREFed after line 1623.
Sorry, something went wrong.
tomasr8 reacted with thumbs up emoji
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIndeed, I move those DECREFs up
Sorry, something went wrong.
All reactions
|
||
| Py_DECREF(value); | ||
| goto error; | ||
| } | ||
|
|
||
| if (i > 0) { | ||
| if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) { | ||
| Py_DECREF(name); | ||
| Py_DECREF(value_repr); | ||
| goto error; | ||
| } | ||
| } | ||
| if (_PyUnicodeWriter_WriteStr(&writer, name) < 0) { | ||
| Py_DECREF(name); | ||
| Py_DECREF(value_repr); | ||
| goto error; | ||
| } | ||
|
|
||
| Py_DECREF(name); | ||
|
|
||
| if (_PyUnicodeWriter_WriteChar(&writer, '=') < 0) { | ||
| Py_DECREF(value_repr); | ||
| goto error; | ||
| } | ||
| if (_PyUnicodeWriter_WriteStr(&writer, value_repr) < 0) { | ||
| Py_DECREF(value_repr); | ||
| goto error; | ||
| } | ||
|
|
||
| Py_DECREF(value_repr); | ||
| } | ||
|
|
||
| if (_PyUnicodeWriter_WriteChar(&writer, ')') < 0) { | ||
| goto error; | ||
| } | ||
| Py_ReprLeave((PyObject *)self); | ||
| Py_DECREF(fields); | ||
| return _PyUnicodeWriter_Finish(&writer); | ||
|
|
||
| error: | ||
| Py_ReprLeave((PyObject *)self); | ||
| Py_DECREF(fields); | ||
| _PyUnicodeWriter_Dealloc(&writer); | ||
| return NULL; | ||
| } | ||
|
|
||
| static PyObject * | ||
| ast_repr(AST_object *self) | ||
| { | ||
| return ast_repr_max_depth(self, 3); | ||
| } | ||
|
|
||
| static PyType_Slot AST_type_slots[] = { | ||
| {Py_tp_dealloc, ast_dealloc}, | ||
| {Py_tp_repr, ast_repr}, | ||
| {Py_tp_getattro, PyObject_GenericGetAttr}, | ||
| {Py_tp_setattro, PyObject_GenericSetAttr}, | ||
| {Py_tp_traverse, ast_traverse}, | ||
| Expand Down | ||
| Back | FazBrowse Home | New Git URL |
Uh oh!
There was an error while loading. Please reload this page.