Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using dataclasses with Cython

I'm using cython for code obfuscation, so performance is not an issue at the moment. The problem is with using dataclasses.

There is no error during compilation time when cythonize code that contains dataclass definitions. But when running the code, I get a TypeError: <field> is a field but has no type annotation.

Here is the code I'm trying to 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)

Running the code without cythonization works fine. But after cythonization I get the following error message:

 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

Is there any way to avoid this problem without or with minimal rewriting of the source code?

like image 673
Andrey Kite Gorin Avatar asked May 10 '19 14:05

Andrey Kite Gorin


1 Answers

Until support for this is merged into Cython, a workaround is to manually add the __annotations__ attribute to your class and repeat your type annotations:

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

    __annotations__ = {
        'label': str,
        'fields': List[Field],
    }
like image 67
cdr Avatar answered Sep 19 '22 10:09

cdr