Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 18476a3

Browse files
committed
Merge changes from PyXML:
[1.15] Added understanding of the feature_validation, feature_external_pes, and feature_string_interning features. Added support for the feature_external_ges feature. Added support for the property_xml_string property. [1.16] Made it recognize the namespace prefixes feature. [1.17] removed erroneous first line [1.19] Support optional string interning in pyexpat. [1.21] Restore compatibility with versions of Python that did not support weak references. These do not get the cyclic reference fix, but they will continue to work as they did before. [1.22] Activate entity processing unless standalone.
1 parent b4fcf4d commit 18476a3

1 file changed

Lines changed: 76 additions & 13 deletions

File tree

Lib/xml/sax/expatreader.py

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
version = "0.20"
77

88
from xml.sax._exceptions import *
9+
from xml.sax.handler import feature_validation, feature_namespaces
10+
from xml.sax.handler import feature_namespace_prefixes
11+
from xml.sax.handler import feature_external_ges, feature_external_pes
12+
from xml.sax.handler import feature_string_interning
13+
from xml.sax.handler import property_xml_string, property_interning_dict
914

1015
# xml.parsers.expat does not raise ImportError in Jython
1116
import sys
@@ -25,7 +30,18 @@
2530
AttributesImpl = xmlreader.AttributesImpl
2631
AttributesNSImpl = xmlreader.AttributesNSImpl
2732

28-
import weakref
33+
# If we're using a sufficiently recent version of Python, we can use
34+
# weak references to avoid cycles between the parser and content
35+
# handler, otherwise we'll just have to pretend.
36+
try:
37+
import _weakref
38+
except ImportError:
39+
def _mkproxy(o):
40+
return o
41+
else:
42+
import weakref
43+
_mkproxy = weakref.proxy
44+
del weakref, _weakref
2945

3046
# --- ExpatLocator
3147

@@ -36,28 +52,28 @@ class ExpatLocator(xmlreader.Locator):
3652
a circular reference between the parser and the content handler.
3753
"""
3854
def __init__(self, parser):
39-
self._ref = weakref.ref(parser)
55+
self._ref = _mkproxy(parser)
4056

4157
def getColumnNumber(self):
42-
parser = self._ref()
43-
if parser is None or parser._parser is None:
58+
parser = self._ref
59+
if parser._parser is None:
4460
return None
4561
return parser._parser.ErrorColumnNumber
4662

4763
def getLineNumber(self):
48-
parser = self._ref()
49-
if parser is None or parser._parser is None:
64+
parser = self._ref
65+
if parser._parser is None:
5066
return 1
5167
return parser._parser.ErrorLineNumber
5268

5369
def getPublicId(self):
54-
parser = self._ref()
70+
parser = self._ref
5571
if parser is None:
5672
return None
5773
return parser._source.getPublicId()
5874

5975
def getSystemId(self):
60-
parser = self._ref()
76+
parser = self._ref
6177
if parser is None:
6278
return None
6379
return parser._source.getSystemId()
@@ -76,6 +92,8 @@ def __init__(self, namespaceHandling=0, bufsize=2**16-20):
7692
self._lex_handler_prop = None
7793
self._parsing = 0
7894
self._entity_stack = []
95+
self._external_ges = 1
96+
self._interning = None
7997

8098
# XMLReader methods
8199

@@ -100,31 +118,72 @@ def setContentHandler(self, handler):
100118
self._reset_cont_handler()
101119

102120
def getFeature(self, name):
103-
if name == handler.feature_namespaces:
121+
if name == feature_namespaces:
104122
return self._namespaces
123+
elif name == feature_string_interning:
124+
return self._interning is not None
125+
elif name in (feature_validation, feature_external_pes,
126+
feature_namespace_prefixes):
127+
return 0
128+
elif name == feature_external_ges:
129+
return self._external_ges
105130
raise SAXNotRecognizedException("Feature '%s' not recognized" % name)
106131

107132
def setFeature(self, name, state):
108133
if self._parsing:
109134
raise SAXNotSupportedException("Cannot set features while parsing")
110-
if name == handler.feature_namespaces:
135+
136+
if name == feature_namespaces:
111137
self._namespaces = state
138+
elif name == feature_external_ges:
139+
self._external_ges = state
140+
elif name == feature_string_interning:
141+
if state:
142+
if self._interning is None:
143+
self._interning = {}
144+
else:
145+
self._interning = None
146+
elif name == feature_validation:
147+
if state:
148+
raise SAXNotSupportedException("expat does not support validation")
149+
elif name == feature_external_pes:
150+
if state:
151+
raise SAXNotSupportedException("expat does not read external parameter entities")
152+
elif name == feature_namespace_prefixes:
153+
if state:
154+
raise SAXNotSupportedException("expat does not report namespace prefixes")
112155
else:
113156
raise SAXNotRecognizedException("Feature '%s' not recognized" %
114157
name)
115158

116159
def getProperty(self, name):
117160
if name == handler.property_lexical_handler:
118161
return self._lex_handler_prop
162+
elif name == property_interning_dict:
163+
return self._interning
164+
elif name == property_xml_string:
165+
if self._parser:
166+
if hasattr(self._parser, "GetInputContext"):
167+
return self._parser.GetInputContext()
168+
else:
169+
raise SAXNotRecognizedException("This version of expat does not support getting the XML string")
170+
else:
171+
raise SAXNotSupportedException("XML string cannot be returned when not parsing")
119172
raise SAXNotRecognizedException("Property '%s' not recognized" % name)
120173

121174
def setProperty(self, name, value):
122175
if name == handler.property_lexical_handler:
123176
self._lex_handler_prop = value
124177
if self._parsing:
125178
self._reset_lex_handler_prop()
179+
elif name == property_interning_dict:
180+
self._interning = value
181+
elif name == property_xml_string:
182+
raise SAXNotSupportedException("Property '%s' cannot be set" %
183+
name)
126184
else:
127-
raise SAXNotRecognizedException("Property '%s' not recognized" % name)
185+
raise SAXNotRecognizedException("Property '%s' not recognized" %
186+
name)
128187

129188
# IncrementalParser methods
130189

@@ -168,11 +227,11 @@ def _reset_lex_handler_prop(self):
168227

169228
def reset(self):
170229
if self._namespaces:
171-
self._parser = expat.ParserCreate(None, " ")
230+
self._parser = expat.ParserCreate(None, " ", intern = self._interning)
172231
self._parser.StartElementHandler = self.start_element_ns
173232
self._parser.EndElementHandler = self.end_element_ns
174233
else:
175-
self._parser = expat.ParserCreate()
234+
self._parser = expat.ParserCreate(intern = self._interning)
176235
self._parser.StartElementHandler = self.start_element
177236
self._parser.EndElementHandler = self.end_element
178237

@@ -189,6 +248,7 @@ def reset(self):
189248
# self._parser.DefaultHandlerExpand =
190249
# self._parser.NotStandaloneHandler =
191250
self._parser.ExternalEntityRefHandler = self.external_entity_ref
251+
self._parser.SetParamEntityParsing(expat.XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
192252

193253
self._parsing = 0
194254
self._entity_stack = []
@@ -268,6 +328,9 @@ def notation_decl(self, name, base, sysid, pubid):
268328
self._dtd_handler.notationDecl(name, pubid, sysid)
269329

270330
def external_entity_ref(self, context, base, sysid, pubid):
331+
if not self._external_ges:
332+
return 1
333+
271334
source = self._ent_handler.resolveEntity(pubid, sysid)
272335
source = saxutils.prepare_input_source(source,
273336
self._source.getSystemId() or

0 commit comments

Comments
 (0)