Package pyxb
[hide private]
[frames] | no frames]

Source Code for Package pyxb

  1  # -*- coding: utf-8 -*- 
  2   
  3  """PyXB stands for Python U{W3C XML 
  4  Schema<http://www.w3.org/XML/Schema>} Bindings, and is pronounced 
  5  "pixbee".  It enables translation between XML instance documents and 
  6  Python objects following rules specified by an XML Schema document. 
  7   
  8  This is the top-level entrypoint to the PyXB system.  Importing this 
  9  gets you all the L{exceptions<pyxb.exceptions_.PyXBException>}, and 
 10  L{pyxb.namespace}.  For more functionality, delve into these 
 11  submodules: 
 12   
 13   - L{pyxb.xmlschema} Module holding the 
 14     L{structures<pyxb.xmlschema.structures>} that convert XMLSchema 
 15     from a DOM model to a Python class model based on the XMLSchema 
 16     components.  Use this when you need to operate on the component 
 17     model. 
 18   
 19   - L{pyxb.binding} Module used to generate the bindings and at runtime 
 20     to support the generated bindings.  Use this if you need to use the 
 21     binding model or content model. 
 22   
 23   - L{pyxb.utils} Common utilities used in parsing, generating, and 
 24     executing.  The submodules must be imported separately. 
 25   
 26  """ 
 27   
 28  import logging 
 29  from pyxb.utils import six 
 30   
 31  _log = logging.getLogger(__name__) 
 32   
