-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
__slots__ for subclasses of variable length types #41779
Comments
This is a first, rough cut at allowing subclasses of variable length The motivation is trying to understand and document what's going on This patch also allows instances of such classes to be weakly What is missing: tests, lots of tests, documentation. Also, the code Also, I think my code probably fails to cope with code like: class A(str):
pass # implicitly adds __dict__, __weakref__
class B(A):
__slots__ = ["a", "b"]
b = B()
b.c = 1 Hmm, yes. Oh well, no time to fix today (I don't think it's that big a |
Logged In: YES I'm confused: the rule for negative slot offsets appear to be different to the one for tp_dictoffset, which only increases the amount of obscurity around here. tp_dictoffset counts relative to the end of the object, whereas in your patch negative slot offsets are a different trick to mean "relative to the start but skipping the varsized part". The difference shows up when subclassing increases tp_basicsize. This should be resolved one way or the other -- and I think that a clear picture of the various parts of the object and how they are measured would be a good start. That's also related to your proposed change to extra_ivars(), which would become slightly more permissive; I strongly suspect that it would allow more strange segfaulting cases to sneak in undetected... |
Logged In: YES
Yes. I think this is actually necessary. Consider: class S(str):
__slots__ = ['a'] you'd except S.__dict__['a'].__offset__ (well, if the attribute existed) to be Then class T(S):
__slots__ = ['b'] then using the 'from the end of the object' rule for T().a would actually find __dict__ indeed works differently, because
Yeah, sorry about that. I think something I've realised over the past few days is that __dict__
See above -- don't think you can.
No kidding here!
Almost certainly! |
Logged In: YES I think it's still possible to give slot.offset the same meaning as tp_dictoffset, even given the additional constrain that it can't change upon subclassing. In your example classes S and T, we can put 'b' before 'a' in memory, so that a.offset==-4 (for both S and T) and b.offset==-8. |
Logged In: YES Heh, yes that works, and completely hadn't occurred to me. |
Patch has tests. |
How much rework if any is needed to get this patch into py3k? |
I believe this is covered by the PEP-3003 3.2 change moratorium. |
ISTM the space saving of value of __slots__ isn't typically needed in the context of variable length built-in types. Guido has long regarded __slots__ as a confusing hack. That should warn us away for extending its functionality. Unless there are some compelling use cases, a simple and clean patch, and a clear one sentence explanation for users, I recommend this feature request be closed. Michael, do you still want this? |
Well, I can think of some counters to that -- surely it's _more_ confusing if slots only works some of the time? -- but realistically I'm not going to work on this any further. |
Declaring YAGNI and closing. |
I do have a usecase for this: subclasses of int. Having slots would be nice for a reasonably efficient implementation of named constants (as recently discussed on python-ideas), and I'm already using a subclass of int of PyObjC to attach a single other value to a Python integer. In both cases the overhead of the __dict__ is pretty large. |
I have a use case for this for namedtuple subclasses, in particular to add fields to |
#1
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: