Given the following:
from dataclasses import dataclass
from typing import Callable
class Bar:
def bar_meth():
return [1, 2, 3]
class Foo(Bar):
@staticmethod
def foo_meth(a: int, b: int, base_func: Callable, *args):
# sample code, it doesn't really matter as I'm sure this part works
items = []
for x in range(a, b):
items.extend(base_func(args))
return items
@dataclass
class Source:
call: Callable = None
args: tuple = None
kwargs: dict = None
def run(self):
return self.call(self.args, self.kwargs)
class Binder:
def __init__(self):
self.source = Source()
def bind(self, source: Callable, *args, **kwargs):
self.source = Source(source, args, kwargs)
return self.source
def check(self):
return self.source.run()
# main.py
a = Foo()
b = Binder()
b.bind(a.foo_meth, 0, 50, a.bar_meth)
b.check()
All of this mess raises TypeError: foo_meth() missing 1 required positional argument: 'base_func'
at return self._call(self._args, self._kwargs)
.
I checked with the debugger and b.args = (arg1, arg2, <bound method Bar.bar_meth of <object and 0xAddress>>)
, so bar_meth()
should be passed correctly.
I know this looks quite convoluted but I don't know how I could improve it, so if you don't have a solution perhaps you could offer some rework suggestions.
You need to unpack self.args
and self.kwargs
when you do self.call()
in Source.run()
.
Change the function to:
def run(self):
return self.call(*self.args, **self.kwargs)
Looks like you also forgot to unpack the arguments to base_func()
inside Foo.foo_meth()
def foo_meth(a: int, b: int, base_func: Callable, *args):
# sample code, it doesn't really matter as I'm sure this part works
items = []
for x in range(a, b):
items.extend(base_func(*args)) # <<------ Unpack here too
return items
Now your MRE gives a different error --
TypeError: bar_meth() takes 0 positional arguments but 1 was given
This is because you defined Bar.bar_meth()
without any arguments, but you call it as a.bar_meth(args)
. You will need to redefine it as
class Bar:
def bar_meth(self):
return [1, 2, 3]