33 -class cscRoot (object):
34 """This little bundle of joy exists because in Python 2.6 it 35 became an error to invoke C{object.__init__} with parameters (unless 36 you also override C{__new__}, in which case it's only a warning. 37 Whatever.). Since I'm bloody not going to check in every class 38 whether C{super(Myclass,self)} refers to C{object} (even if I could 39 figure out how to do that, 'cuz the obvious solutions don't work), 40 we'll just make this thing the root of all U{cooperative super 41 calling<http://www.geocities.com/foetsch/python/new_style_classes.htm#super>} 42 hierarchies. The standard syntax in PyXB for this pattern is:: 43 44 def method_csc (self, *args, **kw): 45 self_fn = lambda *_args, **_kw: self 46 super_fn = getattr(super(ThisClass, self), 'method_csc', self_fn) 47 return super_fn(*args, **kw) 48 49 """ 50
51 - def __init__ (self, *args, **kw):
52 # Oh gross. If this class descends from list (and probably dict), we 53 # get here when object is *not* our direct superclass. In that case, 54 # we have to pass the arguments on up, or the strings don't get 55 # created right. Below is the only way I've figured out to detect the 56 # situation. 57 # 58 # Note that we might also get here if you mix-in a class that used 59 # object as a parent instead of cscRoot. Don't do that. Printing the 60 # mro() is a decent way of identifying the problem. 61 if issubclass(self.__class__.mro()[-2], ( list, dict )): 62 super(cscRoot, self).__init__(*args)
63 64 __version__ = '1.2.5' 65 """The version of PyXB""" 66 67 __url__ = 'http://pyxb.sourceforge.net' 68 """The URL for PyXB's homepage""" 69 70 __license__ = 'Apache License 2.0' 71 72 # Bring in the exception hierarchy 73 from pyxb.exceptions_ import * 74 75 # Bring in namespace stuff 76 import pyxb.namespace 77
78 -class BIND (object):
79 """Bundle data for automated binding generation. 80 81 Instances of this class capture positional and keyword arguments that are 82 used to create binding instances based on context. For example, if C{w} 83 is an instance of a complex type whose C{option} element is declared to be 84 an anonymous class with simple content of type integer and an attribute of 85 C{units}, a correct assignment to that element could be achieved with:: 86 87 w.option = BIND(54, units="m") 88 89 """ 90 __args = None 91 __kw = None 92
93 - def __init__ (self, *args, **kw):
94 """Cache parameters for subsequent binding creation. 95 Invoke just as you would the factory for a binding class.""" 96 self.__args = args 97 self.__kw = kw
98
99 - def createInstance (self, factory, **kw):
100 """Invoke the given factory method. 101 102 Position arguments to the factory are those cached in this instance. 103 Keyword arguments are the ones on the command line, updated from the 104 ones in this instance.""" 105 kw.update(self.__kw) 106 return factory(*self.__args, **kw)
107 108 109 XMLStyle_minidom = 0 110 """Use xml.dom.minidom for XML processing. This is the fastest, but does not 111 provide location information. It produces DOM instances.""" 112 113 XMLStyle_saxdom = 1 114 """Use pyxb.utils.saxdom for XML processing. This is the slowest, but both 115 provides location information and generates a DOM instance.""" 116 117 XMLStyle_saxer = 2 118 """Use pyxb.binding.saxer when converting documents to binding instances. 119 This style supports location information in the bindings. It produces binding 120 instances directly, without going through a DOM stage, so is faster than 121 XMLStyle_saxdom. However, since the pyxb.xmlschema.structures classes require 122 a DOM model, XMLStyle_saxdom will be used for pyxb.utils.domutils.StringToDOM 123 if this style is selected.""" 124 125 _XMLStyle = XMLStyle_saxer 126 """The current XML processing style.""" 127 128 _XMLStyleMap = { 'minidom' : XMLStyle_minidom, 129 'saxdom' : XMLStyle_saxdom, 130 'saxer' : XMLStyle_saxer } 131 _XMLStyleMapReverse = dict([ (_v, _k) for (_k, _v) in six.iteritems(_XMLStyleMap) ]) 132 133 _XMLStyle_envvar = 'PYXB_XML_STYLE' 134
135 -def _SetXMLStyle (style=None):
136 """Set the interface used to parse XML content. 137 138 This can be invoked within code. The system default of L{XMLStyle_saxer} 139 can also be overridden at runtime by setting the environment variable 140 C{PYXB_XML_STYLE} to one of C{minidom}, C{saxdom}, or C{saxer}. 141 142 @param style: One of L{XMLStyle_minidom}, L{XMLStyle_saxdom}, 143 L{XMLStyle_saxer}. If not provided, the system default is used. 144 """ 145 global _XMLStyle 146 if style is None: 147 import os 148 style_name = os.environ.get(_XMLStyle_envvar) 149 if style_name is None: 150 style_name = 'saxer' 151 style = _XMLStyleMap.get(style_name) 152 if style is None: 153 raise PyXBException('Bad value "%s" for %s' % (style_name, _XMLStyle_envvar)) 154 if _XMLStyleMapReverse.get(style) is None: 155 raise PyXBException('Bad value %s for _SetXMLStyle' % (style,)) 156 _XMLStyle = style
157 158 _SetXMLStyle() 159 160 # Global flag that we can use to determine whether optimization is active in 161 # this session. There may be cases where we can bypass methods that just 162 # check for things we don't care about in an optimized context 163 _OptimizationActive = False 164 try: 165 assert False 166 _OptimizationActive = True 167 except: 168 pass 169 170 _CorruptionDetectionEnabled = not _OptimizationActive 171 """If C{True}, blocks attempts to assign to attributes that are reserved for 172 PyXB methods. 173 174 Applies only at compilation time; dynamic changes are ignored. 175 """ 176
177 -class ValidationConfig (object):
178 """Class holding configuration related to validation. 179 180 L{pyxb.GlobalValidationConfig} is available to influence validation in all 181 contexts. Each binding class has a reference to an instance of this 182 class, which can be inspected using 183 L{pyxb.binding.basis._TypeBinding_mixin._GetValidationConfig} and changed 184 using L{pyxb.binding.basis._TypeBinding_mixin._SetValidationConfig}. Each 185 binding instance has a reference inherited from its class which can be 186 inspected using L{pyxb.binding.basis._TypeBinding_mixin._validationConfig} 187 and changed using 188 L{pyxb.binding.basis._TypeBinding_mixin._setValidationConfig}. 189 190 This allows fine control on a per class and per-instance basis. 191 192 L{forBinding} replaces L{RequireValidWhenParsing}. 193 194 L{forDocument} replaces L{RequireValidWhenGenerating}. 195 196 L{contentInfluencesGeneration}, L{orphanElementInContent}, and 197 L{invalidElementInContent} control how 198 L{pyxb.binding.basis.complexTypeDefinition.orderedContent} affects 199 generated documents. 200 """ 201 202 __forBinding = True
203 - def _getForBinding (self):
204 """C{True} iff validation should be performed when manipulating a 205 binding instance. 206 207 This includes parsing a document or DOM tree, using a binding instance 208 class constructor, or assigning to an element or attribute field of a 209 binding instance.""" 210 return self.__forBinding
211 - def _setForBinding (self, value):
212 """Configure whether validation should be performed when manipulating 213 a binding instance.""" 214 if not isinstance(value, bool): 215 raise TypeError(value) 216 self.__forBinding = value 217 return value
218 forBinding = property(_getForBinding) 219 220 __forDocument = True
221 - def _getForDocument (self):
222 """C{True} iff validation should be performed when creating a document 223 from a binding instance. 224 225 This applies at invocation of 226 L{toDOM()<pyxb.binding.basis._TypeBinding_mixin.toDOM>}. 227 L{toxml()<pyxb.binding.basis._TypeBinding_mixin.toDOM>} invokes C{toDOM()}.""" 228 return self.__forDocument
229 - def _setForDocument (self, value):
230 """Configure whether validation should be performed when generating 231 a document from a binding instance.""" 232 if not isinstance(value, bool): 233 raise TypeError(value) 234 self.__forDocument = value 235 return value
236 forDocument = property(_getForDocument) 237 238 ALWAYS = -1 239 """Always do it.""" 240 241 NEVER = 0 242 """Never do it.""" 243 244 IGNORE_ONCE = 1 245 """If an error occurs ignore it and continue with the next one. (E.g., if 246 an element in a content list fails skip it and continue with the next 247 element in the list.)""" 248 249 GIVE_UP = 2 250 """If an error occurs ignore it and stop using whatever provided the cause 251 of the error. (E.g., if an element in a content list fails stop 252 processing the content list and execute as though it was absent).""" 253 254 RAISE_EXCEPTION = 3 255 """If an error occurs, raise an exception.""" 256 257 MIXED_ONLY = 4 258 """Only when content type is mixed.""" 259 260 __contentInfluencesGeneration = MIXED_ONLY
262 """Determine whether complex type content influences element order in 263 document generation. 264 265 The value is one of L{ALWAYS}, L{NEVER}, L{MIXED_ONLY} (default).""" 266 return self.__contentInfluencesGeneration
267 - def _setContentInfluencesGeneration (self, value):
268 """Set the value of L{contentInfluencesGeneration}.""" 269 if not (value in ( self.ALWAYS, self.NEVER, self.MIXED_ONLY )): 270 raise ValueError(value) 271 self.__contentInfluencesGeneration = value
272 contentInfluencesGeneration = property(__getContentInfluencesGeneration) 273 274 __orphanElementInContent = IGNORE_ONCE
276 """How to handle unrecognized elements in content lists. 277 278 This is used when consulting a complex type instance content list to 279 influence the generation of documents from a binding instance. 280 281 The value is one of L{IGNORE_ONCE} (default), L{GIVE_UP}, 282 L{RAISE_EXCEPTION}.""" 283 return self.__orphanElementInContent
284 - def _setOrphanElementInContent (self, value):
285 """Set the value of L{orphanElementInContent}.""" 286 if not (value in ( self.IGNORE_ONCE, self.GIVE_UP, self.RAISE_EXCEPTION )): 287 raise ValueError(value) 288 self.__orphanElementInContent = value
289 orphanElementInContent = property(__getOrphanElementInContent) 290 291 __invalidElementInContent = IGNORE_ONCE
293 """How to handle invalid elements in content lists. 294 295 The value is one of L{IGNORE_ONCE} (default), L{GIVE_UP}, 296 L{RAISE_EXCEPTION}.""" 297 return self.__invalidElementInContent
298 - def _setInvalidElementInContent (self, value):
299 """Set the value of L{invalidElementInContent}.""" 300 if not (value in ( self.IGNORE_ONCE, self.GIVE_UP, self.RAISE_EXCEPTION )): 301 raise ValueError(value) 302 self.__invalidElementInContent = value
303 invalidElementInContent = property(__getInvalidElementInContent) 304
305 - def copy (self):
306 """Make a copy of this instance. 307 308 Use this to get a starting point when you need to customize validation 309 on a per-instance/per-class basis.""" 310 import copy 311 return copy.copy(self)
312 313 GlobalValidationConfig = ValidationConfig() 314 315 _GenerationRequiresValid = True 316 """Legacy flag; prefer L{forDocument<ValidationConfig.forDocument>} in L{GlobalValidationConfig}.""" 317
318 -def RequireValidWhenGenerating (value=None):
319 """Query or set a flag that controls validation checking in XML generation. 320 321 Normally any attempts to convert a binding instance to a DOM or XML 322 representation requires that the binding validate against the content 323 model, since only in this way can the content be generated in the correct 324 order. In some cases it may be necessary or useful to generate a document 325 from a binding that is incomplete. If validation is not required, the 326 generated documents may not validate even if the content validates, 327 because ordering constraints will be ignored. 328 329 @keyword value: If absent or C{None}, no change is made; otherwise, this 330 enables (C{True}) or disables (C{False}) the requirement that instances 331 validate before being converted to XML. 332 @type value: C{bool} 333 334 @return: C{True} iff attempts to generate XML for a binding that does not 335 validate should raise an exception. """ 336 if value is None: 337 return GlobalValidationConfig.forDocument 338 global _GenerationRequiresValid 339 _GenerationRequiresValid = GlobalValidationConfig._setForDocument(value) 340 return value
341 342 _ParsingRequiresValid = True 343 """Legacy flag; prefer L{forBinding<ValidationConfig.forBinding>} in L{GlobalValidationConfig}."""
344 -def RequireValidWhenParsing (value=None):
345 """Query or set a flag that controls validation checking in XML parsing. 346 347 Normally any attempts to convert XML to a binding instance to a binding 348 instance requires that the document validate against the content model. 349 In some cases it may be necessary or useful to process a document that is 350 incomplete. If validation is not required, the generated documents may 351 not validate even if the content validates, because ordering constraints 352 will be ignored. 353 354 @keyword value: If absent or C{None}, no change is made; otherwise, this 355 enables (C{True}) or disables (C{False}) the requirement that documents 356 validate when being converted to bindings. 357 @type value: C{bool} 358 359 @return: C{True} iff attempts to generate bindings for a document that 360 does not validate should raise an exception.""" 361 if value is None: 362 return GlobalValidationConfig.forBinding 363 global _ParsingRequiresValid 364 _ParsingRequiresValid = GlobalValidationConfig._setForBinding(value) 365 return _ParsingRequiresValid
366 367 _PreserveInputTimeZone = False
368 -def PreserveInputTimeZone (value=None):
369 """Control whether time values are converted to UTC during input. 370 371 The U{specification <http://www.w3.org/TR/xmlschema-2/#dateTime>} makes 372 clear that timezoned times are in UTC and that times in other timezones 373 are to be translated to UTC when converted from literal to value form. 374 Provide an option to bypass this step, so the input timezone is preserved. 375 376 @note: Naive processing of unnormalized times--i.e., ignoring the 377 C{tzinfo} field--may result in errors.""" 378 global _PreserveInputTimeZone 379 if value is None: 380 return _PreserveInputTimeZone 381 if not isinstance(value, bool): 382 raise TypeError(value) 383 _PreserveInputTimeZone = value 384 return _PreserveInputTimeZone
385 386 _OutputEncoding = 'utf-8' 387 """Default unicode encoding to use when creating output. 388 389 Material being written to an XML parser is not output.""" 390 391 _InputEncoding = 'utf-8' 392 """Default unicode encoding to assume when decoding input. 393 394 Material being written to an XML parser is treated as input.""" 395
396 -def NonElementContent (instance):
397 """Return an iterator producing the non-element content of the provided instance. 398 399 The catenated text of the non-element content of an instance can 400 be obtained with:: 401 402 text = six.u('').join(pyxb.NonElementContent(instance)) 403 404 @param instance: An instance of L{pyxb.binding.basis.complexTypeDefinition}. 405 406 @return: an iterator producing text values 407 """ 408 import pyxb.binding.basis 409 return pyxb.binding.basis.NonElementContent.ContentIterator(instance.orderedContent())
410 411 ## Local Variables: 412 ## fill-column:78 413 ## End: 414