Call staticmethod from class body

class A:
    @staticmethod
    def f():
        return 1

    x = f()

Fails: TypeError: 'staticmethod' object is not callable
(However mypy does not complain.)

Some suggest the solution is:

class A:
    @staticmethod
    def f() -> int:
        return 1

    x = f.__func__()

Works.
But now mypy complains: "Callable[[], int]" has no attribute "__func__".

I also tried other variations with A.f, classmethod, self.f but none of them seemed to work either.

Is there a recommended / better approach to doing something like this?

See the docs for staticmethod:

https://docs.python.org/3/library/functions.html#staticmethod

Prior to Python 3.10, staticmethods are not directly callable from inside the class. So you can try upgrading to 3.10.

If you cannot upgrade to 3.10, you can try to use this instead of staticmethod:

class callable_staticmethod(staticmethod):
    """Callable version of staticmethod."""
    def __call__(self, *args, **kwargs):
        return self.__func__(*args, **kwargs)

The wrong results with mypy should be reported to the mypy project as bugs, or at least queried there in case they have some good reason why they aren’t bugs.

2 Likes

Thanks! Great this is fixed in Python 3.10.

I had briefly looked at those docs, but didn’t (and still don’t) really see anything that explains this specific aspect.

I now found this on the mypy issue tracker: recognize staticmethod's __func__ · Issue #11211 · python/mypy · GitHub

And Descriptors shouldn't be considered callable inside class definition · Issue #2267 · python/mypy · GitHub