datamodel-code-generator icon indicating copy to clipboard operation
datamodel-code-generator copied to clipboard

RecursionError: maximum recursion depth exceeded while calling a Python object

Open eifinger opened this issue 2 years ago • 6 comments

Describe the bug Trying to create code from an OpenAPI spec fails with a RecursionError.

To Reproduce

Example schema:

https://developer.here.com/documentation/routing-api/swagger/v8.yaml

Used commandline:

$ datamodel-codegen --url https://developer.here.com/documentation/routing-api/swagger/v8.yaml --input-file-type openapi --output result_model.py

Expected behavior No RecursionError

Version:

  • OS: Ubuntu 22.04
  • Python version: 3.8
  • datamodel-code-generator version: 0.13.0

Additional context

Not sure if the OpenAPI is defect or this package.

Traceback (most recent call last):
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/__main__.py", line 541, in main
    generate(
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/__init__.py", line 367, in generate
    results = parser.parse()
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/base.py", line 449, in parse
    self.parse_raw()
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/openapi.py", line 393, in parse_raw
    self.parse_raw_obj(
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/jsonschema.py", line 1149, in parse_raw_obj
    self.parse_obj(name, JsonSchemaObject.parse_obj(raw), path)
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/jsonschema.py", line 1164, in parse_obj
    self.parse_object(name, obj, path)
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/jsonschema.py", line 599, in parse_object
    fields=self.parse_object_fields(
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/jsonschema.py", line 545, in parse_object_fields
    field_type = self.parse_item(modular_name, field, [*path, field_name])
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/jsonschema.py", line 645, in parse_item
    return self.parse_array_fields(
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/jsonschema.py", line 753, in parse_array_fields
    data_types=self.parse_list_item(
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/jsonschema.py", line 720, in parse_list_item
    return [
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/jsonschema.py", line 721, in <listcomp>
    self.parse_item(
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/jsonschema.py", line 639, in parse_item
    return self.get_ref_data_type(item.ref)
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/parser/jsonschema.py", line 436, in get_ref_data_type
    return self.data_type(reference=reference)
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/types.py", line 209, in __init__
    super().__init__(**values)
  File "/home/eifinger/.cache/pypoetry/virtualenvs/here-routing-cgjRCcGK-py3.8/lib/python3.8/site-packages/datamodel_code_generator/reference.py", line 45, in __init__
    super().__init__(**values)
  File "pydantic/main.py", line 339, in pydantic.main.BaseModel.__init__
  File "pydantic/main.py", line 1038, in pydantic.main.validate_model
  File "pydantic/fields.py", line 857, in pydantic.fields.ModelField.validate
  File "pydantic/fields.py", line 1074, in pydantic.fields.ModelField._validate_singleton
  File "pydantic/fields.py", line 1121, in pydantic.fields.ModelField._apply_validators
  File "pydantic/class_validators.py", line 313, in pydantic.class_validators._generic_validator_basic.lambda12
  File "pydantic/main.py", line 679, in pydantic.main.BaseModel.validate
  File "pydantic/main.py", line 605, in pydantic.main.BaseModel._copy_and_set_values
  File "/usr/lib/python3.8/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/usr/lib/python3.8/copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/usr/lib/python3.8/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/usr/lib/python3.8/copy.py", line 270, in _reconstruct
    state = deepcopy(state, memo)
  File "/usr/lib/python3.8/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/usr/lib/python3.8/copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/usr/lib/python3.8/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/usr/lib/python3.8/copy.py", line 205, in _deepcopy_list
    append(deepcopy(a, memo))
  File "/usr/lib/python3.8/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
...
RecursionError: maximum recursion depth exceeded while calling a Python object

eifinger avatar Jul 15 '22 13:07 eifinger

I literally just started getting the same error as well, and my OpenAPI definition hasn't changed. My virtual environment got deleted (oops), so I'm not sure what version was working before, but I think this was a regression after a recent update to the library.

MaJaHa95 avatar Jul 15 '22 19:07 MaJaHa95

After some testing, I found that the issue (for my OpenAPI definition) does not reproduce using 0.11.11, but does in 0.11.12.

I haven't looked too deeply into the code, but based just on the name, I see #505 changed the way recursive models were processed, and it was included in 0.11.12. So I'd guess there was something about that, which caused the issue.

Funny we both happened to come across this error on the same day, if it's truly been in there for nearly a year 😅

Although for what it's worth, I'm getting a different error on 0.11.11, so I do think that's the secret to this one, but I can't confirm whether 0.11.11 is an appropriate alternative, at least for my file. ~~I haven't started troubleshooting the other error, so I'm not sure yet whether it's a bug with this library or not.~~ Edit: looks like 0.11.11 works for me, if I downgrade to black==19.10b0, which is the minimum listed in the requirements for datamodel-code-generator (there's no maximum). So that's fair enough.

MaJaHa95 avatar Jul 15 '22 20:07 MaJaHa95

If it helps, we got that error a month back as we were missing an upper bound to pydantic. There might be some misalignment with higher versions.

In our case, we were able to solve it by fixing the project's pydantic version to pydantic[email]==1.8.2

pmbrull avatar Jul 20 '22 04:07 pmbrull

@pmbrull thank you doing that, pinning markupsafe==2.0.1 and following the fix from this link helped: https://github.com/koxudaxi/fastapi-code-generator/issues/232#issuecomment-1059146715

eifinger avatar Jul 20 '22 11:07 eifinger

We were able to get around it by adding pydantic[email]==1.9.0, combined with datamodel-code-generator==0.13.0. Not sure that helps ;)

pdodds avatar Jul 31 '22 16:07 pdodds

Also encountered this problem.

It seems like pydantic 1.9.1 added deepcopy to model validation:

Config.copy_on_model_validation does a deep copy and not a shallow one, https://github.com/samuelcolvin/pydantic/issues/3641 by @PrettyWood

(from the release notes)

This isn't apparent in the datamodel-code-generator project because it's currently locked on Pydantic 1.9.0.

The fix seems simple enough, hopefully I can a get a PR in today.

eyal-mor avatar Aug 10 '22 11:08 eyal-mor

Thank you for your reports. I think the problem is fixed.

koxudaxi avatar Dec 26 '22 16:12 koxudaxi