Problem with a dynamic class

I suspect the answer to this is some sort of skulpt limitation but, just in case it’s the more common “Owen, you’re an idiot”, here goes…

I’m creating a dynamic class using the type function. It mostly behaves as expected.

However, I can only pass arguments to the methods of that class by position. If I use named arguments, I get a TypeError.

Here’s the code for an MWE:

@classmethod
def say_greeting(self, greeting):
    print(greeting)
    

Greeter = type("Greeter", (object, ), {"say_greeting": say_greeting})

Greeter.say_greeting("hello world")
Greeter.say_greeting(greeting="hello again")

which gives:

hello world
TypeError: newfunc() got an unexpected keyword argument 'greeting'

Here’s a clone link for an app with that code included: https://anvil.works/build#clone:NMOY2XDLOQL664EN=DAT7DFFCF5B7T4PPOHEL3BZ6

Anyone got any ideas of how I might fix (or get around) this one?

Just a quick thought. What about:

Greeter.say_greeting = say_greeting

Yeah, I tried that too but it didn’t make any difference.

Thanks for looking, though!

Yep, looks like a Skulpt limitation to me. I admit to being slightly scared by whatever it is you’re trying to do…dare I ask why you’re dynamically creating classes?

You might be interested to know that @stucork is in the middle of landing a huge improvement to the Skulpt object model, which will make all sorts of tricks work, including metaclasses(!)

Having said all that, it looks like what you’re actually seeing is a limitation in Skulpt’s implementation of the @classmethod decorator. I’ve submitted a PR to Skulpt to fix it :slight_smile:

Oh well. Not much I can do then

It’s the same behaviour for instance methods too.

A quick fix would be to override the classmethod implementation for now.

Skulpt’s current implementation of classmethod is written in python.

You could take a look at meredydd’s pr and just copy that code into the project where you need it until anvil makes a skulpt update.

3 Likes