I found this weird behaviour where I don't know if I am the problem or if this is a python / dataclass / callable bug.
Here is a minimal working example
from dataclasses import dataclass
from typing import Callable
import numpy as np
def my_dummy_callable(my_array, my_bool):
return 1.0
@dataclass()
class MyDataClassDummy:
my_data: int = 1
my_callable: Callable[[np.ndarray, bool], float] = my_dummy_callable
def __init__(self):
print("I initialized my Class!")
@classmethod
def my_factory_with_callable_setting(cls):
my_dummy = MyDataClassDummy()
my_dummy.my_callable = my_dummy_callable
return my_dummy
@classmethod
def my_factory_without_callable_setting(cls):
my_dummy = MyDataClassDummy()
return my_dummy
def do_something(self):
print("This is my data", self.my_data)
print("This is the name of my callable", str(self.my_callable))
return self.my_callable(np.empty(shape=(42, 42)), True) + self.my_data
@dataclass()
class MySecondDataClassDummy:
my_data: int = 4
my_callable: Callable[[np.ndarray, bool], float] = my_dummy_callable
@classmethod
def my_factory(cls):
my_dummy = MySecondDataClassDummy()
return my_dummy
def do_something(self):
print("This is my data", self.my_data)
print("This is the name of my callable", str(self.my_callable))
return self.my_callable(np.empty(shape=(42, 42)), True) - self.my_data
if __name__ == '__main__':
# this works
my_first_dummy = MyDataClassDummy.my_factory_with_callable_setting()
my_first_dummy.do_something()
# this also works
my_second_dummy = MySecondDataClassDummy.my_factory()
my_second_dummy.do_something()
# this does not work
my_other_dummy = MyDataClassDummy.my_factory_without_callable_setting()
my_other_dummy.do_something()
case1: initialize with factory, initialize with my own init and then set the callable explicitly after initialization (allthough there is a default value) - works
case2: initialize with factory but don't explicitly code the init() myself - works
case3: initialize with factory, initialize with my own init and not set the callable explicitly after initialization (because this is why I have default values, isn't it?!) - doesn't work but throws the error:
Traceback (most recent call last):
File "my_path/dataclass_dummy.py", line 63, in <module>
my_other_dummy.do_something()
File "my_path/dataclass_dummy.py", line 33, in do_something
return self.my_callable(np.empty(shape=(42, 42)), True) + self.my_data
TypeError: my_dummy_callable() takes 2 positional arguments but 3 were given
So now I am wondering, what I am doing wrong in the third case.
I am using Python 3.8 and numpy 1.20.2
@dataclassand not@dataclass()if no arguments are passed to the decorator, as in your case you are not passing any arguments to it. It looks nicer without the parentheses. Just saying.