Page 1 of 1

Unexpected __slots__ behavior

Posted: Fri Aug 02, 2019 4:38 pm
by manseekingknowledge
I'm on a crusade to reclaim RAM so I thought I would give slots a try. I was looking at the example here which says it shouldn't be possible to dynamically create a new attribute:

Code: Select all

class S(object):

    __slots__ = ['val']

    def __init__(self, v):
        self.val = v


x = S(42)
print(x.val)

x.new = "not possible"
In MicroPython though this doesn't seem to be the case. In MicroPython the __dict__ variable of an instance is still created. The memory savings associated with __slots__ comes from the fact that (in CPython) the __dict__ variable isn't created. Is there some way to realize the potential memory savings typically associated with __slots__ in MicroPython?

Re: Unexpected __slots__ behavior

Posted: Sat Aug 03, 2019 6:19 am
by pythoncoder
This has been discussed here. As far as I can see it hasn't been implemented in the official build (unfortunately).

Re: Unexpected __slots__ behavior

Posted: Wed Aug 21, 2019 1:02 am
by manseekingknowledge
pythoncoder wrote:
Sat Aug 03, 2019 6:19 am
This has been discussed here. As far as I can see it hasn't been implemented in the official build (unfortunately).
If using __slots__ doesn't prevent __dict__ from being created for an instance of a class, is there any benefit to using them?

Re: Unexpected __slots__ behavior

Posted: Wed Aug 21, 2019 5:29 am
by pythoncoder
I thought I'd already answered that (TTBOMK). If the feature isn't implemented, attempts to use it will confer no benefits.

Re: Unexpected __slots__ behavior

Posted: Wed Aug 21, 2019 2:42 pm
by manseekingknowledge
Sorry, my confusion came from two things. First, the documentation here mentions slots twice saying:
MicroPython doesn’t maintain symbolic local environment, it is optimized to an array of slots
Maybe the "slots" being referred to isn't the same as "__slots__"?

Second, I incorrectly assumed the change @pfalcon made that you linked to was pulled in and was just a partial implementation of slots that offered some benefit that I wasn't understanding, but I now see the changes were never pulled in because when I grep for some of the changes I come up empty handed.

Re: Unexpected __slots__ behavior

Posted: Thu Aug 22, 2019 12:04 am
by jimmo
manseekingknowledge wrote:
Wed Aug 21, 2019 2:42 pm
Maybe the "slots" being referred to isn't the same as "__slots__"?
It's actually the exact same concept, but applied to a different feature (variables in local scope, compared to class attributes).

Given

Code: Select all

x = 3
y = 7
print(x + y)
CPython treats this as:

Code: Select all

locals = {}
locals['x'] = 3
locals['y'] = 7
print(locals['x'] + locals['y'])
MicroPython treats it as:

Code: Select all

locals = [None, None]
locals[0] = 3
locals[1] = 7
print(locals[0] + locals[1])
Which is obviously significantly more efficient, but loses the ability to access a local variable dynamically by name (or query the locals dict).
manseekingknowledge wrote:
Wed Aug 21, 2019 2:42 pm
Second, I incorrectly assumed the change @pfalcon made that you linked to was pulled in and was just a partial implementation of slots that offered some benefit that I wasn't understanding, but I now see the changes were never pulled in because when I grep for some of the changes I come up empty handed.
On the PR you would see a notification to indicate that it had been merged. e.g. compare to https://github.com/micropython/micropython/pull/5016 If you look at some other projects, if the merge is done by the maintainer via the Github UI will actually mark a PR as "merged". However, Damien manually pulls the commits in (not using the Github interface) so this doesn't happen for MicroPython PRs.