Skip to content

Commit ae62747

Browse files
isolate _elementtree
1 parent 5e9f471 commit ae62747

File tree

1 file changed

+42
-43
lines changed

1 file changed

+42
-43
lines changed

Modules/_elementtree.c

+42-43
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
#include "Python.h"
1717
#include "structmember.h" // PyMemberDef
18+
#include "expat.h"
19+
#include "pyexpat.h"
1820

1921
/* -------------------------------------------------------------------- */
2022
/* configuration */
@@ -90,6 +92,8 @@ typedef struct {
9092
PyTypeObject *ElementIter_Type;
9193
PyTypeObject *TreeBuilder_Type;
9294
PyTypeObject *XMLParser_Type;
95+
96+
struct PyExpat_CAPI *expat_capi;
9397
} elementtreestate;
9498

9599
static struct PyModuleDef elementtreemodule;
@@ -146,6 +150,8 @@ elementtree_clear(PyObject *m)
146150
Py_CLEAR(st->ElementIter_Type);
147151
Py_CLEAR(st->TreeBuilder_Type);
148152
Py_CLEAR(st->XMLParser_Type);
153+
154+
st->expat_capi = NULL;
149155
return 0;
150156
}
151157

@@ -3031,14 +3037,7 @@ _elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag,
30313037
/* ==================================================================== */
30323038
/* the expat interface */
30333039

3034-
#include "expat.h"
3035-
#include "pyexpat.h"
3036-
3037-
/* The PyExpat_CAPI structure is an immutable dispatch table, so it can be
3038-
* cached globally without being in per-module state.
3039-
*/
3040-
static struct PyExpat_CAPI *expat_capi;
3041-
#define EXPAT(func) (expat_capi->func)
3040+
#define EXPAT(st, func) ((st)->expat_capi->func)
30423041

