Python < 3.10 - TypeError: 'staticmethod' object is not callable
Describe the bug
It looks like ManimGL is no longer compatible with Python < 3.10, as, prior to this Python version, @staticmethod were not regular callable (hence, using them as a wrapper didn't work).
See here https://stackoverflow.com/a/76237739.
Code:
from manimlib import *
Wrong display or Error traceback:
manim_slides/slide/manimlib.py:4: in <module>
from manimlib import Scene, ThreeDCamera
.venv/lib/python3.9/site-packages/manimlib/__init__.py:12: in <module>
from manimlib.window import *
.venv/lib/python3.9/site-packages/manimlib/window.py:20: in <module>
class Window(PygletWindow):
.venv/lib/python3.9/site-packages/manimlib/window.py:117: in Window
def on_mouse_motion(self, x: int, y: int, dx: int, dy: int) -> None:
E TypeError: 'staticmethod' object is not callable
Additional context
See:
Static methods (@staticmethod) and class methods (@classmethod) now inherit the method attributes (module, name, qualname, doc, annotations) and have a new wrapped attribute. Moreover, static methods are now callable as regular functions. (Contributed by Victor Stinner in bpo-43682.)
from https://docs.python.org/3/whatsnew/3.10.html
I encountered the same problem, Python version is 3.9
I encountered the same problem, Python version is 3.9.5
Guido:
I thought those are callable already.
Me too, but hey, static methods and class methods are weird!
$ python3 Python 3.9.2 (default, Feb 20 2021, 00:00:00) >>> def func(): pass ... >>> wrapper = classmethod(func) >>> wrapper() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'classmethod' object is not callableIt's only callable when it goes throught the descriptor!
Found in the gh discussion acout "making classmethods callable"
I found something curious while experimenting with types tonight.
Everybody knows, if you access a descriptor in a class through the normal attribute-getting methods, you actually get the result of calling its 'get' method. If you want to get your hands on the descriptor itself, you can be sneaky and pull it out through the class's dict.
I did an experiment tonight, accessing a bunch of methods in a bunch of different ways.
The methods I tried were
* an instance method, * a class method, and * a static method.I accessed them
* as an instance attribute, * as a class attribute, and * through the class __dict__.And for each of the above, I tried
* one user method and * one built-in method.That's a total of eighteen methods tried (3x3x2).
For each one, I printed out whether or not it was callable. I found the results startling: fifteen were, but three (!) were not.
All three that weren't were accessed through the class dict. They were:
* Class method, from builtin class ( dict.__dict__['fromkeys'] ) * Static method, from user class * Static method, from builtin class ( str.__dict__['maketrans'] )I find it strange that the static method descriptors aren't callable. I find it even stranger that one of the class method descriptors isn't callable, but the other one is.
I guess a foolish consistency is the hobgoblin of my small mind, but... shouldn't all eighteen of these objects be callable?
Attached is the test harness I wrote.
(p.s. I attached you guys as nosy because I thought you might be interested.)
The above is a python issue from 2014 (Python 3.3)
What does the error you have encountered means? It means, that, in python < 3.10 ; calling
` def a_func(): pass
a_func = staticmethod(a_func) ` raised an error
While it should ha been equivalent to: ` @staticmethod def a_func(): pass
` I looked the class hierarchy above Window(PygletWindow) and their's pretty weird stuff happening, with higher-order functions, dummy functions, function re-assignation etc. It wouldn't surprise me if this stuff lead to calling staticmethod() outside of a descriptor, which in python <3.10 raised an error (and this error, considered a python bug, was fixed in python 3.10)
So:
- I suspect the error is caused by class inheritance stuff in our case
- The error is caused by a python bug
- The error should no longer appear in python >= 3.10
What's to do:
- The error is a Python one so it can't be fixed
- Python-version >= 3.10 should be added to the dependencies of manimlib
I think the case is close