0

I have a metaclass that accepts keyword arguments:

class M(type):
    def __new__(cls, *args, **kwargs):
        print(*kwargs.items())
        super().__new__(cls, *args)

It works as expected:

class A(metaclass=M, test='X'): pass

results in an object A and the printout

('test', 'X')

I would like to make a copy of A using something like this:

def copy_class(cls, name=None):
    if name is None:
        name = cls.__name__
    return type(cls)(name, cls.__bases__, dict(cls.__dict__))

A_copy = copy_class(A, 'A_copy')

However, the keywords are not present. This is especially a problem when type(cls) requires additional arguments or otherwise produces different side-effects when they are not there.

I am aware that I can have M stash the keywords in the class object somewhere, but this is not a very good solution because then my copy method is very class-dependent.

Is there a built-in way to retrieve the keywords a class was created with in Python?

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • I'm voting to close this question as off-topic because this is not really the right question to ask, but I don't want to delete it since there is a very nice answer already posted. – Mad Physicist Mar 06 '18 at 23:22
  • Apparently I can't close my own question? – Mad Physicist Mar 06 '18 at 23:22
  • With the other problems this brings up apart, stashing the keywords on the class itself would be the correct way to do it. The copying function could simply use no keywords if the stashing attribute were not found, with no problems. – jsbueno Mar 07 '18 at 12:14
  • And, on the other hand, you might simply try using `copy.deepcopy` - you'd be surprised. It wouldo work unless your class creation had side effects like creating live resources like files r sockets attached to the class. – jsbueno Mar 07 '18 at 12:16
  • @jsbueno. I've asked a more proper question here: https://stackoverflow.com/q/49157255/2988730. I wanted to close this question because I was suffering from XY syndrome when I asked it. This question is basically nonsense (although your comment is very helpful for what I am actually trying to acheive). – Mad Physicist Mar 07 '18 at 16:53

1 Answers1

1

Python will not save the keyword arguments for you. This is simple to demonstrate:

>>> class DoesntSaveKeywords(type):
...     def __new__(cls, name, bases, dict, **kwargs):
...         return super().__new__(cls, name, bases, dict)
... 
>>> class PrintsOnDel:
...     def __del__(self):
...         print('__del__')
... 
>>> class Foo(metaclass=DoesntSaveKeywords, keyword=PrintsOnDel()):
...     pass
... 
__del__

Also, I don't think the underlying idea of trying to copy a class like this makes sense. There's no guarantee that the class's __dict__ looks anything like what was originally passed to the metaclass constructor, or that calling the metaclass constructor again will do anything remotely reasonable.

user2357112
  • 260,549
  • 28
  • 431
  • 505