Re: [Python-Dev] PEP 520: Ordered Class Definition Namespace (round 3)

2016-06-13 Thread Berker Peksağ
On Sun, Jun 12, 2016 at 5:37 AM, Eric Snow  wrote:
> The following code demonstrates roughly equivalent semantics for the
> default behavior::
>
>class Meta(type):
>def __prepare__(cls, *args, **kwargs):

Shouldn't this be wrapped with a classmethod decorator?

+1 from me.

--Berker
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 520: Ordered Class Definition Namespace (round 3)

2016-06-11 Thread Émanuel Barry
> From: Eric Snow
> Sent: Saturday, June 11, 2016 11:02 PM
> To: Émanuel Barry
> Cc: Python-Dev
> Subject: Re: [Python-Dev] PEP 520: Ordered Class Definition Namespace
> (round 3)
> 
> On Sat, Jun 11, 2016 at 7:51 PM, Émanuel Barry <vgr...@live.ca> wrote:
> >> From: Eric Snow
> >>   1. if ``__definition_order__`` is defined in the class body then it
> >>  must be a ``tuple`` of identifiers or ``None``; any other value
> >>  will result in ``TypeError``
> >
> > Why not just any arbitrary iterable, which get converted to a tuple at
> > runtime?
> 
> An arbitrary iterable does not necessarily infer a definition order.
> For example, dict is an iterable but the order is undefined.  Also,
> I'd rather favor simplicity for this (most likely) uncommon corner
> case of manually setting __definition_order__, particularly at the
> start.  If it proves to be a problematic restriction in the future we
> can loosen it.

Point. This can always be revised later (I'm probably overthinking this as 
always ;)

> 
> -eric

-Emanuel
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 520: Ordered Class Definition Namespace (round 3)

2016-06-11 Thread Eric Snow
On Sat, Jun 11, 2016 at 7:51 PM, Émanuel Barry  wrote:
>> From: Eric Snow
>>   1. if ``__definition_order__`` is defined in the class body then it
>>  must be a ``tuple`` of identifiers or ``None``; any other value
>>  will result in ``TypeError``
>
> Why not just any arbitrary iterable, which get converted to a tuple at
> runtime?

An arbitrary iterable does not necessarily infer a definition order.
For example, dict is an iterable but the order is undefined.  Also,
I'd rather favor simplicity for this (most likely) uncommon corner
case of manually setting __definition_order__, particularly at the
start.  If it proves to be a problematic restriction in the future we
can loosen it.

> __slots__ allows any arbitrary iterable:

Yes, but __slots__ is not order-sensitive.

>> is already complete by the time ``definition_order__`` is set, the
>
> Typo: missing leading underscores in __definition_order__

I'll fix that.

>
>> Compatibility
>> =
>>
>> This PEP does not break backward compatibility, except in the case that
>> someone relies *strictly* on ``dict`` as the class definition namespace.
>> This shouldn't be a problem.
>
> Perhaps add a mention that isinstance(namespace, dict) will still be true,
> so users don't get unnecessarily confused.

Good point.

>
>> .__dict__ as OrderedDict
>> ---
>
>  looks weird to me. I tend to use `cls` (although `klass` isn't
> uncommon). `C` might also not be a bad choice.

Yes, that is better.

-eric
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 520: Ordered Class Definition Namespace (round 3)

2016-06-11 Thread Émanuel Barry
> From: Eric Snow
> Sent: Saturday, June 11, 2016 10:37 PM
> To: Python-Dev; Guido van Rossum
> Subject: [Python-Dev] PEP 520: Ordered Class Definition Namespace (round
> 3)


> The only change to the original proposal
> has been that a manually set __definition_order__ must be a tuple of
> identifiers or None (rather that using the value as-is).


>   1. if ``__definition_order__`` is defined in the class body then it
>  must be a ``tuple`` of identifiers or ``None``; any other value
>  will result in ``TypeError``

Why not just any arbitrary iterable, which get converted to a tuple at
runtime? __slots__ allows any arbitrary iterable:

>>> def g():
...   yield "foo"
...   yield "bar"
...   yield "baz"
>>> class C:
...   __slots__ = g()
>>> C.__slots__

>>> C.__slots__.gi_running
False
>>> dir(C)
[, 'bar', 'baz', 'foo']

> Use of a tuple reflects the fact that we are exposing the order in
> which attributes on the class were *defined*.  Since the definition
> is already complete by the time ``definition_order__`` is set, the
> content and order of the value won't be changing.  Thus we use a type
> that communicates that state of immutability.

Typo: missing leading underscores in __definition_order__

