diff --git a/README.rst b/README.rst index 6183e7ff134286daca9ff6e96c55778f5423573c..676d63716e1d9ac3af967bee658fdd804684325f 100644 --- a/README.rst +++ b/README.rst @@ -141,6 +141,17 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Change history -------------- +Version 2.29.8 (03/02/2018) + +- Added a change so that an attribute specified as `fixed` will be + handled in the same way as one specified as `default`. This + leaves it to the user to validate and enforce the `fixed` + restriction in some other way, e.g. through use of an XML + validating parser such as `xmllint`. Thanks to Sanja Abbott for + suggesting this enhancement. +- Various fixes for string/unicode differences across Python 2 and + Python 3. + Version 2.29.7 (02/05/2018) - Fix for unicode error that occurs during simpleType validation diff --git a/generateDS.html b/generateDS.html index 38fc6cc8b5072e44f2f60c7c4d81519ec5eee652..ea060c8c81eba7e1a0166eb77a6c8aace210f41b 100644 --- a/generateDS.html +++ b/generateDS.html @@ -220,7 +220,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.7</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.8</td> </tr> </tbody> </table> @@ -229,7 +229,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">date:</th><td class="field-body">February 05, 2018</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">March 02, 2018</td> </tr> </tbody> </table> @@ -3380,7 +3380,7 @@ following among others:</p> <div class="footer"> <hr class="footer" /> <a class="reference external" href="generateDS.txt">View document source</a>. -Generated on: 2018-02-05 22:01 UTC. +Generated on: 2018-03-02 19:35 UTC. Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. </div> diff --git a/generateDS.py b/generateDS.py index b68e94707873d0c7204f9eb5923c19ffcbf46d5e..81f53ea440add94ca7d3d70584589117037a6d08 100755 --- a/generateDS.py +++ b/generateDS.py @@ -229,7 +229,7 @@ logging.disable(logging.INFO) # Do not modify the following VERSION comments. # Used by updateversion.py. ##VERSION## -VERSION = '2.29.7' +VERSION = '2.29.8' ##VERSION## BaseStrTypes = six.string_types @@ -1431,11 +1431,15 @@ class XschemaAttribute: name, data_type='xs:string', use='optional', - default=None): + default=None, + fixed=None): self.name = name self.data_type = data_type self.use = use self.default = default + # treat `fixed` the same as `default`. + if fixed is not None: + self.default = fixed # Enumeration values for the attribute. self.values = list() # If we change the name, e.g. because an attribute and child have @@ -1695,13 +1699,19 @@ class XschemaHandler(handler.ContentHandler): default = attrs['default'] else: default = None + if 'fixed' in attrs: + fixed = attrs['fixed'] + else: + fixed = None if self.stack[-1].attributeGroup: # Add this attribute to a current attributeGroup. - attribute = XschemaAttribute(name, data_type, use, default) + attribute = XschemaAttribute( + name, data_type, use, default, fixed) self.stack[-1].attributeGroup.add(name, attribute) else: # Add this attribute to the element/complexType. - attribute = XschemaAttribute(name, data_type, use, default) + attribute = XschemaAttribute( + name, data_type, use, default, fixed) self.stack[-1].attributeDefs[name] = attribute self.stack[-1].attributeDefsList.append(name) self.lastAttribute = attribute @@ -2651,6 +2661,8 @@ def generateExportAttributes(wrt, element, hasAttributes): s1 = ' if self.%s != "%s" and ' % ( cleanName, default, ) s1 += "'%s' not in already_processed:\n" % (cleanName, ) + if sys.version_info.major == 2: + s1 = s1.encode('utf-8') wrt(s1) wrt(" already_processed.add('%s')\n" % ( cleanName, )) @@ -2707,6 +2719,8 @@ def generateExportAttributes(wrt, element, hasAttributes): s1 = '''%s outfile.write(' %s=%%s' %% ''' \ '''(quote_attrib(self.%s), ))\n''' % ( indent, orig_name, cleanName, ) + if sys.version_info.major == 2: + s1 = s1.encode('utf-8') wrt(s1) if element.getExtended(): wrt(" if self.extensiontype_ is not None and 'xsi:type' " @@ -2810,6 +2824,10 @@ def getParentName(element): def generateExportFn(wrt, prefix, element, namespace, nameSpacesDef): childCount = countChildren(element, 0) name = element.getName() + if sys.version_info.major == 2: + encodedname = name.encode('utf-8') + else: + encodedname = name base = element.getBase() ns_prefix = SchemaNamespaceDict.get(name) if ns_prefix is not None and ns_prefix[0] is not None: @@ -2819,9 +2837,9 @@ def generateExportFn(wrt, prefix, element, namespace, nameSpacesDef): nameSpacesDef += ' {}="{}"'.format(ns_def, ns_prefix[1]) wrt(" def export(self, outfile, level, namespace_='%s', " "name_='%s', namespacedef_='%s', pretty_print=True):\n" % - (namespace, name, nameSpacesDef)) + (namespace, encodedname, nameSpacesDef)) wrt(" imported_ns_def_ = GenerateDSNamespaceDefs_.get" - "('%s')\n" % (name, )) + "('%s')\n" % (encodedname, )) wrt(" if imported_ns_def_ is not None:\n") wrt(" namespacedef_ = imported_ns_def_\n") wrt(' if pretty_print:\n') @@ -2837,7 +2855,7 @@ def generateExportFn(wrt, prefix, element, namespace, nameSpacesDef): wrt(" already_processed = set()\n") wrt(" self.exportAttributes(outfile, level, " "already_processed, namespace_, name_='%s')\n" % - (name, )) + (encodedname, )) # fix_abstract if base and base in ElementDict: base_element = ElementDict[base] @@ -2863,7 +2881,7 @@ def generateExportFn(wrt, prefix, element, namespace, nameSpacesDef): wrt(" outfile.write('>%s' % (eol_, ))\n") wrt(" self.exportChildren(outfile, level + 1, " "namespace_='%s', name_='%s', pretty_print=pretty_print)\n" % - (namespace, name)) + (namespace, encodedname)) # Put a condition on the indent to require children. if childCount != 0: wrt(' showIndent(outfile, level, pretty_print)\n') @@ -2873,7 +2891,7 @@ def generateExportFn(wrt, prefix, element, namespace, nameSpacesDef): wrt(" outfile.write('/>%s' % (eol_, ))\n") wrt(" def exportAttributes(self, outfile, level, " "already_processed, namespace_='%s', name_='%s'):\n" % - (namespace, name, )) + (namespace, encodedname, )) hasAttributes = 0 if element.getAnyAttribute(): wrt("""\ @@ -2914,13 +2932,13 @@ def generateExportFn(wrt, prefix, element, namespace, nameSpacesDef): elName = element.getCleanName() wrt(" super(%s%s, self).exportAttributes(" "outfile, level, already_processed, namespace_, name_='%s')\n" % - (prefix, elName, name, )) + (prefix, elName, encodedname, )) hasAttributes += generateExportAttributes(wrt, element, hasAttributes) if hasAttributes == 0: wrt(" pass\n") wrt(" def exportChildren(self, outfile, level, namespace_='%s', " "name_='%s', fromsubclass_=False, pretty_print=True):\n" % - (namespace, name, )) + (namespace, encodedname, )) hasChildren = 0 # Generate call to exportChildren in the superclass only if it is # an extension, but *not* if it is a restriction. @@ -4120,6 +4138,8 @@ def generateCtor(wrt, prefix, element): elName = element.getCleanName() childCount = countChildren(element, 0) s2 = buildCtorArgs_multilevel(element, childCount) + if sys.version_info.major == 2: + s2 = s2.encode('utf-8') wrt(' def __init__(self%s):\n' % s2) # Save the original tag name. This is needed when there is a # xs:substitutionGroup and we later (e.g. during export) do not know @@ -7118,8 +7138,12 @@ def capture_cleanup_name_list(option): 'Option --cleanup-name-list contains ' 'invalid element.') try: + if sys.version_info.major == 2: + target = cleanup_pair[0].decode('utf-8') + else: + target = cleanup_pair[0] cleanupNameList.append( - (re.compile(cleanup_pair[0]), cleanup_pair[1])) + (re.compile(target), cleanup_pair[1])) except Exception: raise RuntimeError( 'Option --cleanup-name-list contains invalid ' diff --git a/generateDS.txt b/generateDS.txt index 86be3c3a4263d555a76f9a289dcb61b347fa137c..d90d20ee52ce7199d70a5edfb34518ed82ecc764 100644 --- a/generateDS.txt +++ b/generateDS.txt @@ -12,7 +12,7 @@ generateDS -- Generate Data Structures from XML Schema .. version -:revision: 2.29.7 +:revision: 2.29.8 .. version diff --git a/generateds_gui_notes.html b/generateds_gui_notes.html index f92b4b069054e698d04213c47c0b469dd423d221..1358124ef445e414c292b79a9a4a5e1a90c1c325 100644 --- a/generateds_gui_notes.html +++ b/generateds_gui_notes.html @@ -220,7 +220,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.7</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.8</td> </tr> </tbody> </table> @@ -229,7 +229,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">date:</th><td class="field-body">February 05, 2018</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">March 02, 2018</td> </tr> </tbody> </table> @@ -401,7 +401,7 @@ $ mv generateds_gui.mo locale/ru/LC_MESSAGES/ <div class="footer"> <hr class="footer" /> <a class="reference external" href="generateds_gui_notes.txt">View document source</a>. -Generated on: 2018-02-05 22:01 UTC. +Generated on: 2018-03-02 19:35 UTC. Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. </div> diff --git a/generateds_gui_notes.txt b/generateds_gui_notes.txt index e509ff5909c6ab1ea0d10e6a3b3f5b813d1ae6b1..a0172b177ef52d64802c694e70e2b22bd635dee1 100644 --- a/generateds_gui_notes.txt +++ b/generateds_gui_notes.txt @@ -12,7 +12,7 @@ GenerateDS GUI Notes .. version -:revision: 2.29.7 +:revision: 2.29.8 .. version diff --git a/gui/generateds_gui.py b/gui/generateds_gui.py index 59f7cd71d11edc7bea0cfc4c93f142d94c36a5a2..5fa5216915f7d4af65dfd41b377bc883ac7c293e 100644 --- a/gui/generateds_gui.py +++ b/gui/generateds_gui.py @@ -41,7 +41,7 @@ from libgenerateDS.gui import generateds_gui_session # Do not modify the following VERSION comments. # Used by updateversion.py. ##VERSION## -VERSION = '2.29.7' +VERSION = '2.29.8' ##VERSION## diff --git a/librarytemplate_howto.html b/librarytemplate_howto.html index 700cf0d5a8b31df89cbedb5127ec2943c35d718e..db0f08c3144c8c57d0fb1a62debad43b3161fa42 100644 --- a/librarytemplate_howto.html +++ b/librarytemplate_howto.html @@ -217,7 +217,7 @@ dkuhlman (at) davekuhlman (dot) org <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.7</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.8</td> </tr> </tbody> </table> @@ -226,7 +226,7 @@ dkuhlman (at) davekuhlman (dot) org <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">date:</th><td class="field-body">February 05, 2018</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">March 02, 2018</td> </tr> </tbody> </table> @@ -380,7 +380,7 @@ this command for your needs. For example, you may need to use <div class="footer"> <hr class="footer" /> <a class="reference external" href="librarytemplate_howto.txt">View document source</a>. -Generated on: 2018-02-05 22:01 UTC. +Generated on: 2018-03-02 19:35 UTC. Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. </div> diff --git a/librarytemplate_howto.txt b/librarytemplate_howto.txt index 93e2b37b75fb82227de5da243ce37d7be82d53cc..7107ceaa24f7aaa3d893bd992cd4965f5cea86cf 100644 --- a/librarytemplate_howto.txt +++ b/librarytemplate_howto.txt @@ -8,7 +8,7 @@ How to package a generateDS.py generated library .. version -:revision: 2.29.7 +:revision: 2.29.8 .. version diff --git a/process_includes.py b/process_includes.py index 57331e39c5558b22c787720120127ccd224312b6..86820811907304acc6ea286124ce46ef29cbbe08 100755 --- a/process_includes.py +++ b/process_includes.py @@ -40,7 +40,7 @@ except ImportError: # Do not modify the following VERSION comments. # Used by updateversion.py. ##VERSION## -VERSION = '2.29.7' +VERSION = '2.29.8' ##VERSION## CatalogDict = {} diff --git a/setup.py b/setup.py index 4ed191cfb02d4305ae42fbcb8e760fcb1098a230..0eddedd2724d4394ede1037c3fec7ca131c09ab9 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup(name="generateDS", # Do not modify the following VERSION comments. # Used by updateversion.py. ##VERSION## - version="2.29.7", + version="2.29.8", ##VERSION## author="Dave Kuhlman", author_email="dkuhlman@davekuhlman.org", diff --git a/tests/defaults_cases.xml b/tests/defaults_cases.xml index 5862ed47464dceb395f4ccdc77f3ac58cdeeeca5..76421334c744f35988ddc61a4d55e84f2c0f614a 100644 --- a/tests/defaults_cases.xml +++ b/tests/defaults_cases.xml @@ -27,5 +27,35 @@ <default2 attrnormal01="wxy"/> <default2 attrnormal02="89"/> + <!-- `fixed` attribute tests. + --> + + <fixed1> + <!-- case 1 --> + <!-- case 2 --> + <normal02>a new value 1</normal02> + <!-- case 3 --> + <!-- case 4 --> + <fixed02>a new value 2</fixed02> + <!-- case 5 --> + <!-- + --> + <normal03>55.66</normal03> + <!-- case 6 --> + <normal04>66.77</normal04> + <!-- case 7 --> + <!-- + --> + <fixed03>77.88</fixed03> + <!-- case 8 --> + <fixed04>88.99</fixed04> + </fixed1> + + <fixed2 attrfixed01="xyz"/> + <fixed2 attrfixed02="14"/> + <fixed2 /> + <fixed2 attrnormal01="wxy"/> + <fixed2 attrnormal02="89"/> + </defaults> diff --git a/tests/defaults_cases.xsd b/tests/defaults_cases.xsd index 32cafe45ada84a18c477c69c7dc5747d2580b346..3d76db5624fddc159145145146ca732a87d0b03f 100644 --- a/tests/defaults_cases.xsd +++ b/tests/defaults_cases.xsd @@ -11,6 +11,10 @@ maxOccurs="unbounded"/> <xs:element name="default2" type="DefaultType2" maxOccurs="unbounded"/> + <xs:element name="fixed1" type="FixedType1" + maxOccurs="unbounded"/> + <xs:element name="fixed2" type="FixedType2" + maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> @@ -94,4 +98,88 @@ <xs:attribute name="attrnormal02" type="xs:integer"/> </xs:complexType> + <!-- 'fixed' attribute tests. Note that we handle `fixed` attributes + in the same way as `default` attributes. + --> + + <xs:complexType name="FixedType1"> + <xs:sequence> + <!-- + *case 1:* + xsd: element optional, no fixed value given + xml: element missing + output: element missing + --> + <xs:element name="normal01" type="xs:integer" + minOccurs="0"/> + <!-- + *case 2:* + xsd: element optional, no fixed value given + xml: element exists + output: element is unchanged + --> + <xs:element name="normal02" type="xs:string" + minOccurs="0"/> + <!-- + *case 3:* + xsd: element optional, fixed value given + xml: element missing + expected output: element missing + current output: missing element is added with fixed value + --> + <xs:element name="fixed01" type="xs:integer" fixed="23" + minOccurs="0"/> + <!-- + *case 4:* + xsd: element optional, fixed value given + xml: element exists + output: element is unchanged + --> + <xs:element name="fixed02" type="xs:string" fixed="Peach" + minOccurs="0"/> + <!-- + *case 5:* + xsd: element mandatory, no fixed value given + xml: element missing + error on reading xml + --> + <xs:element name="normal03" type="xs:float" + minOccurs="1"/> + <!-- + *case 6:* + xsd: element mandatory, no fixed value given + xml: element exists + output: element is unchanged + --> + <xs:element name="normal04" type="xs:double" + minOccurs="1"/> + <!-- + *case 7:* + xsd: element mandatory, fixed value given + xml: element missing + error on reading xml + output: missing element is generated with fixed value + --> + <xs:element name="fixed03" type="xs:float" fixed="23.45" + minOccurs="1"/> + <!-- + *case 8:* + xsd: element mandatory, fixed value given + xml: element exists + output: element is unchanged + --> + <xs:element name="fixed04" type="xs:double" fixed="54.32" + minOccurs="1"/> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="FixedType2"> + <xs:sequence> + </xs:sequence> + <xs:attribute name="attrfixed01" type="xs:string" fixed="abcd"/> + <xs:attribute name="attrfixed02" type="xs:integer" fixed="14"/> + <xs:attribute name="attrnormal01" type="xs:string"/> + <xs:attribute name="attrnormal02" type="xs:integer"/> + </xs:complexType> + </xs:schema> diff --git a/tests/defaults_cases1_out.xml b/tests/defaults_cases1_out.xml index 58064fbb71077e954ce44c50c45802e4de17038b..3d2737ef74e766adbb8169b9dbf11f377541d8d7 100644 --- a/tests/defaults_cases1_out.xml +++ b/tests/defaults_cases1_out.xml @@ -13,4 +13,17 @@ <default2/> <default2 attrnormal01="wxy"/> <default2 attrnormal02="89"/> + <fixed1> + <normal02>a new value 1</normal02> + <fixed02>a new value 2</fixed02> + <normal03>55.659999999999997</normal03> + <normal04>6.677000e+01</normal04> + <fixed03>77.879999999999995</fixed03> + <fixed04>8.899000e+01</fixed04> + </fixed1> + <fixed2 attrfixed01="xyz"/> + <fixed2/> + <fixed2/> + <fixed2 attrnormal01="wxy"/> + <fixed2 attrnormal02="89"/> </defaults> diff --git a/tests/defaults_cases1_sub.py b/tests/defaults_cases1_sub.py index af45048b04eb5aa92c5b5c7fca309a5092d5ccc5..32171bb9111163d20ddbcf07302be9315a10436f 100644 --- a/tests/defaults_cases1_sub.py +++ b/tests/defaults_cases1_sub.py @@ -48,8 +48,8 @@ ExternalEncoding = 'ascii' class DefaultTypesSub(supermod.DefaultTypes): - def __init__(self, default1=None, default2=None): - super(DefaultTypesSub, self).__init__(default1, default2, ) + def __init__(self, default1=None, default2=None, fixed1=None, fixed2=None): + super(DefaultTypesSub, self).__init__(default1, default2, fixed1, fixed2, ) supermod.DefaultTypes.subclass = DefaultTypesSub # end class DefaultTypesSub @@ -68,6 +68,20 @@ supermod.DefaultType2.subclass = DefaultType2Sub # end class DefaultType2Sub +class FixedType1Sub(supermod.FixedType1): + def __init__(self, normal01=None, normal02=None, fixed01=None, fixed02=None, normal03=None, normal04=None, fixed03=None, fixed04=None): + super(FixedType1Sub, self).__init__(normal01, normal02, fixed01, fixed02, normal03, normal04, fixed03, fixed04, ) +supermod.FixedType1.subclass = FixedType1Sub +# end class FixedType1Sub + + +class FixedType2Sub(supermod.FixedType2): + def __init__(self, attrfixed01='abcd', attrfixed02=14, attrnormal01=None, attrnormal02=None): + super(FixedType2Sub, self).__init__(attrfixed01, attrfixed02, attrnormal01, attrnormal02, ) +supermod.FixedType2.subclass = FixedType2Sub +# end class FixedType2Sub + + def get_root_tag(node): tag = supermod.Tag_pattern_.match(node.tag).groups()[-1] rootClass = None diff --git a/tests/defaults_cases1_sup.py b/tests/defaults_cases1_sup.py index e576fe27d0ab5b983342c99851e70c37b58dff4a..78baf41f2d572ebe23939af20dcfb0c4ab14f534 100644 --- a/tests/defaults_cases1_sup.py +++ b/tests/defaults_cases1_sup.py @@ -725,10 +725,12 @@ class DefaultTypes(GeneratedsSuper): member_data_items_ = [ MemberSpec_('default1', 'DefaultType1', 1, 0, {u'maxOccurs': u'unbounded', u'type': u'DefaultType1', u'name': u'default1'}, None), MemberSpec_('default2', 'DefaultType2', 1, 0, {u'maxOccurs': u'unbounded', u'type': u'DefaultType2', u'name': u'default2'}, None), + MemberSpec_('fixed1', 'FixedType1', 1, 0, {u'maxOccurs': u'unbounded', u'type': u'FixedType1', u'name': u'fixed1'}, None), + MemberSpec_('fixed2', 'FixedType2', 1, 0, {u'maxOccurs': u'unbounded', u'type': u'FixedType2', u'name': u'fixed2'}, None), ] subclass = None superclass = None - def __init__(self, default1=None, default2=None): + def __init__(self, default1=None, default2=None, fixed1=None, fixed2=None): self.original_tagname_ = None if default1 is None: self.default1 = [] @@ -738,6 +740,14 @@ class DefaultTypes(GeneratedsSuper): self.default2 = [] else: self.default2 = default2 + if fixed1 is None: + self.fixed1 = [] + else: + self.fixed1 = fixed1 + if fixed2 is None: + self.fixed2 = [] + else: + self.fixed2 = fixed2 def factory(*args_, **kwargs_): if CurrentSubclassModule_ is not None: subclass = getSubclassFromModule_( @@ -759,10 +769,22 @@ class DefaultTypes(GeneratedsSuper): def add_default2(self, value): self.default2.append(value) def insert_default2_at(self, index, value): self.default2.insert(index, value) def replace_default2_at(self, index, value): self.default2[index] = value + def get_fixed1(self): return self.fixed1 + def set_fixed1(self, fixed1): self.fixed1 = fixed1 + def add_fixed1(self, value): self.fixed1.append(value) + def insert_fixed1_at(self, index, value): self.fixed1.insert(index, value) + def replace_fixed1_at(self, index, value): self.fixed1[index] = value + def get_fixed2(self): return self.fixed2 + def set_fixed2(self, fixed2): self.fixed2 = fixed2 + def add_fixed2(self, value): self.fixed2.append(value) + def insert_fixed2_at(self, index, value): self.fixed2.insert(index, value) + def replace_fixed2_at(self, index, value): self.fixed2[index] = value def hasContent_(self): if ( self.default1 or - self.default2 + self.default2 or + self.fixed1 or + self.fixed2 ): return True else: @@ -799,6 +821,10 @@ class DefaultTypes(GeneratedsSuper): default1_.export(outfile, level, namespace_, name_='default1', pretty_print=pretty_print) for default2_ in self.default2: default2_.export(outfile, level, namespace_, name_='default2', pretty_print=pretty_print) + for fixed1_ in self.fixed1: + fixed1_.export(outfile, level, namespace_, name_='fixed1', pretty_print=pretty_print) + for fixed2_ in self.fixed2: + fixed2_.export(outfile, level, namespace_, name_='fixed2', pretty_print=pretty_print) def build(self, node): already_processed = set() self.buildAttributes(node, node.attrib, already_processed) @@ -819,6 +845,16 @@ class DefaultTypes(GeneratedsSuper): obj_.build(child_) self.default2.append(obj_) obj_.original_tagname_ = 'default2' + elif nodeName_ == 'fixed1': + obj_ = FixedType1.factory() + obj_.build(child_) + self.fixed1.append(obj_) + obj_.original_tagname_ = 'fixed1' + elif nodeName_ == 'fixed2': + obj_ = FixedType2.factory() + obj_.build(child_) + self.fixed2.append(obj_) + obj_.original_tagname_ = 'fixed2' # end class DefaultTypes @@ -1118,6 +1154,302 @@ class DefaultType2(GeneratedsSuper): # end class DefaultType2 +class FixedType1(GeneratedsSuper): + member_data_items_ = [ + MemberSpec_('normal01', 'xs:integer', 0, 1, {u'type': u'xs:integer', u'name': u'normal01', u'minOccurs': u'0'}, None), + MemberSpec_('normal02', 'xs:string', 0, 1, {u'type': u'xs:string', u'name': u'normal02', u'minOccurs': u'0'}, None), + MemberSpec_('fixed01', 'xs:integer', 0, 1, {u'fixed': u'23', u'type': u'xs:integer', u'name': u'fixed01', u'minOccurs': u'0'}, None), + MemberSpec_('fixed02', 'xs:string', 0, 1, {u'fixed': u'Peach', u'type': u'xs:string', u'name': u'fixed02', u'minOccurs': u'0'}, None), + MemberSpec_('normal03', 'xs:float', 0, 0, {u'type': u'xs:float', u'name': u'normal03', u'minOccurs': u'1'}, None), + MemberSpec_('normal04', 'xs:double', 0, 0, {u'type': u'xs:double', u'name': u'normal04', u'minOccurs': u'1'}, None), + MemberSpec_('fixed03', 'xs:float', 0, 0, {u'fixed': u'23.45', u'type': u'xs:float', u'name': u'fixed03', u'minOccurs': u'1'}, None), + MemberSpec_('fixed04', 'xs:double', 0, 0, {u'fixed': u'54.32', u'type': u'xs:double', u'name': u'fixed04', u'minOccurs': u'1'}, None), + ] + subclass = None + superclass = None + def __init__(self, normal01=None, normal02=None, fixed01=None, fixed02=None, normal03=None, normal04=None, fixed03=None, fixed04=None): + self.original_tagname_ = None + self.normal01 = normal01 + self.normal02 = normal02 + self.fixed01 = fixed01 + self.fixed02 = fixed02 + self.normal03 = normal03 + self.normal04 = normal04 + self.fixed03 = fixed03 + self.fixed04 = fixed04 + def factory(*args_, **kwargs_): + if CurrentSubclassModule_ is not None: + subclass = getSubclassFromModule_( + CurrentSubclassModule_, FixedType1) + if subclass is not None: + return subclass(*args_, **kwargs_) + if FixedType1.subclass: + return FixedType1.subclass(*args_, **kwargs_) + else: + return FixedType1(*args_, **kwargs_) + factory = staticmethod(factory) + def get_normal01(self): return self.normal01 + def set_normal01(self, normal01): self.normal01 = normal01 + def get_normal02(self): return self.normal02 + def set_normal02(self, normal02): self.normal02 = normal02 + def get_fixed01(self): return self.fixed01 + def set_fixed01(self, fixed01): self.fixed01 = fixed01 + def get_fixed02(self): return self.fixed02 + def set_fixed02(self, fixed02): self.fixed02 = fixed02 + def get_normal03(self): return self.normal03 + def set_normal03(self, normal03): self.normal03 = normal03 + def get_normal04(self): return self.normal04 + def set_normal04(self, normal04): self.normal04 = normal04 + def get_fixed03(self): return self.fixed03 + def set_fixed03(self, fixed03): self.fixed03 = fixed03 + def get_fixed04(self): return self.fixed04 + def set_fixed04(self, fixed04): self.fixed04 = fixed04 + def hasContent_(self): + if ( + self.normal01 is not None or + self.normal02 is not None or + self.fixed01 is not None or + self.fixed02 is not None or + self.normal03 is not None or + self.normal04 is not None or + self.fixed03 is not None or + self.fixed04 is not None + ): + return True + else: + return False + def export(self, outfile, level, namespace_='', name_='FixedType1', namespacedef_='', pretty_print=True): + imported_ns_def_ = GenerateDSNamespaceDefs_.get('FixedType1') + if imported_ns_def_ is not None: + namespacedef_ = imported_ns_def_ + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + if self.original_tagname_ is not None: + name_ = self.original_tagname_ + showIndent(outfile, level, pretty_print) + outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) + already_processed = set() + self.exportAttributes(outfile, level, already_processed, namespace_, name_='FixedType1') + if self.hasContent_(): + outfile.write('>%s' % (eol_, )) + self.exportChildren(outfile, level + 1, namespace_='', name_='FixedType1', pretty_print=pretty_print) + showIndent(outfile, level, pretty_print) + outfile.write('</%s%s>%s' % (namespace_, name_, eol_)) + else: + outfile.write('/>%s' % (eol_, )) + def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='FixedType1'): + pass + def exportChildren(self, outfile, level, namespace_='', name_='FixedType1', fromsubclass_=False, pretty_print=True): + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + if self.normal01 is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<normal01>%s</normal01>%s' % (self.gds_format_integer(self.normal01, input_name='normal01'), eol_)) + if self.normal02 is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<normal02>%s</normal02>%s' % (self.gds_encode(self.gds_format_string(quote_xml(self.normal02), input_name='normal02')), eol_)) + if self.fixed01 is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<fixed01>%s</fixed01>%s' % (self.gds_format_integer(self.fixed01, input_name='fixed01'), eol_)) + if self.fixed02 is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<fixed02>%s</fixed02>%s' % (self.gds_encode(self.gds_format_string(quote_xml(self.fixed02), input_name='fixed02')), eol_)) + if self.normal03 is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<normal03>%s</normal03>%s' % (self.gds_format_float(self.normal03, input_name='normal03'), eol_)) + if self.normal04 is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<normal04>%s</normal04>%s' % (self.gds_format_double(self.normal04, input_name='normal04'), eol_)) + if self.fixed03 is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<fixed03>%s</fixed03>%s' % (self.gds_format_float(self.fixed03, input_name='fixed03'), eol_)) + if self.fixed04 is not None: + showIndent(outfile, level, pretty_print) + outfile.write('<fixed04>%s</fixed04>%s' % (self.gds_format_double(self.fixed04, input_name='fixed04'), eol_)) + def build(self, node): + already_processed = set() + self.buildAttributes(node, node.attrib, already_processed) + for child in node: + nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] + self.buildChildren(child, node, nodeName_) + return self + def buildAttributes(self, node, attrs, already_processed): + pass + def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): + if nodeName_ == 'normal01': + sval_ = child_.text + try: + ival_ = int(sval_) + except (TypeError, ValueError) as exp: + raise_parse_error(child_, 'requires integer: %s' % exp) + ival_ = self.gds_validate_integer(ival_, node, 'normal01') + self.normal01 = ival_ + elif nodeName_ == 'normal02': + normal02_ = child_.text + normal02_ = self.gds_validate_string(normal02_, node, 'normal02') + self.normal02 = normal02_ + elif nodeName_ == 'fixed01': + sval_ = child_.text + try: + ival_ = int(sval_) + except (TypeError, ValueError) as exp: + raise_parse_error(child_, 'requires integer: %s' % exp) + ival_ = self.gds_validate_integer(ival_, node, 'fixed01') + self.fixed01 = ival_ + elif nodeName_ == 'fixed02': + fixed02_ = child_.text + fixed02_ = self.gds_validate_string(fixed02_, node, 'fixed02') + self.fixed02 = fixed02_ + elif nodeName_ == 'normal03': + sval_ = child_.text + try: + fval_ = float(sval_) + except (TypeError, ValueError) as exp: + raise_parse_error(child_, 'requires float or double: %s' % exp) + fval_ = self.gds_validate_float(fval_, node, 'normal03') + self.normal03 = fval_ + elif nodeName_ == 'normal04': + sval_ = child_.text + try: + fval_ = float(sval_) + except (TypeError, ValueError) as exp: + raise_parse_error(child_, 'requires float or double: %s' % exp) + fval_ = self.gds_validate_float(fval_, node, 'normal04') + self.normal04 = fval_ + elif nodeName_ == 'fixed03': + sval_ = child_.text + try: + fval_ = float(sval_) + except (TypeError, ValueError) as exp: + raise_parse_error(child_, 'requires float or double: %s' % exp) + fval_ = self.gds_validate_float(fval_, node, 'fixed03') + self.fixed03 = fval_ + elif nodeName_ == 'fixed04': + sval_ = child_.text + try: + fval_ = float(sval_) + except (TypeError, ValueError) as exp: + raise_parse_error(child_, 'requires float or double: %s' % exp) + fval_ = self.gds_validate_float(fval_, node, 'fixed04') + self.fixed04 = fval_ +# end class FixedType1 + + +class FixedType2(GeneratedsSuper): + member_data_items_ = [ + MemberSpec_('attrfixed01', 'xs:string', 0, 1, {'use': 'optional'}), + MemberSpec_('attrfixed02', 'xs:integer', 0, 1, {'use': 'optional'}), + MemberSpec_('attrnormal01', 'xs:string', 0, 1, {'use': 'optional'}), + MemberSpec_('attrnormal02', 'xs:integer', 0, 1, {'use': 'optional'}), + ] + subclass = None + superclass = None + def __init__(self, attrfixed01='abcd', attrfixed02=14, attrnormal01=None, attrnormal02=None): + self.original_tagname_ = None + self.attrfixed01 = _cast(None, attrfixed01) + self.attrfixed02 = _cast(int, attrfixed02) + self.attrnormal01 = _cast(None, attrnormal01) + self.attrnormal02 = _cast(int, attrnormal02) + def factory(*args_, **kwargs_): + if CurrentSubclassModule_ is not None: + subclass = getSubclassFromModule_( + CurrentSubclassModule_, FixedType2) + if subclass is not None: + return subclass(*args_, **kwargs_) + if FixedType2.subclass: + return FixedType2.subclass(*args_, **kwargs_) + else: + return FixedType2(*args_, **kwargs_) + factory = staticmethod(factory) + def get_attrfixed01(self): return self.attrfixed01 + def set_attrfixed01(self, attrfixed01): self.attrfixed01 = attrfixed01 + def get_attrfixed02(self): return self.attrfixed02 + def set_attrfixed02(self, attrfixed02): self.attrfixed02 = attrfixed02 + def get_attrnormal01(self): return self.attrnormal01 + def set_attrnormal01(self, attrnormal01): self.attrnormal01 = attrnormal01 + def get_attrnormal02(self): return self.attrnormal02 + def set_attrnormal02(self, attrnormal02): self.attrnormal02 = attrnormal02 + def hasContent_(self): + if ( + + ): + return True + else: + return False + def export(self, outfile, level, namespace_='', name_='FixedType2', namespacedef_='', pretty_print=True): + imported_ns_def_ = GenerateDSNamespaceDefs_.get('FixedType2') + if imported_ns_def_ is not None: + namespacedef_ = imported_ns_def_ + if pretty_print: + eol_ = '\n' + else: + eol_ = '' + if self.original_tagname_ is not None: + name_ = self.original_tagname_ + showIndent(outfile, level, pretty_print) + outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', )) + already_processed = set() + self.exportAttributes(outfile, level, already_processed, namespace_, name_='FixedType2') + if self.hasContent_(): + outfile.write('>%s' % (eol_, )) + self.exportChildren(outfile, level + 1, namespace_='', name_='FixedType2', pretty_print=pretty_print) + outfile.write('</%s%s>%s' % (namespace_, name_, eol_)) + else: + outfile.write('/>%s' % (eol_, )) + def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='FixedType2'): + if self.attrfixed01 != "abcd" and 'attrfixed01' not in already_processed: + already_processed.add('attrfixed01') + outfile.write(' attrfixed01=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.attrfixed01), input_name='attrfixed01')), )) + if self.attrfixed02 != 14 and 'attrfixed02' not in already_processed: + already_processed.add('attrfixed02') + outfile.write(' attrfixed02="%s"' % self.gds_format_integer(self.attrfixed02, input_name='attrfixed02')) + if self.attrnormal01 is not None and 'attrnormal01' not in already_processed: + already_processed.add('attrnormal01') + outfile.write(' attrnormal01=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.attrnormal01), input_name='attrnormal01')), )) + if self.attrnormal02 is not None and 'attrnormal02' not in already_processed: + already_processed.add('attrnormal02') + outfile.write(' attrnormal02="%s"' % self.gds_format_integer(self.attrnormal02, input_name='attrnormal02')) + def exportChildren(self, outfile, level, namespace_='', name_='FixedType2', fromsubclass_=False, pretty_print=True): + pass + def build(self, node): + already_processed = set() + self.buildAttributes(node, node.attrib, already_processed) + for child in node: + nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] + self.buildChildren(child, node, nodeName_) + return self + def buildAttributes(self, node, attrs, already_processed): + value = find_attr_value_('attrfixed01', node) + if value is not None and 'attrfixed01' not in already_processed: + already_processed.add('attrfixed01') + self.attrfixed01 = value + value = find_attr_value_('attrfixed02', node) + if value is not None and 'attrfixed02' not in already_processed: + already_processed.add('attrfixed02') + try: + self.attrfixed02 = int(value) + except ValueError as exp: + raise_parse_error(node, 'Bad integer attribute: %s' % exp) + value = find_attr_value_('attrnormal01', node) + if value is not None and 'attrnormal01' not in already_processed: + already_processed.add('attrnormal01') + self.attrnormal01 = value + value = find_attr_value_('attrnormal02', node) + if value is not None and 'attrnormal02' not in already_processed: + already_processed.add('attrnormal02') + try: + self.attrnormal02 = int(value) + except ValueError as exp: + raise_parse_error(node, 'Bad integer attribute: %s' % exp) + def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): + pass +# end class FixedType2 + + GDSClassesMapping = { 'defaults': DefaultTypes, } @@ -1249,5 +1581,7 @@ if __name__ == '__main__': __all__ = [ "DefaultType1", "DefaultType2", - "DefaultTypes" + "DefaultTypes", + "FixedType1", + "FixedType2" ] diff --git a/tests/ipo1_out.xml b/tests/ipo1_out.xml index 44ae582b319375939713951bbf2dec8af5936cb6..efb1667b8cc9253cf5399684983b635bf37bcb53 100644 --- a/tests/ipo1_out.xml +++ b/tests/ipo1_out.xml @@ -1,6 +1,6 @@ <?xml version="1.0" ?> <ipo:purchaseOrder xmlns:ipo="http://www.example.com/IPO" orderDate="1999-12-01"> - <ipo:shipTo xmlns:ipo="http://www.example.com/IPO" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ipo:UKAddress" exportCode="1"> + <ipo:shipTo xmlns:ipo="http://www.example.com/IPO" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ipo:UKAddress"> <ipo:name>Helen Zoe</ipo:name> <ipo:street>47 Eden Street</ipo:street> <ipo:city>Cambridge</ipo:city> diff --git a/tests/ipo1_sub.py b/tests/ipo1_sub.py index f5b8efcde3eb4d9655d122e656a430de1854d791..edd498e2aa034fcdb2e943b13a5be70f65021282 100644 --- a/tests/ipo1_sub.py +++ b/tests/ipo1_sub.py @@ -83,7 +83,7 @@ supermod.USAddress.subclass = USAddressSub class UKAddressSub(supermod.UKAddress): - def __init__(self, name=None, street=None, city=None, exportCode=None, postcode=None): + def __init__(self, name=None, street=None, city=None, exportCode=1, postcode=None): super(UKAddressSub, self).__init__(name, street, city, exportCode, postcode, ) supermod.UKAddress.subclass = UKAddressSub # end class UKAddressSub diff --git a/tests/ipo1_sup.py b/tests/ipo1_sup.py index 5299bd7e544220980523d2962f9905d87c09ed51..a2121467d245a692f2e7c89e13c5eb33478da339 100644 --- a/tests/ipo1_sup.py +++ b/tests/ipo1_sup.py @@ -1379,7 +1379,7 @@ class UKAddress(Address): ] subclass = None superclass = Address - def __init__(self, name=None, street=None, city=None, exportCode=None, postcode=None): + def __init__(self, name=None, street=None, city=None, exportCode=1, postcode=None): self.original_tagname_ = None super(UKAddress, self).__init__(name, street, city, ) self.exportCode = _cast(int, exportCode) @@ -1430,7 +1430,7 @@ class UKAddress(Address): outfile.write('/>%s' % (eol_, )) def exportAttributes(self, outfile, level, already_processed, namespace_='ipo:', name_='UKAddress'): super(UKAddress, self).exportAttributes(outfile, level, already_processed, namespace_, name_='UKAddress') - if self.exportCode is not None and 'exportCode' not in already_processed: + if self.exportCode != 1 and 'exportCode' not in already_processed: already_processed.add('exportCode') outfile.write(' exportCode="%s"' % self.gds_format_integer(self.exportCode, input_name='exportCode')) def exportChildren(self, outfile, level, namespace_='ipo:', name_='UKAddress', fromsubclass_=False, pretty_print=True): diff --git a/tests/ipo2_sub.py b/tests/ipo2_sub.py index f5b8efcde3eb4d9655d122e656a430de1854d791..edd498e2aa034fcdb2e943b13a5be70f65021282 100644 --- a/tests/ipo2_sub.py +++ b/tests/ipo2_sub.py @@ -83,7 +83,7 @@ supermod.USAddress.subclass = USAddressSub class UKAddressSub(supermod.UKAddress): - def __init__(self, name=None, street=None, city=None, exportCode=None, postcode=None): + def __init__(self, name=None, street=None, city=None, exportCode=1, postcode=None): super(UKAddressSub, self).__init__(name, street, city, exportCode, postcode, ) supermod.UKAddress.subclass = UKAddressSub # end class UKAddressSub diff --git a/tests/ipo2_sup.py b/tests/ipo2_sup.py index 5299bd7e544220980523d2962f9905d87c09ed51..a2121467d245a692f2e7c89e13c5eb33478da339 100644 --- a/tests/ipo2_sup.py +++ b/tests/ipo2_sup.py @@ -1379,7 +1379,7 @@ class UKAddress(Address): ] subclass = None superclass = Address - def __init__(self, name=None, street=None, city=None, exportCode=None, postcode=None): + def __init__(self, name=None, street=None, city=None, exportCode=1, postcode=None): self.original_tagname_ = None super(UKAddress, self).__init__(name, street, city, ) self.exportCode = _cast(int, exportCode) @@ -1430,7 +1430,7 @@ class UKAddress(Address): outfile.write('/>%s' % (eol_, )) def exportAttributes(self, outfile, level, already_processed, namespace_='ipo:', name_='UKAddress'): super(UKAddress, self).exportAttributes(outfile, level, already_processed, namespace_, name_='UKAddress') - if self.exportCode is not None and 'exportCode' not in already_processed: + if self.exportCode != 1 and 'exportCode' not in already_processed: already_processed.add('exportCode') outfile.write(' exportCode="%s"' % self.gds_format_integer(self.exportCode, input_name='exportCode')) def exportChildren(self, outfile, level, namespace_='ipo:', name_='UKAddress', fromsubclass_=False, pretty_print=True): diff --git a/tutorial/generateds_tutorial.html b/tutorial/generateds_tutorial.html index 6103b5a2c25adde1aacaa7c3e677d950a9b965bf..acda9405ed83593064c4950180e5386bcb3e0a1f 100644 --- a/tutorial/generateds_tutorial.html +++ b/tutorial/generateds_tutorial.html @@ -219,7 +219,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.7</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.8</td> </tr> </tbody> </table> @@ -228,7 +228,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">date:</th><td class="field-body">February 05, 2018</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">March 02, 2018</td> </tr> </tbody> </table> @@ -1210,7 +1210,7 @@ named <tt class="docutils literal">garden_api.py</tt>, you can create an instanc <div class="footer"> <hr class="footer" /> <a class="reference external" href="generateds_tutorial.txt">View document source</a>. -Generated on: 2018-02-05 22:01 UTC. +Generated on: 2018-03-02 19:35 UTC. Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. </div> diff --git a/tutorial/generateds_tutorial.txt b/tutorial/generateds_tutorial.txt index 0601deebc6574dc6132dfe6fd12c890d7e65385f..dd4639926e94c215715ac837626799326d03e5c9 100644 --- a/tutorial/generateds_tutorial.txt +++ b/tutorial/generateds_tutorial.txt @@ -11,7 +11,7 @@ generateDS -- Introduction and Tutorial .. version -:revision: 2.29.7 +:revision: 2.29.8 .. version diff --git a/tutorial/generateds_tutorial.zip b/tutorial/generateds_tutorial.zip index 6af5372e5e0e6031da3fd616a99d1968c0f78bce..e3a54a1505c696f7798968ce6ccb75b3754e270e 100644 Binary files a/tutorial/generateds_tutorial.zip and b/tutorial/generateds_tutorial.zip differ