print(I'm puzzled by what appears to be a bug in python3.
I want to create a class dynamically with some class methods. I seem to be able to do it like this:
import types
def class_body(ns):
ns.update({"a": lambda self, x: x - 1})
return ns
newc = types.new_class("foo", exec_body=class_body)
print(newc().a(3))
# prints 2 as expected
But I also want to create the class methods dynamically. I seem to be able to do something like:
import types
def funcs_gen(k=1):
def fn(self, a):
return a + k + self.i
return fn
def class_body(ns):
ns.update({"a": funcs_gen(k=2), "i": 5})
return ns
newc = types.new_class("foo", exec_body=class_body)
print(newc().a(1))
# prints 8 as expected
But something weird seems to happen if I try to do the same with partial functions:
import types
from functools import partial
def fn(self, a, k=1):
return a + k + self.i
def class_body(ns):
ns.update({"a": partial(fn, k=2), "i": 5})
return ns
newc = types.new_class("foo", exec_body=class_body)
print(newc().a(1))
# Unexpectedly produces: `TypeError: fn() missing 1 required positional argument: 'a'`
def fn(self, a ...->def fn(a ...partialmethodinstead for class methodspartialobjects do not implement the descriptor protocol to bind the instance as the first argument to itself. As an aside, note thattypes.new_classis a just a convienience function, you can also just usetypedirectly, which takestype(name, bases, namespace)