BaseEntity's __setattr__ prevents private attributes, for what?

Discuss API design here.
User avatar
Mahi
Senior Member
Posts: 236
Joined: Wed Aug 29, 2012 8:39 pm
Location: Finland

BaseEntity's __setattr__ prevents private attributes, for what?

Postby Mahi » Tue Mar 17, 2015 10:26 pm

Syntax: Select all

def __setattr__(self, attr, value):
"""Find if the attribute is value and sets its value."""
# Is the given attribute private?
if attr.startswith('_'):

# Get the name of the private attribute
name = attr[1:]

# Is the attribute a property?
if (name in super(BaseEntity, self).__dir__() and isinstance(
getattr(self.__class__, name), property)):

# Set the private attribute's value
super(BaseEntity, self).__setattr__(attr, value)

# No need to go further
return

# If not a property, do not allow the private attribute
raise ValueError(
'Invalid private attribute "{0}" given.'.format(attr))
If I read it correctly, I can only create a "private" attribute if there's a matching property in _EntitySpecials' __dir__()? It prevents me from creating any attributes that are meant to be private.

Please fix, or give us a good explanation!
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Tue Mar 17, 2015 11:14 pm

There was a purpose to that previously, but I have been meaning to look at possibly removing that portion. And no, it has nothing to do with _EntitySpecials. It has to do with attributes like _index, _playerinfo, _pointer, etc... that have a property that returns the private attribute.

This line annoys me a little bit, though:
Mahi wrote:Please fix, or give us a good explanation!


I can also read your edits, which annoy me further. Please try to be more civil in the future.
Image
User avatar
Mahi
Senior Member
Posts: 236
Joined: Wed Aug 29, 2012 8:39 pm
Location: Finland

Postby Mahi » Wed Mar 18, 2015 5:12 am

satoon101 wrote:There was a purpose to that previously, but I have been meaning to look at possibly removing that portion. And no, it has nothing to do with _EntitySpecials. It has to do with attributes like _index, _playerinfo, _pointer, etc... that have a property that returns the private attribute.
But isn't this line:[PYTHON]if (name in super(BaseEntity, self).__dir__()[/PYTHON]just a direct check to make sure _EntitySpecials has a matching property for the attribute's name? Or is there something I'm not understanding?

satoon101 wrote:This line annoys me a little bit, though:
Mahi wrote:Please fix, or give us a good explanation!

I can also read your edits, which annoy me further. Please try to be more civil in the future.
I didn't mean it to be too serious about it :( I apologize if you (or anyone else) got offended.
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Wed Mar 18, 2015 5:26 am

Mahi wrote:But isn't this line:

Syntax: Select all

if (name in super(BaseEntity, self).__dir__()
just a direct check to make sure _EntitySpecials has a matching property for the attribute's name?


No, not at all. There are no private attributes in _EntitySpecials anyway. Calling super().__dir__() ends up calling object.__dir__(), as object is the only super class to BaseEntity that has a defined __dir__ attribute. Using the super class, we still get all attributes contained in BaseEntity (or PlayerEntity/WeaponEntity) without listing the dynamically created attributes. Just run a test. Prior to that line, put:

Syntax: Select all

if name in super(BaseEntity, self).__dir__():
print(name)


Now, run the following script (with a player/bot on the server):

Syntax: Select all

from entities.entity import BaseEntity

print('Testing BaseEntity')
entity = BaseEntity(1)

from players.entity import PlayerEntity

print('Testing PlayerEntity')
player = PlayerEntity(1)


You will see the following output:

Code: Select all

sp load test
Testing BaseEntity
index
edict
pointer
Testing PlayerEntity
index
edict
pointer
playerinfo


All of the values listed are the private attributes we store when creating a BaseEntity/PlayerEntity instance. Again, I will test to see if this is needed anymore, but it definitely used to before we made some other design decisions. I cannot remember exactly why, just that without that check I was having a lot of issues getting some things to work correctly.
Image
User avatar
Mahi
Senior Member
Posts: 236
Joined: Wed Aug 29, 2012 8:39 pm
Location: Finland

Postby Mahi » Wed Mar 18, 2015 5:31 am

Oh, right. Well that explains a lot. But still, it would be awesome if we'd get to create our own private attributes :) Sure I can just make them public, but I think it would be much better convention to make them private.
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Wed Apr 01, 2015 1:53 pm

I just fixed this, though I forgot to add it in the commit message:
https://github.com/Source-Python-Dev-Team/Source.Python/commit/35164d423614c327f40e6149ed7db9ea35dca6cf

My first tests show that I am not having the issues that required that with the old implementation.
Image

Return to “API Design”

Who is online

Users browsing this forum: No registered users and 18 guests