> Compatibility
> =
> 
> This PEP does not break backward compatibility, except in the case that
> someone relies *strictly* on ``dict`` as the class definition namespace.
> This shouldn't be a problem.

Perhaps add a mention that isinstance(namespace, dict) will still be true,
so users don't get unnecessarily confused.

> .__dict__ as OrderedDict
> ---

 looks weird to me. I tend to use `cls` (although `klass` isn't
uncommon). `C` might also not be a bad choice.

Thanks!
-Emanuel
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] PEP 520: Ordered Class Definition Namespace (round 3)

2016-06-11 Thread Eric Snow
I've updated the PEP to reflect feedback up to this point.  The
reception has been positive.  The only change to the original proposal
has been that a manually set __definition_order__ must be a tuple of
identifiers or None (rather that using the value as-is).  All other
updates to the PEP have been clarification.

Guido, at this point I believe the PEP is ready for pronouncement. *
I've included the most recent copy of the text below.  Thanks.

-eric

==

PEP: 520
Title: Ordered Class Definition Namespace
Version: $Revision$
Last-Modified: $Date$
Author: Eric Snow 
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 7-Jun-2016
Python-Version: 3.6
Post-History: 7-Jun-2016


Abstract


When a class is defined using a ``class`` statement, the class body is
executed within a namespace.  After the execution completes, that
namespace is copied into new ``dict`` and the original definition
namespace is discarded.  The new copy is stored away as the class's
namespace and is exposed as ``__dict__`` through a read-only proxy.

This PEP changes the default class definition namespace to ``OrderedDict``.
The long-lived class namespace (``__dict__``) will remain a ``dict``.
Furthermore, the order in which the attributes are defined in each class
body will now be preserved in the ``__definition_order__`` attribute of
the class.  This allows introspection of the original definition order,
e.g. by class decorators.


Motivation
==

Currently the namespace used during execution of a class body defaults
to ``dict``.  If the metaclass defines ``__prepare__()`` then the result
of calling it is used.  Thus, before this PEP, if you needed your class
definition namespace to be ``OrderedDict`` you had to use a metaclass.

Metaclasses introduce an extra level of complexity to code and in some
cases (e.g. conflicts) are a problem.  So reducing the need for them is
worth doing when the opportunity presents itself.  Given that we now have
a C implementation of ``OrderedDict`` and that ``OrderedDict`` is the
common use case for ``__prepare__()``, we have such an opportunity by
defaulting to ``OrderedDict``.

The usefulness of ``OrderedDict``-by-default is greatly increased if the
definition order is directly introspectable on classes afterward,
particularly by code that is independent of the original class definition.
One of the original motivating use cases for this PEP is generic class
decorators that make use of the definition order.

Changing the default class definition namespace has been discussed a
number of times, including on the mailing lists and in PEP 422 and
PEP 487 (see the References section below).


Specification
=

* the default class *definition* namespace is now ``OrderdDict``
* the order in which class attributes are defined is preserved in the
  new ``__definition_order__`` attribute on each class
* "dunder" attributes (e.g. ``__init__``, ``__module__``) are ignored
* ``__definition_order__`` is a ``tuple`` (or ``None``)
* ``__definition_order__`` is a read-only attribute
* ``__definition_order__`` is always set:

  1. if ``__definition_order__`` is defined in the class body then it
 must be a ``tuple`` of identifiers or ``None``; any other value
 will result in ``TypeError``
  2. classes that do not have a class definition (e.g. builtins) have
 their ``__definition_order__`` set to ``None``
  3. classes for which `__prepare__()`` returned something other than
 ``OrderedDict`` (or a subclass) have their ``__definition_order__``
 set to ``None`` (except where #1 applies)

The following code demonstrates roughly equivalent semantics for the
default behavior::

   class Meta(type):
   def __prepare__(cls, *args, **kwargs):
   return OrderedDict()

   class Spam(metaclass=Meta):
   ham = None
   eggs = 5
   __definition_order__ = tuple(k for k in locals()
if not (k.startswith('__') and
k.endswith('__')))

Note that [pep487_] proposes a similar solution, albeit as part of a
broader proposal.

Why a tuple?


Use of a tuple reflects the fact that we are exposing the order in
which attributes on the class were *defined*.  Since the definition
is already complete by the time ``definition_order__`` is set, the
content and order of the value won't be changing.  Thus we use a type
that communicates that state of immutability.

Why a read-only attribute?
--

As with the use of tuple, making ``__definition_order__`` a read-only
attribute communicates the fact that the information it represents is
complete.  Since it represents the state of a particular one-time event
(execution of the class definition body), allowing the value to be
replaced would reduce confidence that the attribute corresponds to the
original class body.

If a use case for a writable (or mutable)