Re: [Python-Dev] Replacing self.__dict__ in __init__
Thank you to everyone who participated (Kirill, Raymond, Nick, Naoki). I've
decided there are too many caveats for this approach to be worthwhile and
I'm giving up on it.
Kind regards,
Tin
On Sat, Mar 24, 2018 at 3:18 PM Tin Tvrtković wrote:
> Hi Python-dev,
>
> I'm one of the core attrs contributors, and I'm contemplating applying an
> optimization to our generated __init__s. Before someone warns me python-dev
> is for the development of the language itself, there are two reasons I'm
> posting this here:
>
> 1) it's a very low level question that I'd really like the input of the
> core devs on, and
> 2) maybe this will find its way into dataclasses if it works out.
>
> I've found that, if a class has more than one attribute, instead of
> creating an init like this:
>
> self.a = a
> self.b = b
> self.c = c
>
> it's faster to do this:
>
> self.__dict__ = {'a': a, 'b': b, 'c': c}
>
> i.e. to replace the instance dictionary altogether. On PyPy, their core
> devs inform me this is a bad idea because the instance dictionary is
> special there, so we won't be doing this on PyPy.
>
> But is it safe to do on CPython?
>
> To make the question simpler, disregard the possibility of custom setters
> on the attributes.
>
> Thanks in advance!
>
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] descriptor __set_name__ and dataclasses
https://bugs.python.org/issue33141 points out an interesting issue with dataclasses and descriptors. Given this code: from dataclasses import * class D: """A descriptor class that knows its name.""" def __set_name__(self, owner, name): self.name = name def __get__(self, instance, owner): if instance is not None: return 1 return self @dataclass class C: d: int = field(default=D(), init=False) C.d.name is not set, because d.__set_name__ is never called. However, in this case: class X: d: int = D() X.d.name is set to 'd' when d.__set_name__ is called during type.__new__. The problem of course, is that in the dataclass case, when class C is initialized, and before the decorator is called, C.d is set to a Field() object, not to D(). It's only when the dataclass decorator is run that I change C.d from a Field to the value of D(). That means that the call to d.__set_name__(C, 'd') is skipped. See https://www.python.org/dev/peps/pep-0487/#implementation-details for details on how type.__new__ works. The only workaround I can think of is to emulate the part of PEP 487 where __set_name__ is called. I can do this from within the @dataclass decorator when I'm initializing C.d. I'm not sure how great this solution is, since it's moving the call from class creation time to class decorator time. I think in 99+% of cases this would be fine, but you could likely write code that depends on side effects of being called during type.__new__. Unless anyone has strong objections, I'm going to make the call to __set_name__ in the @datacalss decorator. Since this is such a niche use case, I don't feel strongly that it needs to be in today's beta release, but if possible I'll get it in. I already have the patch written. And if it does get in but the consensus is that it's a bad idea, we can back it out. Eric ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] descriptor __set_name__ and dataclasses
On 27 March 2018 at 00:40, Eric V. Smith wrote: > https://bugs.python.org/issue33141 points out an interesting issue with > dataclasses and descriptors. > > Given this code: > > from dataclasses import * > > class D: > """A descriptor class that knows its name.""" > def __set_name__(self, owner, name): > self.name = name > def __get__(self, instance, owner): > if instance is not None: > return 1 > return self > > > @dataclass > class C: > d: int = field(default=D(), init=False) > > C.d.name is not set, because d.__set_name__ is never called. However, in > this case: > > class X: > d: int = D() > > X.d.name is set to 'd' when d.__set_name__ is called during type.__new__. > > The problem of course, is that in the dataclass case, when class C is > initialized, and before the decorator is called, C.d is set to a Field() > object, not to D(). It's only when the dataclass decorator is run that I > change C.d from a Field to the value of D(). That means that the call to > d.__set_name__(C, 'd') is skipped. See > https://www.python.org/dev/peps/pep-0487/#implementation-details for details > on how type.__new__ works. > > The only workaround I can think of is to emulate the part of PEP 487 where > __set_name__ is called. I can do this from within the @dataclass decorator > when I'm initializing C.d. I'm not sure how great this solution is, since > it's moving the call from class creation time to class decorator time. I > think in 99+% of cases this would be fine, but you could likely write code > that depends on side effects of being called during type.__new__. > > Unless anyone has strong objections, I'm going to make the call to > __set_name__ in the @datacalss decorator. Since this is such a niche use > case, I don't feel strongly that it needs to be in today's beta release, but > if possible I'll get it in. I already have the patch written. And if it does > get in but the consensus is that it's a bad idea, we can back it out. Would it be feasible to define `Field.__set_name__`, and have that call `default.__set_name__` when the latter exists, and be a no-op otherwise? Cheers, Nick. -- Nick Coghlan | [email protected] | Brisbane, Australia ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] descriptor __set_name__ and dataclasses
On 3/26/18 11:08 AM, Nick Coghlan wrote: On 27 March 2018 at 00:40, Eric V. Smith wrote: https://bugs.python.org/issue33141 points out an interesting issue with dataclasses and descriptors. Given this code: from dataclasses import * class D: """A descriptor class that knows its name.""" def __set_name__(self, owner, name): self.name = name def __get__(self, instance, owner): if instance is not None: return 1 return self @dataclass class C: d: int = field(default=D(), init=False) C.d.name is not set, because d.__set_name__ is never called. However, in this case: class X: d: int = D() X.d.name is set to 'd' when d.__set_name__ is called during type.__new__. The problem of course, is that in the dataclass case, when class C is initialized, and before the decorator is called, C.d is set to a Field() object, not to D(). It's only when the dataclass decorator is run that I change C.d from a Field to the value of D(). That means that the call to d.__set_name__(C, 'd') is skipped. See https://www.python.org/dev/peps/pep-0487/#implementation-details for details on how type.__new__ works. The only workaround I can think of is to emulate the part of PEP 487 where __set_name__ is called. I can do this from within the @dataclass decorator when I'm initializing C.d. I'm not sure how great this solution is, since it's moving the call from class creation time to class decorator time. I think in 99+% of cases this would be fine, but you could likely write code that depends on side effects of being called during type.__new__. Unless anyone has strong objections, I'm going to make the call to __set_name__ in the @datacalss decorator. Since this is such a niche use case, I don't feel strongly that it needs to be in today's beta release, but if possible I'll get it in. I already have the patch written. And if it does get in but the consensus is that it's a bad idea, we can back it out. Would it be feasible to define `Field.__set_name__`, and have that call `default.__set_name__` when the latter exists, and be a no-op otherwise? A clever idea! I'll look in to it. Eric. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] descriptor __set_name__ and dataclasses
On 3/26/18 11:10 AM, Eric V. Smith wrote: On 3/26/18 11:08 AM, Nick Coghlan wrote: On 27 March 2018 at 00:40, Eric V. Smith wrote: Would it be feasible to define `Field.__set_name__`, and have that call `default.__set_name__` when the latter exists, and be a no-op otherwise? A clever idea! I'll look in to it. It looks like that does work. Thank, Nick! Eric ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
