I have a function in a class that is entirely private in usage and should never be called outside of the class itself (its just an internal decorator).
It would be nice if I could turn off the linter error about not including a self argument if its not a staticmethod):
Also, since it’s a portable_class, I can’t really set it as a staticmethod because that makes the designer angry when I use it on the client side because it’s a static method.
?! That should work! “Make @staticmethod
work client-side” is a much better FR than “turn off this linting as a workaround for being unable to tag a method as static”
1 Like
Static method itself does work when you use it outside of the class, but when I try to use a static method within the class as a decorator on other methods, I get this error:
TypeError: 'staticmethod' object is not callable
at portable_class, line 21
called from portable_class, line 7
called from Form1, line 4
Here is a clone link to a minimal example:
Also, I still would like a way to silence the error because I don’t actually want my decorator to be a static method, I just want to use it within my class.
While waiting for Meredydd FR implementation, you can customize the linter behavior by adding a pyproject.toml
file to the repository. See here: [Done] Add Black Code Formatter - #4
I don’t think that’s possible since the error doesn’t list a Ruff rule violation. I think this is an anvil specific linting error – and it was there long before ruff was implemented.
Also, I think the issue with the staticmethod not working as a decorator would be more of a bug with anvil client side rather than a feature request – from skulpt or anvil itself, or just python3.7 – because on the python 3.10 server there’s no issue and when I run my minimal example on my local machine running python3.11 there’s also no issue.
Thanks for the clone
here’s the code
@anvil.server.portable_class
class TestClass:
@staticmethod
def class_decorator(func):
def inner(*args, **kwargs):
print("this is a decorator")
func(*args, **kwargs)
return inner
@staticmethod
def static_test():
print("static")
@classmethod
@class_decorator
def test(cls):
print("this is a test function")
That code doesn’t work in python 3.9 either so it’s not a bug in skulpt.
(In your clone if you open up a server console and try to import the portable_class
module you get the same error)
it’s equivalent to
@staticmethod
def foo():
pass
foo() # TypeError: 'staticmethod' object is not callable
Without the staticmethod
on class_decorator
it works as expected
but you get the annoying lint warning (annoying in this case)
The lint warning is not part of Ruff but something Anvil adds because it’s common to forget self
when defining methods.
Why not just hoist your decorator to the module scope?
def class_decorator(func):
def inner(*args, **kwargs):
print("this is a decorator")
func(*args, **kwargs)
return inner
@anvil.server.portable_class
class TestClass:
@staticmethod
def static_test():
print("static")
@classmethod
@class_decorator
def test(cls):
print("this is a test function")
EDIT
correction - doesn’t work in python 3.9
2 Likes
Sorry I forgot to change the clone’s python server version to 3.10 (though it was in my actual app). So I guess that means this was something odd in python 3.7.
What is the benefit of that besides no linting error? It seems to move it out of the scope of what its actually used for/related to to me, but maybe there’s something I’m missing.
I guess that’s why I have tried with this, but didn’t help, even if the docs says it should (assuming I am looking at the correct doc, and I am interpreting it correctly):
[tool.ruff.lint]
ignore = ["N805"]
Is it time to get rid of the Anvil added warning and rely on the warning from the linter, so one can manage it?
1 Like
Looks like staticmethods changed in python 3.10 (which I hadn’t realised)
docs in 3.9
Built-in Functions — Python 3.9.19 documentation
docs in 3.10
Built-in Functions — Python 3.10.13 documentation
Moreover, they can be called as regular functions (such as f()
).
That last sentence was added
Add in the change log:
Moreover, static methods are now callable as regular functions.
What’s New In Python 3.10 — Python 3.10.13 documentation
We can probably add support for this in skulpt since 3.7(ish) means what it means.
1 Like
Good spot @stefano
We’ll look at seeing if adding N805 and N804 are sufficient
1 Like
We’ve partially implemented this.
if you have you’re own ruff config (either a ruff.toml
or pyproject.toml
and you haven’t included N805
or N804
then we won’t warn you about self
and cls
as the first arguments to your methods/class methods.
you can also add the comment: # noqa: N805
on the method line, which tells ruff to ignore this warning type.
Caveat:
Ruff has not implemented a similar warning if there are no arguments to methods/classmethods. In this case Anvil will provide its own warning. (as ruff continues to add compatibility between itself and existing py linting tools this should get added in the future - if they do we’ll adjust accordingly)
2 Likes