Re: [Python-Dev] Replacing self.__dict__ in __init__

2018-03-26 Thread Tin Tvrtković
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

2018-03-26 Thread Eric V. Smith
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

2018-03-26 Thread Nick Coghlan
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

2018-03-26 Thread Eric V. Smith

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

2018-03-26 Thread Eric V. Smith

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