Skip to content

Commit

Permalink
Auto-detect whether we're looking at a component or schema file.
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed May 9, 2019
1 parent e60c530 commit 4e4568a
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 28 deletions.
4 changes: 4 additions & 0 deletions ZConfig/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ def __init__(self, msg, url=None, lineno=None, colno=None):
_ParseError.__init__(self, msg, url, lineno, colno)


class UnknownDocumentTypeError(SchemaError):
"Raised when the root element is unexpected."


class SchemaResourceError(SchemaError):
"""Raised when there's an error locating a resource required by the
schema.
Expand Down
26 changes: 10 additions & 16 deletions ZConfig/_schema_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,37 +309,31 @@ def _visit_default(self, name, info):


def load_schema(schema,
package=False,
package_file='component.xml',
component=True):
package=None):
"""
Load the *schema* and return the schema object.
By default, *schema* is interpreted as a path on disk to a schema
file.
If *package* is set to True, then *schema* must name a Python
package, and the file will be loaded from that package, defaulting
to the ``component.xml`` file as named by *package_file*. In this
case, a ``<schema>`` is generated that imports this component.
If *package* is set to True and *component* is set to False, then
no schema tag is added and the file must refer to an actual
schema.
If *package* is set to a true string value, then *package* must
name a Python package, and the file in *schema* will be loaded
from that package. The *schema* can either refer to a component
definition (e.g., ``components.xml``) or to a schema.
"""

if not package:
# A schema file
schema_reader = argparse.FileType('r')(schema)
return ZConfig.loader.loadSchemaFile(schema_reader)

if component:
try:
# A component in a package
schema_template = (
"<schema><import package='%s' file='%s' /></schema>"
% (schema, package_file))
% (package, schema))
from ZConfig._compat import TextIO
return ZConfig.loader.loadSchemaFile(TextIO(schema_template))

# A schema in a package
return ZConfig.loader.loadSchema('package:%s:%s' % (schema, package_file))
except ZConfig.UnknownDocumentTypeError:
# Ok, not parseable as a component. Try a simple schema.
return ZConfig.loader.loadSchema('package:%s:%s' % (package, schema))
9 changes: 6 additions & 3 deletions ZConfig/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ def startElement(self, name, attrs):
self.error("%s elements may not be nested in %s elements"
% (_srepr(name), _srepr(parent)))
elif name != self._top_level:
self.error("Unknown document type " + name)
self.error("Unknown document type " + name,
ZConfig.UnknownDocumentTypeError)

self._elem_stack.append(name)

Expand Down Expand Up @@ -465,8 +466,10 @@ def initerror(self, e):
e.url = self._locator.getSystemId()
return e

def error(self, message):
raise_with_same_tb(self.initerror(ZConfig.SchemaError(message)))
def error(self, message, kind=None):
# Can't do this as a default value because of import order
kind = kind or ZConfig.SchemaError
raise_with_same_tb(self.initerror(kind(message)))


class SchemaParser(BaseParser):
Expand Down
5 changes: 4 additions & 1 deletion ZConfig/schema2html.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ def main(argv=None):

out = args.out or sys.stdout

schema = load_schema(args.schema, args.package, args.package_file)
if args.package:
schema = load_schema(args.package_file, args.schema)
else:
schema = load_schema(args.schema)

printer_factory = HtmlSchemaPrinter
if hasattr(args, 'format') and args.format == 'xml':
Expand Down
5 changes: 1 addition & 4 deletions ZConfig/sphinx.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,12 @@ class SchemaToRstDirective(Directive):
'file': str,
'members': str,
'excluded-members': str,
'schema': bool,
}

def run(self):
schema = load_schema(
self.options.get('file', 'component.xml'),
self.arguments[0],
package=True,
package_file=self.options.get('file', 'component.xml'),
component=not self.options.get('schema')
)

members = ()
Expand Down
1 change: 0 additions & 1 deletion ZConfig/tests/test_schema2html.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ def test_parse_package_schema(self):
========
.. zconfig:: ZConfig.tests
:file: sphinx_test_schema.xml
:schema: true
"""
document = self._parse(text)
doc_text = document.astext()
Expand Down
6 changes: 3 additions & 3 deletions doc/documenting-components.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ There is one directive:
.. versionadded:: 3.2.0

Document the components found in the Python package *package-name*.
Document the components or schema found in the Python package *package-name*.

By default, the contents of ``component.xml`` will be documented.
You can specify the ``:file:`` option to choose a different file
from that package. If you wish to document a schema instead of a
set of components, add the option ``:schema: true``.
from that package. This file can refer to a schema or component
definition.

Each component will have its name, type, and default value
documented. The description of the component will be rendered as
Expand Down

0 comments on commit 4e4568a

Please sign in to comment.