66version = "0.20"
77
88from 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
1116import sys
2530AttributesImpl = xmlreader .AttributesImpl
2631AttributesNSImpl = 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