Rahul
Rahul

Reputation: 1021

Is cython compatible with typing.NamedTuple?

I have the following code in file temp.py

from typing import NamedTuple

class C(NamedTuple):
    a: int
    b: int

c = C(1, 2)

I compile it using the command:

cythonize -3 -i temp.py

and run it using the command

python3 -c 'import temp'

I get the following exception:

Traceback (most recent call last):   File "<string>", line 1, in <module>   File "temp.py", line 7, in init temp
    c = C(1, 2) TypeError: __new__() takes 1 positional argument but 3 were given

Version of python: 3.6.15

Version of cython: 0.29.14

Is there anything wrong in the above code/build steps ?

Upvotes: 0

Views: 378

Answers (2)

Ahmed AEK
Ahmed AEK

Reputation: 17616

in short, NO, it is not compatible. Edit: not currently compatible.

named tuples is just python magic (creating classes at runtime), cython doesn't know about it, so you have to execute that code by calling the interpreter at runtime, using exec.

# temp.pyx

temp_global = {}

exec("""
from typing import NamedTuple


class C(NamedTuple):
    a: int
    b: int   
""",temp_global)

C = temp_global['C']
c = C(1,2)
print(c)

to test it

import pyximport
pyximport.install()
import temp

this ends up being some python code that's being executed whenever you import your binary, the entire file is being passed to exec whenever you import it, so it's not really "Cython Code", you can just write it as a python .py file and avoid cython, or just implement your "Cython class" without relying on python magic. (no named tuples or dynamic code that is created at runtime)

Upvotes: 0

DavidW
DavidW

Reputation: 30915

It'll work in the current Cython 3 alpha version (and later). It won't work in Cython 0.29.x (you're using a pretty outdated version of this, but that won't affect this feature).

It requires classes to have an __annotations__ dictionary, which is a feature that was added in the Cython 3 alpha releases.

You won't get much/any speed advantage from compiling this is Cython though - it'll still generate a normal Python class. But it will work.

Upvotes: 1

Related Questions