30433042
static XML_Memory_Handling_Suite ExpatMemoryHandler = {
30443043
PyObject_Malloc, PyObject_Realloc, PyObject_Free};
@@ -3147,7 +3146,7 @@ expat_set_error(elementtreestate *st, enum XML_Error error_code,
31473146
PyObject *errmsg, *error, *position, *code;
31483147

31493148
errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd",
3150-
message ? message : EXPAT(ErrorString)(error_code),
3149+
message ? message : EXPAT(st, ErrorString)(error_code),
31513150
line, column);
31523151
if (errmsg == NULL)
31533152
return;
@@ -3227,8 +3226,8 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
32273226
expat_set_error(
32283227
st,
32293228
XML_ERROR_UNDEFINED_ENTITY,
3230-
EXPAT(GetErrorLineNumber)(self->parser),
3231-
EXPAT(GetErrorColumnNumber)(self->parser),
3229+
EXPAT(st, GetErrorLineNumber)(self->parser),
3230+
EXPAT(st, GetErrorColumnNumber)(self->parser),
32323231
message
32333232
);
32343233
}
@@ -3648,24 +3647,23 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
36483647
Py_CLEAR(self->entity);
36493648
return -1;
36503649
}
3651-
3652-
self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
3650+
elementtreestate *st = self->state;
3651+
self->parser = EXPAT(st, ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
36533652
if (!self->parser) {
36543653
Py_CLEAR(self->entity);
36553654
Py_CLEAR(self->names);
36563655
PyErr_NoMemory();
36573656
return -1;
36583657
}
36593658
/* expat < 2.1.0 has no XML_SetHashSalt() */
3660-
if (EXPAT(SetHashSalt) != NULL) {
3661-
EXPAT(SetHashSalt)(self->parser,
3659+
if (EXPAT(st, SetHashSalt) != NULL) {
3660+
EXPAT(st, SetHashSalt)(self->parser,
36623661
(unsigned long)_Py_HashSecret.expat.hashsalt);
36633662
}
36643663

36653664
if (target != Py_None) {
36663665
Py_INCREF(target);
36673666
} else {
3668-
elementtreestate *st = self->state;
36693667
target = treebuilder_new(st->TreeBuilder_Type, NULL, NULL);
36703668
if (!target) {
36713669
Py_CLEAR(self->entity);
@@ -3713,43 +3711,43 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
37133711
}
37143712

37153713
/* configure parser */
3716-
EXPAT(SetUserData)(self->parser, self);
3714+
EXPAT(st, SetUserData)(self->parser, self);
37173715
if (self->handle_start_ns || self->handle_end_ns)
3718-
EXPAT(SetNamespaceDeclHandler)(
3716+
EXPAT(st, SetNamespaceDeclHandler)(
37193717
self->parser,
37203718
(XML_StartNamespaceDeclHandler) expat_start_ns_handler,
37213719
(XML_EndNamespaceDeclHandler) expat_end_ns_handler
37223720
);
3723-
EXPAT(SetElementHandler)(
3721+
EXPAT(st, SetElementHandler)(
37243722
self->parser,
37253723
(XML_StartElementHandler) expat_start_handler,
37263724
(XML_EndElementHandler) expat_end_handler
37273725
);
3728-
EXPAT(SetDefaultHandlerExpand)(
3726+
EXPAT(st, SetDefaultHandlerExpand)(
37293727
self->parser,
37303728
(XML_DefaultHandler) expat_default_handler
37313729
);
3732-
EXPAT(SetCharacterDataHandler)(
3730+
EXPAT(st, SetCharacterDataHandler)(
37333731
self->parser,
37343732
(XML_CharacterDataHandler) expat_data_handler
37353733
);
37363734
if (self->handle_comment)
3737-
EXPAT(SetCommentHandler)(
3735+
EXPAT(st, SetCommentHandler)(
37383736
self->parser,
37393737
(XML_CommentHandler) expat_comment_handler
37403738
);
37413739
if (self->handle_pi)
3742-
EXPAT(SetProcessingInstructionHandler)(
3740+
EXPAT(st, SetProcessingInstructionHandler)(
37433741
self->parser,
37443742
(XML_ProcessingInstructionHandler) expat_pi_handler
37453743
);
3746-
EXPAT(SetStartDoctypeDeclHandler)(
3744+
EXPAT(st, SetStartDoctypeDeclHandler)(
37473745
self->parser,
37483746
(XML_StartDoctypeDeclHandler) expat_start_doctype_handler
37493747
);
3750-
EXPAT(SetUnknownEncodingHandler)(
3748+
EXPAT(st, SetUnknownEncodingHandler)(
37513749
self->parser,
3752-
EXPAT(DefaultUnknownEncodingHandler), NULL
3750+
EXPAT(st, DefaultUnknownEncodingHandler), NULL
37533751
);
37543752

37553753
return 0;
@@ -3779,10 +3777,11 @@ xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg)
37793777
static int
37803778
xmlparser_gc_clear(XMLParserObject *self)
37813779
{
3780+
elementtreestate *st = self->state;
37823781
if (self->parser != NULL) {
37833782
XML_Parser parser = self->parser;
37843783
self->parser = NULL;
3785-
EXPAT(ParserFree)(parser);
3784+
EXPAT(st, ParserFree)(parser);
37863785
}
37873786

37883787
Py_CLEAR(self->handle_close);
@@ -3830,17 +3829,17 @@ expat_parse(elementtreestate *st, XMLParserObject *self, const char *data,
38303829
int ok;
38313830

38323831
assert(!PyErr_Occurred());
3833-
ok = EXPAT(Parse)(self->parser, data, data_len, final);
3832+
ok = EXPAT(st, Parse)(self->parser, data, data_len, final);
38343833

38353834
if (PyErr_Occurred())
38363835
return NULL;
38373836

38383837
if (!ok) {
38393838
expat_set_error(
38403839
st,
3841-
EXPAT(GetErrorCode)(self->parser),
3842-
EXPAT(GetErrorLineNumber)(self->parser),
3843-
EXPAT(GetErrorColumnNumber)(self->parser),
3840+
EXPAT(st, GetErrorCode)(self->parser),
3841+
EXPAT(st, GetErrorLineNumber)(self->parser),
3842+
EXPAT(st, GetErrorColumnNumber)(self->parser),
38443843
NULL
38453844
);
38463845
return NULL;
@@ -3911,7 +3910,7 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data)
39113910
return NULL;
39123911
}
39133912
/* Explicitly set UTF-8 encoding. Return code ignored. */
3914-
(void)EXPAT(SetEncoding)(self->parser, "utf-8");
3913+
(void)EXPAT(st, SetEncoding)(self->parser, "utf-8");
39153914

39163915
return expat_parse(st, self, data_ptr, (int)data_len, 0);
39173916
}
@@ -4099,27 +4098,27 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self,
40994098
Py_XSETREF(target->end_event_obj, Py_NewRef(event_name_obj));
41004099
} else if (strcmp(event_name, "start-ns") == 0) {
41014100
Py_XSETREF(target->start_ns_event_obj, Py_NewRef(event_name_obj));
4102-
EXPAT(SetNamespaceDeclHandler)(
4101+
EXPAT(st, SetNamespaceDeclHandler)(
41034102
self->parser,
41044103
(XML_StartNamespaceDeclHandler) expat_start_ns_handler,
41054104
(XML_EndNamespaceDeclHandler) expat_end_ns_handler
41064105
);
41074106
} else if (strcmp(event_name, "end-ns") == 0) {
41084107
Py_XSETREF(target->end_ns_event_obj, Py_NewRef(event_name_obj));
4109-
EXPAT(SetNamespaceDeclHandler)(
4108+
EXPAT(st, SetNamespaceDeclHandler)(
41104109
self->parser,
41114110
(XML_StartNamespaceDeclHandler) expat_start_ns_handler,
41124111
(XML_EndNamespaceDeclHandler) expat_end_ns_handler
41134112
);
41144113
} else if (strcmp(event_name, "comment") == 0) {
41154114
Py_XSETREF(target->comment_event_obj, Py_NewRef(event_name_obj));
4116-
EXPAT(SetCommentHandler)(
4115+
EXPAT(st, SetCommentHandler)(
41174116
self->parser,
41184117
(XML_CommentHandler) expat_comment_handler
41194118
);
41204119
} else if (strcmp(event_name, "pi") == 0) {
41214120
Py_XSETREF(target->pi_event_obj, Py_NewRef(event_name_obj));
4122-
EXPAT(SetProcessingInstructionHandler)(
4121+
EXPAT(st, SetProcessingInstructionHandler)(
41234122
self->parser,
41244123
(XML_ProcessingInstructionHandler) expat_pi_handler
41254124
);
@@ -4344,14 +4343,14 @@ module_exec(PyObject *m)
43444343
goto error;
43454344

43464345
/* link against pyexpat */
4347-
expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0);
4348-
if (expat_capi) {
4346+
st->expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0);
4347+
if (st->expat_capi) {
43494348
/* check that it's usable */
4350-
if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 ||
4351-
(size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) ||
4352-
expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION ||
4353-
expat_capi->MINOR_VERSION != XML_MINOR_VERSION ||
4354-
expat_capi->MICRO_VERSION != XML_MICRO_VERSION) {
4349+
if (strcmp(st->expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 ||
4350+
(size_t)st->expat_capi->size < sizeof(struct PyExpat_CAPI) ||
4351+
st->expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION ||
4352+
st->expat_capi->MINOR_VERSION != XML_MINOR_VERSION ||
4353+
st->expat_capi->MICRO_VERSION != XML_MICRO_VERSION) {
43554354
PyErr_SetString(PyExc_ImportError,
43564355
"pyexpat version is incompatible");
43574356
goto error;

0 commit comments

Comments
 (0)