Unable to add attributes to a subclass of PlayerEntity in __new__?

Please post any questions about developing your plugin here. Please use the search function before posting!
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Mon Jul 06, 2015 2:42 pm

I actually noticed this change last night and wondered what it was for:
https://github.com/Source-Python-Dev-Team/Source.Python/blob/master/addons/source-python/packages/source-python/players/weapons/projectiles.py#L18

That line used to be:

Syntax: Select all

class _ProjectileMeta(type):


Having tested, it seems that using 'type' instead causes the same error you are getting, but also crashes the server on plugin_load. I tested changing your example to use BaseEntity.__class__, but that still gave the same error. Changing it to use PlayerEntity.__class__, however, seems to work fine:

Syntax: Select all

from players.entity import PlayerEntity


class MetaTest(PlayerEntity.__class__):

def __new__(cls, name, bases, attrs):
attrs['_instances'] = dict()
return super(MetaTest, cls).__new__(cls, name, bases, attrs)


class Test(PlayerEntity, metaclass=MetaTest):

def __new__(cls, index):
if index not in cls._instances:
cls._instances[index] = super(Test, cls).__new__(cls, index)
return cls._instances[index]


class Test2(Test):
...


class Test3(Test):
...


one = Test(1)
two = Test2(1)
three = Test3(1)
print(one)
print(two)
print(three)
print(Test(1))


And that outputs:

Code: Select all

<new.new.Test object at 0x1E5C6900>
<new.new.Test2 object at 0x1E5C6930>
<new.new.Test3 object at 0x1E5C6960>
<new.new.Test object at 0x1E5C6900>
Image
User avatar
Mahi
Senior Member
Posts: 236
Joined: Wed Aug 29, 2012 8:39 pm
Location: Finland

Postby Mahi » Mon Jul 06, 2015 3:09 pm

Interesting. So you're unaware of why this issue is happening? I can't find any classes related to player class that even use metaclasses... Well, I'll just use type(PlayerEntity) for now. :) Thanks for the help!
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Mon Jul 06, 2015 3:24 pm

It has to be due to the fact that we are inheriting from BaseEntity. If you change the example to use Entity instead of PlayerEntity, the same error is encountered:

Syntax: Select all

from entities.entity import Entity


class MetaTest(type):

def __new__(cls, name, bases, attrs):
attrs['_instances'] = dict()
return super(MetaTest, cls).__new__(cls, name, bases, attrs)


class Test(Entity, metaclass=MetaTest):

def __new__(cls, index):
if index not in cls._instances:
cls._instances[index] = super(Test, cls).__new__(cls, index)
return cls._instances[index]


class Test2(Test):
...


class Test3(Test):
...


one = Test(1)
two = Test2(1)
three = Test3(1)
print(one)
print(two)
print(three)
print(Test(1))


However, changing 'type' to Entity.__class__ works as it should. type(Entity) gives you the same object as Entity.__class__ (same for PlayerEntity), so either way works.
Image
User avatar
Mahi
Senior Member
Posts: 236
Joined: Wed Aug 29, 2012 8:39 pm
Location: Finland

Postby Mahi » Mon Jul 06, 2015 5:53 pm

Alright, good to know. But yeah, I'm fine with using type(PlayerEntity) as long as it works! :) And I'm aware of type(x) == x.__class__, but I've always found type() better looking and less-hacky :)

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 149 guests