Использование классов данных с Cython

Я использую cython для обфускации кода, поэтому производительность сейчас не проблема. Проблема заключается в использовании классов данных.

Во время компиляции при cythonize коде, содержащем определения классов данных, нет ошибок. Но при запуске кода я получаю TypeError: <field> is a field but has no type annotation.

Вот код, который я пытаюсь cythonize:

from dataclasses import dataclass, field
from typing import Dict, Any, List

@dataclass
class dataclass_test:
    ddict: Dict[str, Any]
    sstr: str
    bbool: bool
    llist: List[str]
    ffloat: float
    llist1: List[str] = field(default_factory=list)

Запуск кода без cythonization работает нормально. Но после cythonization я получаю следующее сообщение об ошибке:

 File "dataclass_.py", line 4, in init dataclass_
    @dataclass   File "/home/aryskin/miniconda3/envs/tf113_gpu_conda/lib/python3.7/dataclasses.py", line 991, in dataclass
    return wrap(_cls)   File "/home/aryskin/miniconda3/envs/tf113_gpu_conda/lib/python3.7/dataclasses.py", line 983, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)   File "/home/aryskin/miniconda3/envs/tf113_gpu_conda/lib/python3.7/dataclasses.py", line 857, in _process_class
    raise TypeError(f'{name!r} is a field but has no type annotation') TypeError: 'llist1' is a field but has no type annotation

Есть ли способ избежать этой проблемы без или с минимальным переписыванием исходного кода?


person Andrey Kite Gorin    schedule 10.05.2019    source источник
comment
В долгосрочной перспективе лучше всего отправить отчет об ошибке. Cython предполагается совместим с Python (с некоторыми небольшими ограничениями), поэтому я думаю, что это должно быть исправлено.   -  person DavidW    schedule 10.05.2019
comment
несколько связано: github.com/cython/cython/issues/2903. В некоторых областях Cython еще не догнал Python3.7.   -  person ead    schedule 10.05.2019


Ответы (1)


Пока поддержка этого не будет объединена с Cython, можно вручную добавить атрибут __annotations__ к вашему классу и повторить аннотации вашего типа:

@dataclass
class Fieldset:
    label: str
    fields: List[Field] = []

    __annotations__ = {
        'label': str,
        'fields': List[Field],
    }
person cdr    schedule 29.05.2020
comment
На данный момент это действительно работает, хотя и возвращает шаблон, который должен удалить класс данных. Думаю, нам просто нужно, чтобы класс данных поддерживался в Cython. а пока, спасибо @cdr - person Salvatore Cosentino; 10.02.2021
comment
@SalvatoreCosentino Я полагаю, что теперь они поддерживаются в текущей основной ветке (хотя я не думаю, что это еще не превратилось в релиз). - person DavidW; 10.02.2021