Skip to content

[Bug]: UnboundLocalError: local variable 'value' referenced before assignment #696

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
andersk opened this issue Oct 19, 2023 · 4 comments · Fixed by #697
Closed

[Bug]: UnboundLocalError: local variable 'value' referenced before assignment #696

andersk opened this issue Oct 19, 2023 · 4 comments · Fixed by #697
Labels
kind/bug Indicates an issue

Comments

@andersk
Copy link
Contributor

andersk commented Oct 19, 2023

Actual Behavior

Traceback (most recent call last):
  File "/home/anders/python/openapi-core/test.py", line 38, in <module>
    validate_request(request, spec=spec)
  File "/home/anders/python/openapi-core/openapi_core/shortcuts.py", line 321, in validate_request
    validate_apicall_request(
  File "/home/anders/python/openapi-core/openapi_core/shortcuts.py", line 396, in validate_apicall_request
    return v.validate(request)
  File "/home/anders/python/openapi-core/openapi_core/validation/request/validators.py", line 278, in validate
    for err in self.iter_errors(request):
  File "/home/anders/python/openapi-core/openapi_core/validation/request/validators.py", line 341, in iter_errors
    yield from self._iter_errors(request, operation, path)
  File "/home/anders/python/openapi-core/openapi_core/validation/request/validators.py", line 114, in _iter_errors
    self._get_body(request.body, request.mimetype, operation)
  File "/home/anders/python/openapi-core/openapi_core/validation/decorators.py", line 31, in wrapper
    return f(*args, **kwds)
  File "/home/anders/python/openapi-core/openapi_core/validation/request/validators.py", line 260, in _get_body
    value, _ = self._get_content_and_schema(raw_body, content, mimetype)
  File "/home/anders/python/openapi-core/openapi_core/validation/validators.py", line 244, in _get_content_and_schema
    casted, schema = self._get_content_schema_value_and_schema(
  File "/home/anders/python/openapi-core/openapi_core/validation/validators.py", line 230, in _get_content_schema_value_and_schema
    deserialised = self._deserialise_media_type(
  File "/home/anders/python/openapi-core/openapi_core/validation/validators.py", line 118, in _deserialise_media_type
    return deserializer.deserialize(value)
  File "/home/anders/python/openapi-core/openapi_core/deserializing/media_types/deserializers.py", line 90, in deserialize
    return self.decode(deserialized)
  File "/home/anders/python/openapi-core/openapi_core/deserializing/media_types/deserializers.py", line 111, in decode
    properties[prop_name] = self.decode_property(
  File "/home/anders/python/openapi-core/openapi_core/deserializing/media_types/deserializers.py", line 138, in decode_property
    return self.decode_property_content_type(
  File "/home/anders/python/openapi-core/openapi_core/deserializing/media_types/deserializers.py", line 179, in decode_property_content_type
    return list(map(prop_deserializer.deserialize, value))
UnboundLocalError: local variable 'value' referenced before assignment

Expected Behavior

No error.

Steps to Reproduce

from openapi_core import Spec, validate_request
from openapi_core.testing import MockRequest

spec = Spec.from_dict(
    {
        "openapi": "3.1.0",
        "info": {"version": "0", "title": "test"},
        "paths": {
            "/test": {
                "post": {
                    "requestBody": {
                        "content": {
                            "application/x-www-form-urlencoded": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "foo": {"type": "array", "items": {"type": "string"}}
                                    },
                                },
                                "encoding": {"foo": {"contentType": "application/json"}},
                            }
                        }
                    },
                    "responses": {"200": {"description": "OK"}},
                }
            }
        },
    }
)

request = MockRequest(
    "http://localhost",
    "post",
    "/test",
    data='foo=["a","b","c"]',
    mimetype="application/x-www-form-urlencoded",
)
validate_request(request, spec=spec)

OpenAPI Core Version

current Git (0838a84)

OpenAPI Core Integration

none

Affected Area(s)

No response

References

No response

Anything else we need to know?

No response

Would you like to implement a fix?

None

@andersk
Copy link
Contributor Author

andersk commented Oct 19, 2023

Oh hmm, this might be user error? The request validates if I set "explode": False in the encoding object.

-                                "encoding": {"foo": {"contentType": "application/json"}},
+                                "encoding": {
+                                    "foo": {
+                                        "contentType": "application/json",
+                                        "explode": False,
+                                    }
+                                },

Still, UnboundLocalError is the wrong failure mode.

@p1c2u
Copy link
Collaborator

p1c2u commented Oct 20, 2023

Hi @andersk

you use invalid data serialization strategy ?

["a","b","c"]

this doesn't seem to correct json

If you want to use style serialization then you don't need "contentype" just style/explode.

You don't even need encoding object because it default serialization strategy is style form (which I forgot to implement)

When passing complex objects in the application/x-www-form-urlencoded content type, the default serialization strategy of such properties is described in the Encoding Object's style property as form.

The UnboundLocalError is related to content type serialization, I will fix that also.

Thanks for your feedback.

@andersk
Copy link
Contributor Author

andersk commented Oct 20, 2023

Huh? It is correct JSON.

Python 3.10.12 (main, Jun  6 2023, 22:43:10) [GCC 12.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> json.loads('["a","b","c"]')
['a', 'b', 'c']

Without contentType: application/json, and with the default explode: true, style: form, the parameter would be serialized as foo=a&foo=b&foo=c; with explode: false, style: form, it would be serialized as foo=a,b,c. Neither serialization is compatible with the endpoint API I need to specify (and I can’t change the API, for backwards compatibility).

@p1c2u
Copy link
Collaborator

p1c2u commented Oct 21, 2023

I get some confusion in drrialization process between those two similar examples:

application/x-www-form-urlencoded:
  schema:
    type: object
    properties:
      prop:
        type: array
        items:
          type: integer

and

multipart/form-data:
  schema:
    type: object
    properties:
      file:
        type: array
        items:
          type: string
          format: binary

I will make change . hope it will work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Indicates an issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants