Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-sphinx-jsonschema for openSUSE:Factory checked in at 2024-01-15 22:16:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-sphinx-jsonschema (Old) and /work/SRC/openSUSE:Factory/.python-sphinx-jsonschema.new.21961 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-sphinx-jsonschema" Mon Jan 15 22:16:07 2024 rev:4 rq:1138556 version:1.19.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-sphinx-jsonschema/python-sphinx-jsonschema.changes 2021-04-19 21:06:53.472109595 +0200 +++ /work/SRC/openSUSE:Factory/.python-sphinx-jsonschema.new.21961/python-sphinx-jsonschema.changes 2024-01-15 22:17:11.506358204 +0100 @@ -1,0 +2,13 @@ +Sun Jan 14 10:36:35 UTC 2024 - Dirk Müller <dmuel...@suse.com> + +- update to 1.19.1: + * load a schema from a Python dict or object (or actually any + Python entity with a ``__str__`` method.). + * with JSON Pointer the ``:pass_unmodified:`` option is included. + * fixed a bug escaping backspaces. + * ``:hide_key:`` directive option. + This option allows you to hide certain keys, specified by a JSON + Path specification, to be excluded from rendering. + * added the ``:encoding:`` directive option. + +------------------------------------------------------------------- Old: ---- sphinx-jsonschema-1.16.8.tar.gz New: ---- sphinx-jsonschema-1.19.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-sphinx-jsonschema.spec ++++++ --- /var/tmp/diff_new_pack.QcjUIe/_old 2024-01-15 22:17:11.922373402 +0100 +++ /var/tmp/diff_new_pack.QcjUIe/_new 2024-01-15 22:17:11.926373549 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-sphinx-jsonschema # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,13 +18,13 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-sphinx-jsonschema -Version: 1.16.8 +Version: 1.19.1 Release: 0 Summary: Sphinx extension to display JSON Schema License: GPL-3.0-only URL: https://github.com/lnoor/sphinx-jsonschema # Tarballs from pypi.org are missing license files -Source: https://github.com/lnoor/sphinx-jsonschema/archive/refs/tags/v%{version}.tar.gz#/sphinx-jsonschema-%{version}.tar.gz +Source: https://github.com/lnoor/sphinx-jsonschema/archive/refs/tags/v.%{version}.tar.gz#/sphinx-jsonschema-%{version}.tar.gz BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros @@ -46,7 +46,7 @@ Sphinx extension to display JSON Schema. %prep -%setup -q -n sphinx-jsonschema-%{version} +%setup -q -n sphinx-jsonschema-v.%{version} %build %python_build ++++++ sphinx-jsonschema-1.16.8.tar.gz -> sphinx-jsonschema-1.19.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-jsonschema-1.16.8/.gitignore new/sphinx-jsonschema-v.1.19.1/.gitignore --- old/sphinx-jsonschema-1.16.8/.gitignore 2021-03-23 17:35:18.000000000 +0100 +++ new/sphinx-jsonschema-v.1.19.1/.gitignore 2022-05-01 14:24:48.000000000 +0200 @@ -91,3 +91,5 @@ # PyCharm .idea/ +# vscode +.code-workspace diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-jsonschema-1.16.8/README.rst new/sphinx-jsonschema-v.1.19.1/README.rst --- old/sphinx-jsonschema-1.16.8/README.rst 2021-03-23 17:35:18.000000000 +0100 +++ new/sphinx-jsonschema-v.1.19.1/README.rst 2022-05-01 14:24:48.000000000 +0200 @@ -60,15 +60,20 @@ .. jsonschema:: /home/leo/src/jsonschema/sample.json -Or a path relative to the referencing document:: +A path relative to the referencing document:: .. jsonschema:: jsonschema/sample.json +Or a schema defined in a Python object:: + + .. jsonschema:: mod.pkg.SCHEMA + With all three of the above you may add JSON Pointer notation to display a subschema:: .. jsonschema:: http://some.domain/with/a/path/spec.json#/path/to/schema .. jsonschema:: /home/leo/src/jsonschema/sample.json#/path/to/schema .. jsonschema:: jsonschema/sample.json#/path/to/schema + .. jsonschema:: mod.pkg.SCHEMA#/path/to/schema Alternatively you can embed the schema:: @@ -169,6 +174,50 @@ Changelog ========= +Version 1.19.0 +-------------- + +Glenn Nicholls <https://github.com/GlenNicholls> contributed code to load a schema from a +Python dict or object (or actually any Python entity with a ``__str__`` method.). + +Version 1.18.0 +-------------- + +Expanding on the work of `Pavel Odvody <https://github.com/shaded-enmity>`_ with JSON Pointer +the ``:pass_unmodified:`` option is included. +This option prevents escaping the string pointed at. +This extension arose from discussions with `Ryan Lane <https://github.com/ryan-lane>` + +Version 1.17.2 +-------------- + +`Ezequiel Orbe <https://github.com/eorbe>`_ found, reported and fixed a bug escaping backspaces. + +Version 1.17.0 +-------------- + +`Pavel Odvody <https://github.com/shaded-enmity>`_ contributed the ``:hide_key:`` directive option. +This option allows you to hide certain keys, specified by a JSON Path specification, to be excluded +from rendering. + + +Version 1.16.11 +--------------- + +Removed debugging code left in, pointed out by `Kevin Landreth <https://github.com/CrackerJackMack>`. + +Version 1.16.10 +--------------- + +`iamdbychkov <https://github.com/iamdbychkov>`_ added the ``:encoding:`` directive option. +This option allows explicit control of the encoding used to read a file +instead of relying on the operating system default. + +Version 1.16.9 +-------------- + +Bugfix. + Version 1.16.8 -------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-jsonschema-1.16.8/docs/conf.py new/sphinx-jsonschema-v.1.19.1/docs/conf.py --- old/sphinx-jsonschema-1.16.8/docs/conf.py 2021-03-23 17:35:18.000000000 +0100 +++ new/sphinx-jsonschema-v.1.19.1/docs/conf.py 2022-05-01 14:24:48.000000000 +0200 @@ -60,9 +60,9 @@ # built documents. # # The short X.Y version. -version = u'1.16' +version = u'1.17' # The full version, including alpha/beta/rc tags. -release = u'1.16.8' +release = u'1.17.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-jsonschema-1.16.8/docs/directive.rst new/sphinx-jsonschema-v.1.19.1/docs/directive.rst --- old/sphinx-jsonschema-1.16.8/docs/directive.rst 2021-03-23 17:35:18.000000000 +0100 +++ new/sphinx-jsonschema-v.1.19.1/docs/directive.rst 2022-05-01 14:24:48.000000000 +0200 @@ -124,6 +124,38 @@ } } +Lastly, you can use the ``jsonschema`` directive to render a schema from a Python +object: + +.. code-block:: python + :caption: ``example.py`` + + SCHEMA = { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "An example", + "id": "http://example.com/schemas/example.json", + "description": "This is just a tiny example of a schema rendered by `sphinx-jsonschema <http://github.com/lnoor/sphinx-jsonschema>`_.\n\nYes that's right you can use *reStructuredText* in a description.", + "type": "string", + "minLength": 10, + "maxLength": 100, + "pattern": "^[A-Z]+$" + } + +with the following usage of the directive: + +.. code-block:: rst + + .. jsonschema:: sphinx-jsonschema.example.SCHEMA + +which should render as: + +.. jsonschema:: sphinx-jsonschema.example.SCHEMA + +.. important:: + For rendering Python objects with the ``jsonschema`` directive, the object does not + *need* to be a dict or a string. However, the object must have a ``__str__`` method + defined that will return a valid schema. + Options ------- @@ -152,6 +184,17 @@ Automatically resolves references when possible. Works well with ``:auto_target:`` and ``:lift_definitions:``. +hide_key: (default: None) + Hide parts of the schema matching comma separated list of JSON pointers + +hide_key_if_empty: (default: None) + Hide parts of the schema matching comma separated list of JSON pointers if the value is empty + +encoding (default: None) + Allows you to define the encoding used by the file containing the json schema. + +pass_unmodified (default: None) + Allows you to prevent escaping of _, / and * characters in strings. Lift Title ++++++++++ @@ -359,7 +402,9 @@ It takes a dict as value the boolean valued keys of which have the same name as the options. So, in ``conf.py`` you can state: -.. code-block:: py + +.. code-block:: python + :caption: ``conf.py`` jsonschema_options = { 'lift_description': True, @@ -374,3 +419,65 @@ They accept an optional argument which can be one of the words ``On``, ``Off``, ``True`` or ``False``. The default value for the argument is ``True``. +Declare file encoding ++++++++++++++++++++++ +The ``:encoding:`` option allows you to define the encoding used by the file containing +the json schema. When the operating system default encoding does not produce correct +results then this option allows you to specify the encoding to use. +When omitted the operating system default is used as it always has been. But it is now +possible to explicitly declare the expected encoding using ``:encoding: utf8``. +You can use any encoding defined by Python's codecs for your platform. + +Hiding parts of the schema +++++++++++++++++++++++++++ +Sometimes we want to omit certain keys from rendering to make the table more succicnt. +This can be achieved using the ``:hide_key:`` and ``:hide_key_if_empty:`` options to hide +all matching keys or all matching keys with empty associated value, respectively. +The options accept comma separated list of JSON pointers. Matching multiple keys +is possible using the wildcard syntax ``*`` for single level matching and ``**`` for +deep matching. + +.. code-block:: rst + + .. jsonschema:: + :hide_key: /**/examples + +This example will hide all ``examples`` fields regardless of where they are located +in the schema. +If your JSON pointer contains comma you need to place it inside quotes: + +.. code-block:: rst + + .. jsonschema:: + :hide_key: /**/examples,"/**/with, comma" + +It is also possible to hide a key if their value is empty using ``:hide_key_if_empty:``. + +.. code-block:: rst + + .. jsonschema:: + :hide_key_if_empty: /**/defaults + +Prevent escaping of strings ++++++++++++++++++++++++++++ +Strings are sometimes subject to multiple evaluation passes when rendering. +This happens because `sphinx-jsonschema` renders a schema by transforming in into a table +and then recursively call on Sphinx to render the table. +To prevent unintended modifications due to this second pass some characters (such as '_' +and '*' are escaped before the second pass. + +Sometimes that doesn't work out well and you don't want to escape those characters. +The option ``:pass_unmodified:`` accepts one or more JSON pointers and prevents the strings +pointed at to be escaped. + +.. code-block:: rst + + .. jsonschema:: + :pass_unmodified: /examples/0 + + { + "examples": [ + "unescaped under_score", + "escaped under_score" + ] + } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-jsonschema-1.16.8/docs/index.rst new/sphinx-jsonschema-v.1.19.1/docs/index.rst --- old/sphinx-jsonschema-1.16.8/docs/index.rst 2021-03-23 17:35:18.000000000 +0100 +++ new/sphinx-jsonschema-v.1.19.1/docs/index.rst 2022-05-01 14:24:48.000000000 +0200 @@ -34,6 +34,49 @@ Changelog ========= +Version 1.19.0 +-------------- + +Glenn Nicholls <https://github.com/GlenNicholls> contributed code to load a schema from a +Python dict or object (or actually any Python entity with a ``__str__`` method.). + +Version 1.18.0 +-------------- + +Expanding on the work of `Pavel Odvody <https://github.com/shaded-enmity>`_ with JSON Pointer +the ``:pass_unmodified:`` option is included. +This option prevents escaping the string pointed at. +This extension arose from discussions with `Ryan Lane <https://github.com/ryan-lane>` + +Version 1.17.2 +-------------- + +`Ezequiel Orbe <https://github.com/eorbe>`_ found, reported and fixed a bug escaping backspaces. + +Version 1.17.0 +-------------- + +`Pavel Odvody <https://github.com/shaded-enmity>`_ contributed the ``:hide_key:`` directive option. +This option allows you to hide certain keys, specified by a JSON Pointer specification, to be excluded +from rendering. + +Version 1.16.11 +--------------- + +Removed debugging code left in, pointed out by `Kevin Landreth <https://github.com/CrackerJackMack>`. + +Version 1.16.10 +--------------- + +`iamdbychkov <https://github.com/iamdbychkov>`_ added the ``:encoding:`` directive option. +This option allows explicit control of the encoding used to read a file instead of +relying on the operating system default. + +Version 1.16.9 +-------------- + +Bugfix. + Version 1.16.8 -------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-jsonschema-1.16.8/setup.py new/sphinx-jsonschema-v.1.19.1/setup.py --- old/sphinx-jsonschema-1.16.8/setup.py 2021-03-23 17:35:18.000000000 +0100 +++ new/sphinx-jsonschema-v.1.19.1/setup.py 2022-05-01 14:24:48.000000000 +0200 @@ -10,7 +10,7 @@ setup( name='sphinx-jsonschema', - version='1.16.8', # don't forget: must match __init__.py::setup() return value + version='1.19.0', # don't forget: must match __init__.py::setup() return value description='Sphinx extension to display JSON Schema', long_description=long_description, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-jsonschema-1.16.8/sphinx-jsonschema/__init__.py new/sphinx-jsonschema-v.1.19.1/sphinx-jsonschema/__init__.py --- old/sphinx-jsonschema-1.16.8/sphinx-jsonschema/__init__.py 2021-03-23 17:35:18.000000000 +0100 +++ new/sphinx-jsonschema-v.1.19.1/sphinx-jsonschema/__init__.py 2022-05-01 14:24:48.000000000 +0200 @@ -13,11 +13,14 @@ :licence: GPL v3, see LICENCE for details. """ -import os.path +import csv +import importlib import json +import os +import yaml + from jsonpointer import resolve_pointer from traceback import format_exception, format_exception_only -import yaml from collections import OrderedDict from docutils import nodes, utils @@ -25,7 +28,131 @@ from docutils.parsers.rst import directives from docutils.utils import SystemMessagePropagation from docutils.utils.error_reporting import SafeString -from .wide_format import WideFormat +from .wide_format import WideFormat, NOESC + + +def pairwise(seq): + """ Iterate over pairs in a sequence """ + return zip(seq, seq[1:]) + + +def maybe_int(val): + """ Convert value to an int and return it or just return the value """ + try: + return int(val) + except: + return val + + +def json_path_validate(path): + """ Check that json path doesn't contain consecutive or trailing wildcards """ + forbidden = { + ('**', '**'), + ('**', '*'), + ('*', '**'), + ('*', '*') + } + + return set(pairwise(path)) & forbidden == set() + + +def _json_fan_out(doc, path, transform, deep=False): + """ Process */** wildcards in the path by fanning out the processing to multiple keys """ + if not path: + if isinstance(doc, list): + for r in range(len(doc)): + transform(doc, r) + return + + targets = [] + + def deeper(v): + if deep: + _json_fan_out(v, path, transform, deep) + else: + if len(path) > 1 : + _json_bind(v, path[1:], transform) + + def iterate(iterator): + for k, v in iterator: + if k == path[0]: + targets.append(path) + else: + deeper(v) + + if isinstance(doc, dict): + iterate(doc.items()) + if isinstance(doc, list): + iterate(enumerate(doc)) + + # Since transformers can mutate the original document + # we need to process them once we're done iterating + for r in targets: + _json_bind(doc, r, transform) + + +def _json_bind(doc, path, transform): + """ Bind (sub)document to a particular path """ + obj = doc + last = obj + + for idx, p in enumerate(path): + if p in ('**', '*'): + return _json_fan_out( + obj, + path[idx+1:], + transform, + deep=(p == '**') + ) + + last = obj + try: + obj = obj[p] + except (KeyError, IndexError): + return + + if path: + transform(last, path[-1]) + + +def json_path_transform(document, path, transformer): + """ Transform items in `document` conforming to `path` with a `transformer` in-place """ + + # Try to cast parts of the path as int if possible so that we can support + # paths like `/some/array/0/something` and we don't end up with TypeError + # trying to index into a list with a string '0' + parts = [maybe_int(p) for p in path.split('/')[1:]] + + if not parts or not json_path_validate(parts): + raise ValueError('Supplied JSON path is invalid') + + _json_bind(document, parts, transformer) + + +def remove(doc, key): + if key in ('*', '**'): + raise ValueError('Supplied JSON path is invalid') + del doc[key] + + +def remove_empty(doc, key): + if key in ('*', '**'): + raise ValueError('Supplied JSON path is invalid') + if not doc[key]: + del doc[key] + + +def tag_noescape(doc, key): + if isinstance(doc[key], str): + doc[key] = NOESC + doc[key] + else: + raise ValueError('"%s" does not refer to a string' % key) + + +def jsonpath_list(item): + if item: + return list(csv.reader([item])).pop() + raise ValueError('Invalid JSON path: "%s"' % item) def flag(argument): @@ -37,7 +164,9 @@ return True if value in ['off', 'false']: return False - raise ValueError('"%s" unknown, choose from "On", "True", "Off" or "False"' % argument) + raise ValueError( + '"%s" unknown, choose from "On", "True", "Off" or "False"' % argument) + class JsonSchema(Directive): optional_arguments = 1 @@ -47,12 +176,28 @@ 'lift_definitions': flag, 'auto_reference': flag, 'auto_target': flag, - 'timeout': float} + 'timeout': float, + 'encoding': directives.encoding, + 'hide_key': jsonpath_list, + 'hide_key_if_empty': jsonpath_list, + 'pass_unmodified': jsonpath_list} def run(self): try: schema, source, pointer = self.get_json_data() - format = WideFormat(self.state, self.lineno, source, self.options, self.state.document.settings.env.app) + + if self.options.get('hide_key'): + for hide_path in self.options['hide_key']: + json_path_transform(schema, hide_path, remove) + if self.options.get('hide_key_if_empty'): + for hide_path in self.options['hide_key_if_empty']: + json_path_transform(schema, hide_path, remove_empty) + if self.options.get('pass_unmodified'): + for path in self.options['pass_unmodified']: + json_path_transform(schema, path, tag_noescape) + + format = WideFormat(self.state, self.lineno, source, + self.options, self.state.document.settings.env.app) return format.run(schema, pointer) except SystemMessagePropagation as detail: return [detail.args[0]] @@ -61,15 +206,16 @@ except Exception as error: tb = error.__traceback__ # loop through all traceback points to only return the last traceback - while tb.tb_next: + while tb and tb.tb_next: tb = tb.tb_next - raise self.error(''.join(format_exception(type(error), error, tb, chain=False))) + raise self.error(''.join(format_exception( + type(error), error, tb, chain=False))) def get_json_data(self): """ Get JSON data from the directive content, from an external - file, or from a URL reference. + file, from a URL reference, or from importing a schema defined in Python. """ if self.arguments: filename, pointer = self._splitpointer(self.arguments[0]) @@ -80,9 +226,14 @@ if self.content: schema, source = self.from_content(filename) elif filename and filename.startswith('http'): + # Appears to be URL so process it as such schema, source = self.from_url(filename) - elif filename: + elif os.path.exists(self._convert_filename(filename)): + # File exists so it must be a JSON schema schema, source = self.from_file(filename) + elif filename: + # Must be a Python reference to a schema + schema, source = self.from_data(filename) else: raise self.error('"%s" directive has no content or a reference to an external file.' % self.name) @@ -91,9 +242,9 @@ schema = self.ordered_load(schema) except Exception as error: error = self.state_machine.reporter.error( - '"%s" directive encountered a the following error while parsing the data.\n %s' - % (self.name, SafeString("".join(format_exception_only(type(error), error)))), - nodes.literal_block(schema, schema), line=self.lineno) + '"%s" directive encountered a the following error while parsing the data.\n %s' + % (self.name, SafeString("".join(format_exception_only(type(error), error)))), + nodes.literal_block(schema, schema), line=self.lineno) raise SystemMessagePropagation(error) if pointer: @@ -137,35 +288,70 @@ response = requests.get(url, timeout=timeout) except requests.exceptions.RequestException as e: raise self.error(u'"%s" directive recieved an "%s" when loading from url: %s.' - % (self.name, type(e), url)) + % (self.name, type(e), url)) if response.status_code != 200: # When making a connection to the url a status code will be returned # Normally a OK (200) response would we be returned all other responses # an error will be raised could be separated futher raise self.error(u'"%s" directive received an "%s" when loading from url: %s.' - % (self.name, response.reason, url)) + % (self.name, response.reason, url)) # response content always binary converting with decode() no specific format defined data = response.content.decode() return data, url - def from_file(self, filename): + def _convert_filename(self, filename): + """ + Join the filename with the docs' source if it is not absolute. + """ + if os.path.isabs(filename): + return filename + # file relative to the path of the current rst file document_source = os.path.dirname(self.state.document.current_source) - if not os.path.isabs(filename): - # file relative to the path of the current rst file - source = os.path.join(document_source, filename) - else: - source = filename + return os.path.join(document_source, filename) + def from_file(self, filename): + source = self._convert_filename(filename) try: - with open(source) as file: + with open(source, encoding=self.options.get('encoding')) as file: data = file.read() except IOError as error: raise self.error(u'"%s" directive encountered an IOError while loading file: %s\n%s' - % (self.name, source, error)) + % (self.name, source, error)) + + # Simplifing source path and to the document a new dependency + document_source = os.path.dirname(self.state.document.current_source) + source = utils.relative_path(document_source, source) + self.state.document.settings.record_dependencies.add(source) + + return data, source + + def from_data(self, filename): + """Get schema from Python data/object.""" + document_source = os.path.dirname(self.state.document.current_source) + + parts = filename.split('.') + if len(parts) > 1: + module_name = '.'.join(parts[:-1]) + obj_name = parts[-1] + else: + raise self.error( + f"{self.name} directive requires a Python reference to a schema object" + f" like 'mod.pkg.data'. '{filename}' is not valid." + ) + + try: + mod = importlib.import_module(module_name) + data = str(getattr(mod, obj_name)) + except (ImportError, ModuleNotFoundError) as error: + raise self.error( + f"{self.name} directive encountered an error while importing python" + f" module '{module_name}': \n{error}" + ) # Simplifing source path and to the document a new dependency + source = mod.__file__ source = utils.relative_path(document_source, source) self.state.document.settings.record_dependencies.add(source) @@ -193,8 +379,8 @@ yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, construct_mapping) - text = text.replace('\\(', '\\\\(') - text = text.replace('\\)', '\\\\)') + text = text.replace(r'\\(', r'\\\\(') + text = text.replace(r'\\)', r'\\\\)') try: result = yaml.load(text, OrderedLoader) except yaml.scanner.ScannerError: @@ -206,4 +392,7 @@ def setup(app): app.add_directive('jsonschema', JsonSchema) app.add_config_value('jsonschema_options', {}, 'env') - return {'version': '1.16.8'} + return { + 'parallel_read_safe': True, + 'version': '1.19.0' + } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-jsonschema-1.16.8/sphinx-jsonschema/example.py new/sphinx-jsonschema-v.1.19.1/sphinx-jsonschema/example.py --- old/sphinx-jsonschema-1.16.8/sphinx-jsonschema/example.py 1970-01-01 01:00:00.000000000 +0100 +++ new/sphinx-jsonschema-v.1.19.1/sphinx-jsonschema/example.py 2022-05-01 14:24:48.000000000 +0200 @@ -0,0 +1,10 @@ +SCHEMA = { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "An example", + "id": "http://example.com/schemas/example.json", + "description": "This is just a tiny example of a schema rendered by `sphinx-jsonschema <http://github.com/lnoor/sphinx-jsonschema>`_.\n\nYes that's right you can use *reStructuredText* in a description.", + "type": "string", + "minLength": 10, + "maxLength": 100, + "pattern": "^[A-Z]+$" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-jsonschema-1.16.8/sphinx-jsonschema/wide_format.py new/sphinx-jsonschema-v.1.19.1/sphinx-jsonschema/wide_format.py --- old/sphinx-jsonschema-1.16.8/sphinx-jsonschema/wide_format.py 2021-03-23 17:35:18.000000000 +0100 +++ new/sphinx-jsonschema-v.1.19.1/sphinx-jsonschema/wide_format.py 2022-05-01 14:24:48.000000000 +0200 @@ -22,6 +22,7 @@ else: str_unicode = str +NOESC = ':noesc:' # prefix marker to indicate string must not be escaped. class WideFormat(object): KV_SIMPLE = [ @@ -211,10 +212,12 @@ rows = [] self.nesting += 1 - if 'definitions' in schema and self.options['lift_definitions']: - definitions = self._definitions(schema) - else: - definitions = None + definitions = [] + if self.options['lift_definitions']: + if '$defs' in schema: + definitions = self._definitions(schema, '$defs') + elif 'definitions' in schema: + definitions = self._definitions(schema, 'definitions') if 'type' in schema: # select processor for type @@ -234,6 +237,7 @@ # definitions aren't really type equiv's but still best place for them rows.extend(self._objectproperties(schema, 'definitions')) + rows.extend(self._objectproperties(schema, '$defs')) if label is not None: # prepend label column if required @@ -334,9 +338,9 @@ del schema[key] return rows - def _definitions(self, schema): + def _definitions(self, schema, defs_key): target = {} - for name, item in schema['definitions'].items(): + for name, item in schema[defs_key].items(): # add title by the name of the object if title not defined if 'title' not in item: item['title'] = name @@ -353,10 +357,13 @@ result = [] - for name, item in schema['definitions'].items(): - result.extend(self.run(item, '/definitions/' + name)) + for name, item in schema[defs_key].items(): + new_target = '/{defs_key}/{name}'.format( + defs_key=defs_key, name=name + ) + result.extend(self.run(item, new_target)) - del schema['definitions'] + del schema[defs_key] return result def _complexstructures(self, schema): @@ -410,27 +417,32 @@ label, self._cell(str_unicode(', '.join(obj))))) else: - import pdb; pdb.set_trace() rows.extend(self._dispatch(obj, label)[0]) del schema[key] return rows + def _get_defined_reference(self, schema, key): + target = '#/{defs}/'.format(defs=key) + if schema['$ref'].startswith(target): + reference = [r for r in schema['$ref'][2:].split('/') if r != key] + return len(reference), reference[-1] + def _reference(self, schema): if self.options['auto_reference'] and self.options['lift_title']: # first check if references is to own schema # when definitions is separated automated they will be linked to the title # otherwise it will only be a string + reference = ( + self._get_defined_reference(schema, 'definitions') or + self._get_defined_reference(schema, '$defs') + ) if schema['$ref'] == '#' or schema['$ref'] == '#/': if self.ref_titles.get(0, False): row = (self._line(self._cell('`' + self.ref_titles[0] + '`_'))) else: row = (self._line(self._cell(schema['$ref']))) - elif schema['$ref'].startswith("#/definitions/"): - reference = schema['$ref'][2:].split('/') - # removing definitions from list otherwise nesting level will be to deep - reference = [v for v in reference if v != "definitions"] - target_name = reference[-1] - ref_length = len(reference) + elif reference: + ref_length, target_name = reference # Check if there are definitions available to make a reference if (self.ref_titles.get(ref_length, False) and target_name in self.ref_titles[ref_length]): @@ -620,6 +632,8 @@ return Path(path).name def _escape(self, text): + if text.startswith(NOESC): + return text[len(NOESC):] text = text.replace('\\', '\\\\') text = text.replace('_', '\\_') text = text.replace('*', '\\*')