ocpp icon indicating copy to clipboard operation
ocpp copied to clipboard

As of `jsonschemas>=4.18.0`, loading certain schemas fails with `_WrappedReferencingError`

Open OrangeTux opened this issue 2 years ago • 0 comments

This library doesn't anymore with of jsonschema 4.18 and higher. This version changes the way references are resolved. Apparently, not all schemas include correct references and raise an error.

Steps to reproduce with Python 3.8 or above:

  1. poetry update [email protected]
  2. poetry run pytest

Thanks @rasaffie for noticing.

self = Draft4Validator(schema={'$ref': '#definitions...ngStationType'}, format_checker=None), ref = '#definitions/ChargingStationType'
instance = {'firmwareVersion': '#1:3.4.0-2990#N:217H;1.0-223', 'model': 'ICU Eve Mini', 'vendorName': 'ICU Eve Mini'}

    def _validate_reference(self, ref, instance):
        if self._ref_resolver is None:
            try:
>               resolved = self._resolver.lookup(ref)

.venv/lib/python3.10/site-packages/jsonschema/validators.py:432:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.10/site-packages/referencing/_core.py:597: in lookup
    retrieved = retrieved.registry.anchor(uri, fragment)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <Registry (21 resources, 1 uncrawled)>, uri = '', name = 'definitions/ChargingStationType'

    def anchor(self, uri: URI, name: str):
        """
        Retrieve a given anchor from a resource which must already be crawled.
        """
        value = self._anchors.get((uri, name))
        if value is not None:
            return Retrieved(value=value, registry=self)

        registry = self.crawl()
        value = registry._anchors.get((uri, name))
        if value is not None:
            return Retrieved(value=value, registry=registry)

        resource = self[uri]
        canonical_uri = resource.id()
        if canonical_uri is not None:
            value = registry._anchors.get((canonical_uri, name))
            if value is not None:
                return Retrieved(value=value, registry=registry)

        if "/" in name:
>           raise exceptions.InvalidAnchor(
                ref=uri,
                resource=resource,
                anchor=name,
            )
E           referencing.exceptions.InvalidAnchor: '#definitions/ChargingStationType' is not a valid anchor, neither as a plain name anchor nor as a JSON Pointer. You may have intended to use '#/definitions/ChargingStationType', as the slash is required *before each segment* of a JSON pointer.

.venv/lib/python3.10/site-packages/referencing/_core.py:385: InvalidAnchor

During handling of the above exception, another exception occurred:

base_central_system = <ocpp.v20.ChargePoint object at 0x7f66cb4519f0>
boot_notification_call = '[2,"1","BootNotification",{"reason":"PowerUp","chargingStation":{"vendorName":"ICU Eve Mini","firmwareVersion":"#1:3.4.0-2990#N:217H;1.0-223","model":"ICU Eve Mini"}}]'

    @pytest.mark.asyncio
    async def test_route_message_with_existing_route(
        base_central_system, boot_notification_call
    ):
        """Test if the correct handler is called when routing a message.
        Also test if payload of request is injected correctly in handler.

        """

        @on("BootNotification")
        def on_boot_notification(reason, charging_station, **kwargs):
            assert reason == "PowerUp"
            assert charging_station == {
                "vendor_name": "ICU Eve Mini",
                "firmware_version": "#1:3.4.0-2990#N:217H;1.0-223",
                "model": "ICU Eve Mini",
            }

            return call_result.BootNotificationPayload(
                current_time="2018-05-29T17:37:05.495259",
                interval=350,
                status="Accepted",
            )

        @after("BootNotification")
        def after_boot_notification(reason, charging_station, **kwargs):
            assert reason == "PowerUp"
            assert charging_station == {
                "vendor_name": "ICU Eve Mini",
                "firmware_version": "#1:3.4.0-2990#N:217H;1.0-223",
                "model": "ICU Eve Mini",
            }

        setattr(base_central_system, "on_boot_notification", on_boot_notification)
        setattr(base_central_system, "after_boot_notification", after_boot_notification)
        base_central_system.route_map = create_route_map(base_central_system)

>       await base_central_system.route_message(boot_notification_call)

tests/v20/test_v20_charge_point.py:46:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
ocpp/charge_point.py:153: in route_message
    await self._handle_call(msg)
ocpp/charge_point.py:181: in _handle_call
    validate_payload(msg, self._ocpp_version)
ocpp/messages.py:226: in validate_payload
    validator.validate(message.payload)
.venv/lib/python3.10/site-packages/jsonschema/validators.py:420: in validate
    for error in self.iter_errors(*args, **kwargs):
.venv/lib/python3.10/site-packages/jsonschema/validators.py:354: in iter_errors
    for error in errors:
.venv/lib/python3.10/site-packages/jsonschema/_validators.py:305: in properties
    yield from validator.descend(
.venv/lib/python3.10/site-packages/jsonschema/validators.py:402: in descend
    for error in errors:
.venv/lib/python3.10/site-packages/jsonschema/_validators.py:284: in ref
    yield from validator._validate_reference(ref=ref, instance=instance)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = Draft4Validator(schema={'$ref': '#definitions...ngStationType'}, format_checker=None), ref = '#definitions/ChargingStationType'
instance = {'firmwareVersion': '#1:3.4.0-2990#N:217H;1.0-223', 'model': 'ICU Eve Mini', 'vendorName': 'ICU Eve Mini'}

    def _validate_reference(self, ref, instance):
        if self._ref_resolver is None:
            try:
                resolved = self._resolver.lookup(ref)
            except referencing.exceptions.Unresolvable as err:
>               raise exceptions._WrappedReferencingError(err)
E               jsonschema.exceptions._WrappedReferencingError: InvalidAnchor: '#definitions/ChargingStationType' is not a valid anchor, neither as a plain name anchor nor as a JSON Pointer. You may have intended to use '#/definitions/ChargingStationType', as the slash is required *before each segment* of a JSON pointer.

.venv/lib/python3.10/site-packages/jsonschema/validators.py:434: _WrappedReferencingError

OrangeTux avatar Sep 26 '23 16:09 OrangeTux