Dealing with non-callable classmethod objects

Cameron Simpson cs at cskk.id.au
Sat Nov 12 15:57:16 EST 2022


On 12Nov2022 10:34, Ian Pilcher <arequipeno at gmail.com> wrote:
>So I've done this.
>
>    class _HasUnboundClassMethod(object):
>        @classmethod
>        def _classmethod(cls):
>            pass  # pragma: no cover
>        _methods = [ _classmethod ]
>
>    _ClassMethodType = type(_HasUnboundClassMethod._methods[0])
>
>Which allows me to do this:
>
>    def __init__(self, d):
>        for attr, factory in self._attrs.items():
>            if callable(factory):
>                value = factory(d[attr])
>            else:
>                assert type(factory) is self._ClassMethodType
>                value = factory.__func__(type(self), d[attr])
>            setattr(self, attr, value)
>
>It's a bit cleaner, although I'm not thrilled about having a throwaway
>class, just to define a literal that ought to be provided by the
>runtime.

Ah, nice again.

You shouldn't need a throwaway class, just use the name "classmethod" 
directly - it's the type!

     if not callable(factory):
         if type(factory) is classmethod:
             # replace fctory with a function calling factory.__func__
             factory = lambda arg: factory.__func__(classmethod, arg)
         else:
             raise TypeError("unhandled factory type %s:%r" % (type(factory), factory)
     value = factory(d[attr])

Cheers,
Cameron Simpson <cs at cskk.id.au>


More information about the Python-list mailing list