Сегменты пакета Python «dpath».py дает бесконечную рекурсию при простом вызове «isinstance»

#python #recursion #swagger #isinstance #dpath

Вопрос:

Попытка использовать swagger codegen для автоматического создания клиентской библиотеки для проекта, который я выполняю для работы. По-видимому, у swagger изначально нет версии python, но они ссылаются на код, поддерживаемый сообществом swagger-py. Установил это с помощью pip, попробовал запустить репо OpenAPI в моих проектах, и я получаю ошибку «RecursionError: максимальная глубина рекурсии превышена при проверке экземпляра«.

Вот трассировка стека:

 Traceback (most recent call last):
  File "/home/user/.local/bin/swagger_py_codegen", line 8, in <module>
    sys.exit(generate())
  File "/home/user/.local/lib/python3.8/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/home/user/.local/lib/python3.8/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/home/user/.local/lib/python3.8/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/user/.local/lib/python3.8/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/home/user/.local/lib/python3.8/site-packages/swagger_py_codegen/command.py", line 200, in generate
    for code in generator.generate():
  File "/home/user/.local/lib/python3.8/site-packages/swagger_py_codegen/base.py", line 44, in generate
    for code in g:
  File "/home/user/.local/lib/python3.8/site-packages/swagger_py_codegen/base.py", line 47, in generate
    for code in self._process():
  File "/home/user/.local/lib/python3.8/site-packages/swagger_py_codegen/jsonschema.py", line 110, in _process
    yield Schema(build_data(self.swagger))
  File "/home/user/.local/lib/python3.8/site-packages/swagger_py_codegen/jsonschema.py", line 51, in build_data
    for path, _ in swagger.search(['paths', '*']):
  File "/home/user/.local/lib/python3.8/site-packages/swagger_py_codegen/parser.py", line 118, in search
    for p, d in dpath.util.search(
  File "/home/user/.local/lib/python3.8/site-packages/dpath/util.py", line 222, in yielder
    for segments, found in dpath.segments.walk(obj):
  File "/home/user/.local/lib/python3.8/site-packages/dpath/segments.py", line 73, in walk
    for found in walk(v, location   (k,)):
  File "/home/user/.local/lib/python3.8/site-packages/dpath/segments.py", line 73, in walk
    for found in walk(v, location   (k,)):
  File "/home/user/.local/lib/python3.8/site-packages/dpath/segments.py", line 73, in walk
    for found in walk(v, location   (k,)):
  [Previous line repeated 981 more times]
  File "/home/user/.local/lib/python3.8/site-packages/dpath/segments.py", line 58, in walk
    if not leaf(obj):
  File "/home/user/.local/lib/python3.8/site-packages/dpath/segments.py", line 33, in leaf
    return isinstance(thing, leaves)
RecursionError: maximum recursion depth exceeded in __instancecheck__
 

Если бы это была просто реализация на python сообщества swagger codegen, я бы понял, но это происходит в isInstance.

Похоже, что он попадает в пакет сайта dpath (не знаком с этим, возможно, его добавил swagger_py_codegen), он попадает в сегменты, а затем есть функция, которая проверяет, является ли что-то листом.

Вот соответствующий раздел из segments.py:

 def leaf(thing):
    '''
    Return True if thing is a leaf, otherwise False.

    leaf(thing) -> bool
    '''
    leaves = (bytes, str, int, float, bool, type(None))

    return isinstance(thing, leaves)
 

Я почти уверен, что isinstance-это просто часть стандартной библиотеки, так что я не могу это изменить. Но, глядя на этот листовой(вещевой) метод из dpath, я не вижу, что может быть причиной ошибки.

То, что я пробовал до сих пор:

Я попытался отредактировать segments.py чтобы увеличить максимальное количество рекурсий до 10 000. Это просто приводит к тому, что ты бежишь вечно. Я оставил его в покое на 5 минут, но он так и не был завершен.

Таким образом, это своего рода бесконечный рекурсивный цикл, но, предполагая, что isinstance верен, я ни за что на свете не могу понять, что вызывает проблему из этого простого вызова листа(вещи)

Комментарии:

1. Не ответ на ваш вопрос, но в Swagger Codegen есть встроенные генераторы клиентов Python как для OpenAPI 2.0, так и для 3.0.

2. @Хелен У меня было подозрение, что это так, но я ни за что на свете не мог его найти. Я предположил, что тот факт, что они ссылаются на версию python, созданную сообществом, указывает на то, что ее не существовало. Вы случайно не знаете, где его найти?

3. Онлайн-версия: Вставьте спецификацию OpenAPI YAML/JSON в editor.swagger.io и выберите в меню Создать клиент > python> . Версия CLI (при условии OAS3): java -jar swagger-codegen-cli-3.0.29.jar generate -l python -i ./path/to/MyAPI.yaml -o OUT_DIR . CLI JAR можно загрузить с Maven Central .

4. @Helen Мне интересно, в чем будет заключаться призыв к чему-либо, кроме онлайн-реализации. Большое вам спасибо

5. CLI полезен, если у вас есть определение API для нескольких файлов с относительными ссылками $(например $ref: '../another/file.yaml' ). Онлайн-редактор/codegen может разрешить только https:// $ссылки.