Skip to content
This repository has been archived by the owner on Apr 29, 2023. It is now read-only.

Commit

Permalink
fix #6: SF/192: non-global complex types permit names
Browse files Browse the repository at this point in the history
Be aware this impacts generated code: in the past these invalid names
were used for the corresponding classes in the generated bindings.  Now
those classes are CTD_ANON instances.
  • Loading branch information
pabigot committed Jun 6, 2014
1 parent 7fda74b commit 6acc22b
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 10 deletions.
25 changes: 18 additions & 7 deletions pyxb/xmlschema/structures.py
Expand Up @@ -107,7 +107,7 @@ def _clearNamespaceContext (self):
__PrivateTransient.add('ownedComponent')

def _scope (self):
"""The context into which declarations in or subordinate to this nodeare placed."""
"""The context into which declarations in or subordinate to this node are placed."""
return self.__scope
__scope = None

Expand Down Expand Up @@ -1044,7 +1044,8 @@ def scope (self):
Valid values are SCOPE_global, or a complex type definition.
A value of None means a non-global declaration that is not
owned by a complex type definition. These can only appear in
attribute group definitions or model group definitions.
attribute group definitions, model group definitions, and element
declarations.
@todo: For declarations in named model groups (viz., local
elements that aren't references), the scope needs to be set by
Expand Down Expand Up @@ -1593,6 +1594,13 @@ def CreateFromDOM (cls, node, **kw):
kw.pop('node', None)
kw['owner'] = rv

# Global EDs should be given indeterminate scope to ensure subordinate
# declarations are not inappropriately associated with the element's
# namespace. If the ED is within a non-global scope that scope should
# be retained.
if rv._scopeIsGlobal():
kw['scope'] = _ScopedDeclaration_mixin.XSCOPE_indeterminate

identity_constraints = []
for cn in node.childNodes:
if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'key', 'unique', 'keyref'):
Expand Down Expand Up @@ -2033,15 +2041,18 @@ def CreateFromDOM (cls, node, **kw):

rv = cls(name=name, node=node, derivation_method=None, **kw)

if name is None:
assert not isinstance(rv.owner(), Schema)

# Most of the time, the scope will be global. It can be something
# else only if this is an anonymous CTD (created within an element
# declaration which itself may be global, in a containing CTD, or in a
# model group).
if not (rv._scopeIsGlobal() or rv.isAnonymous()):
raise pyxb.LogicError('Attempt to create non-global complex type definition')
if rv._scopeIsGlobal():
assert isinstance(rv.owner(), Schema)
if rv.isAnonymous():
raise pyxb.SchemaValidationError("Anonymous complex type at schema top level")
else:
assert not isinstance(rv.owner(), Schema)
if not rv.isAnonymous():
raise pyxb.SchemaValidationError('Name attribute invalid on non-global complex types: %s' % (rv.expandedName(),))

kw.pop('node', None)
kw['owner'] = rv
Expand Down
60 changes: 60 additions & 0 deletions tests/trac/test-issue-0006.py
@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
import logging
if __name__ == '__main__':
logging.basicConfig()
_log = logging.getLogger(__name__)
# Undeclared XML namespace
import pyxb.binding.generate
import pyxb.binding.datatypes as xs
import pyxb.utils.domutils
from xml.dom import Node

import os.path


import unittest

class TestIssue0006 (unittest.TestCase):

local_xsd = '''<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ce">
<xs:complexType name="cet">
<xs:sequence>
<xs:element name="s" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
'''

top_xsd = '''<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="cet">
<xs:sequence>
<xs:element name="s" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
'''

def testNamedLocal (self):
with self.assertRaises(pyxb.SchemaValidationError) as cm:
code = pyxb.binding.generate.GeneratePython(schema_text=self.local_xsd)
e = cm.exception

def testUnnamedLocal (self):
fixed = self.local_xsd.replace('name="cet"', '')
code = pyxb.binding.generate.GeneratePython(schema_text=fixed)

def testNamedTop (self):
code = pyxb.binding.generate.GeneratePython(schema_text=self.top_xsd)

def testUnnamedTop (self):
broken = self.top_xsd.replace('name="cet"', '')
with self.assertRaises(pyxb.SchemaValidationError) as cm:
code = pyxb.binding.generate.GeneratePython(schema_text=broken)
e = cm.exception

if __name__ == '__main__':
unittest.main()
2 changes: 1 addition & 1 deletion tests/trac/test-trac-0117.py
Expand Up @@ -19,7 +19,7 @@
</xs:restriction>
</xs:simpleType>
<xs:element name="Element">
<xs:complexType name="tElement">
<xs:complexType>
<xs:attribute name="attr" type="tABCD"/>
<xs:attribute name="Required" type="xs:string" use="required"/>
</xs:complexType>
Expand Down
2 changes: 1 addition & 1 deletion tests/trac/test-trac-0122.py
Expand Up @@ -11,7 +11,7 @@
xsd='''<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="Element">
<complexType name="tElement">
<complexType>
<attribute name="Required" type="string" use="required"/>
<attribute name="Optional" type="string" use="optional"/>
<attribute name="Prohibited" type="string" use="prohibited"/>
Expand Down
2 changes: 1 addition & 1 deletion tests/trac/test-trac-0126.py
Expand Up @@ -12,7 +12,7 @@
xsd='''<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="Element">
<complexType name="tElement">
<complexType>
<attribute name="Required" type="string" use="required"/>
<attribute name="Optional" type="string" use="optional"/>
</complexType>
Expand Down

0 comments on commit 6acc22b

Please sign in to comment.