mirror of
https://github.com/python/cpython.git
synced 2025-11-25 04:34:37 +00:00
GH-92123: Store _elementtree state in type contexts (#101190)
- add state pointer to TreeBuilderObject - add state pointer to XMLParserObject
This commit is contained in:
parent
5d868efde9
commit
984387f39a
1 changed files with 21 additions and 17 deletions
|
|
@ -2306,6 +2306,7 @@ typedef struct {
|
|||
|
||||
char insert_comments;
|
||||
char insert_pis;
|
||||
elementtreestate *state;
|
||||
} TreeBuilderObject;
|
||||
|
||||
#define TreeBuilder_CheckExact(st, op) Py_IS_TYPE((op), (st)->TreeBuilder_Type)
|
||||
|
|
@ -2339,6 +2340,7 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
t->start_ns_event_obj = t->end_ns_event_obj = NULL;
|
||||
t->comment_event_obj = t->pi_event_obj = NULL;
|
||||
t->insert_comments = t->insert_pis = 0;
|
||||
t->state = ET_STATE_GLOBAL;
|
||||
}
|
||||
return (PyObject *)t;
|
||||
}
|
||||
|
|
@ -2370,7 +2372,7 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self,
|
|||
}
|
||||
|
||||
if (comment_factory == Py_None) {
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
comment_factory = st->comment_factory;
|
||||
}
|
||||
if (comment_factory) {
|
||||
|
|
@ -2382,7 +2384,7 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self,
|
|||
}
|
||||
|
||||
if (pi_factory == Py_None) {
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
pi_factory = st->pi_factory;
|
||||
}
|
||||
if (pi_factory) {
|
||||
|
|
@ -2564,7 +2566,7 @@ treebuilder_flush_data(TreeBuilderObject* self)
|
|||
if (!self->data) {
|
||||
return 0;
|
||||
}
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (!self->last_for_tail) {
|
||||
PyObject *element = self->last;
|
||||
return treebuilder_extend_element_text_or_tail(
|
||||
|
|
@ -2624,7 +2626,7 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
|
|||
{
|
||||
PyObject* node;
|
||||
PyObject* this;
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
|
||||
if (treebuilder_flush_data(self) < 0) {
|
||||
return NULL;
|
||||
|
|
@ -3013,6 +3015,7 @@ typedef struct {
|
|||
|
||||
PyObject *handle_close;
|
||||
|
||||
elementtreestate *state;
|
||||
} XMLParserObject;
|
||||
|
||||
/* helpers */
|
||||
|
|
@ -3158,7 +3161,7 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
|
|||
value = PyDict_GetItemWithError(self->entity, key);
|
||||
|
||||
if (value) {
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (TreeBuilder_CheckExact(st, self->target))
|
||||
res = treebuilder_handle_data(
|
||||
(TreeBuilderObject*) self->target, value
|
||||
|
|
@ -3231,7 +3234,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
|
|||
attrib = NULL;
|
||||
}
|
||||
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (TreeBuilder_CheckExact(st, self->target)) {
|
||||
/* shortcut */
|
||||
res = treebuilder_handle_start((TreeBuilderObject*) self->target,
|
||||
|
|
@ -3270,7 +3273,7 @@ expat_data_handler(XMLParserObject* self, const XML_Char* data_in,
|
|||
if (!data)
|
||||
return; /* parser will look for errors */
|
||||
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (TreeBuilder_CheckExact(st, self->target))
|
||||
/* shortcut */
|
||||
res = treebuilder_handle_data((TreeBuilderObject*) self->target, data);
|
||||
|
|
@ -3293,7 +3296,7 @@ expat_end_handler(XMLParserObject* self, const XML_Char* tag_in)
|
|||
if (PyErr_Occurred())
|
||||
return;
|
||||
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (TreeBuilder_CheckExact(st, self->target))
|
||||
/* shortcut */
|
||||
/* the standard tree builder doesn't look at the end tag */
|
||||
|
|
@ -3328,7 +3331,7 @@ expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix_in,
|
|||
if (!prefix_in)
|
||||
prefix_in = "";
|
||||
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (TreeBuilder_CheckExact(st, self->target)) {
|
||||
/* shortcut - TreeBuilder does not actually implement .start_ns() */
|
||||
TreeBuilderObject *target = (TreeBuilderObject*) self->target;
|
||||
|
|
@ -3379,7 +3382,7 @@ expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in)
|
|||
if (!prefix_in)
|
||||
prefix_in = "";
|
||||
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (TreeBuilder_CheckExact(st, self->target)) {
|
||||
/* shortcut - TreeBuilder does not actually implement .end_ns() */
|
||||
TreeBuilderObject *target = (TreeBuilderObject*) self->target;
|
||||
|
|
@ -3408,7 +3411,7 @@ expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in)
|
|||
if (PyErr_Occurred())
|
||||
return;
|
||||
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (TreeBuilder_CheckExact(st, self->target)) {
|
||||
/* shortcut */
|
||||
TreeBuilderObject *target = (TreeBuilderObject*) self->target;
|
||||
|
|
@ -3469,7 +3472,7 @@ expat_start_doctype_handler(XMLParserObject *self,
|
|||
pubid_obj = Py_NewRef(Py_None);
|
||||
}
|
||||
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
/* If the target has a handler for doctype, call it. */
|
||||
if (self->handle_doctype) {
|
||||
res = PyObject_CallFunctionObjArgs(self->handle_doctype,
|
||||
|
|
@ -3502,7 +3505,7 @@ expat_pi_handler(XMLParserObject* self, const XML_Char* target_in,
|
|||
if (PyErr_Occurred())
|
||||
return;
|
||||
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (TreeBuilder_CheckExact(st, self->target)) {
|
||||
/* shortcut */
|
||||
TreeBuilderObject *target = (TreeBuilderObject*) self->target;
|
||||
|
|
@ -3555,6 +3558,7 @@ xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
self->handle_start = self->handle_data = self->handle_end = NULL;
|
||||
self->handle_comment = self->handle_pi = self->handle_close = NULL;
|
||||
self->handle_doctype = NULL;
|
||||
self->state = ET_STATE_GLOBAL;
|
||||
}
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
|
@ -3611,7 +3615,7 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
|
|||
if (target != Py_None) {
|
||||
Py_INCREF(target);
|
||||
} else {
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
target = treebuilder_new(st->TreeBuilder_Type, NULL, NULL);
|
||||
if (!target) {
|
||||
Py_CLEAR(self->entity);
|
||||
|
|
@ -3813,7 +3817,7 @@ _elementtree_XMLParser_close_impl(XMLParserObject *self)
|
|||
if (!res)
|
||||
return NULL;
|
||||
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (TreeBuilder_CheckExact(st, self->target)) {
|
||||
Py_DECREF(res);
|
||||
return treebuilder_done((TreeBuilderObject*) self->target);
|
||||
|
|
@ -3953,7 +3957,7 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file)
|
|||
|
||||
res = expat_parse(self, "", 0, 1);
|
||||
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (res && TreeBuilder_CheckExact(st, self->target)) {
|
||||
Py_DECREF(res);
|
||||
return treebuilder_done((TreeBuilderObject*) self->target);
|
||||
|
|
@ -3985,7 +3989,7 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self,
|
|||
if (!_check_xmlparser(self)) {
|
||||
return NULL;
|
||||
}
|
||||
elementtreestate *st = ET_STATE_GLOBAL;
|
||||
elementtreestate *st = self->state;
|
||||
if (!TreeBuilder_CheckExact(st, self->target)) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue