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