Re: [Python-Dev] PEP 487 vs 422 (dynamic class decoration)

2015-04-06 Thread Eric Snow
On Sat, Apr 4, 2015 at 6:40 PM, Greg Ewing  wrote:
> Eric Snow wrote:
>>
>> I've felt for a long time that it would be helpful in some situations
>> to have a reverse descriptor protocol.
>
> Can you elaborate on what you mean by that?

Sure.  It's more python-ideas territory (I posted about it a few years
back).  The idea is to allow an object the opportunity to handle being
bound to a name.  So if a type defines __bound__ (or similar) then it
will be called for the instance being bound to a name:
type(obj).__bound__(obj, name).  There would also be an __unbound__,
but that is less of an issue here.

I'm still not convinced such a reverse descriptor protocol is
practical as a general approach (though no less than the current
descriptor protocol).  However, I do see a distinct correspondence
with the "__post_process__" method being considered here.  So I wanted
to point out the possibility of a more general approach for the sake
of its impact on the name and semantics of a descriptor post-process
method.  While I expect __post_process__ would be called at a
different place than __bound__, the responsibility of both would still
be identical.

-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] PEP 487 vs 422 (dynamic class decoration)

2015-04-06 Thread Eric Snow
On Fri, Apr 3, 2015 at 6:44 AM, Martin Teichmann
 wrote:
> Nick, I couldn't agree more with you, yet I think PJ actually brought
> up a very interesting point. Post-processing is a very common thing
> these days, and has been re-written so many times that I think it is
> about time that something like it should be in the standard library.

Here's another approach that would help.  Support a mechanism for
inheriting class decorators.  Classes would have an attribute like
__subclass_decorators__ that would hold a tuple of all the inherited
decorators.  They would be applied, in order, in __build_class__
before any explicit decorators are.

One way to accomplish this is with a meta-decorator, e.g.
"classutil.inherited_decorator".  You would decorate a class decorator
with it:

def inherited_decorator(deco):
def new_deco(cls):
cls = deco(cls)
try:
inherited = cls.__subclass_decorators__
except AttributeError:
cls.__subclass_decorators__ = (deco,)
else:
cls.__subclass_decorators__ = inherited + (deco,)
return cls

@inherited_decorator
def register(cls):
registry.add(cls)
return cls

@register
class X:
...

The downside to the meta-decorator is that is isn't apparent when the
class decorator is used that it will be inherited.  It could also be
used directly to make it more apparent:

def register(cls):
registry.add(cls)
return cls

@inherited(register)
class X:
...

However, that doesn't read well.  Syntax would be better, but is a
harder sell and a little grittier:

def register(cls):
registry.add(cls)
return cls

@@register
class X:

-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


[Python-Dev] PEP 8 update

2015-04-06 Thread Guido van Rossum
I've taken the liberty of adding the following old but good rule to PEP 8
(I was surprised to find it wasn't already there since I've lived by this
for ages):


   -

   Be consistent in return statements. Either all return statements in a
   function should return an expression, or none of them should. If any return
   statement returns an expression, any return statements where no value is
   returned should explicitly state this as return None, and an explicit
   return statement should be present at the end of the function (if
   reachable).

   Yes:

   def foo(x):
   if x >= 0:
   return math.sqrt(x)
   else:
   return None

   def bar(x):
   if x < 0:
   return None
   return math.sqrt(x)

   No:

   def foo(x):
   if x >= 0:
   return math.sqrt(x)

   def bar(x):
   if x < 0:
   return
   return math.sqrt(x)





-- 
--Guido van Rossum (python.org/~guido)
___
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] PEP 8 update

2015-04-06 Thread Barry Warsaw
On Apr 06, 2015, at 06:08 PM, Guido van Rossum wrote:

>I've taken the liberty of adding the following old but good rule to PEP 8
>(I was surprised to find it wasn't already there since I've lived by this
>for ages):
>
>   Be consistent in return statements. Either all return statements in a
>   function should return an expression, or none of them should. If any return
>   statement returns an expression, any return statements where no value is
>   returned should explicitly state this as return None, and an explicit
>   return statement should be present at the end of the function (if
>   reachable).

+1

Odd synchronicity: Today I discovered an old interface that was documented as
returning a "thing or None" but the latter was relying on implicit None return
in some cases.  Fixed of course in exactly the way PEP 8 now recommends. :)

Cheers,
-Barry
___
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] PEP 8 update

2015-04-06 Thread Rob Cliffe



On 07/04/2015 02:08, Guido van Rossum wrote:
I've taken the liberty of adding the following old but good rule to 
PEP 8 (I was surprised to find it wasn't already there since I've 
lived by this for ages):


 *

Be consistent in return statements. Either all return statements
in a function should return an expression, or none of them should.
If any return statement returns an expression, any return
statements where no value is returned should explicitly state this
asreturn None, and an explicit return statement should be present
at the end of the function (if reachable).

Yes:

def foo(x):
 if x >= 0:
 return math.sqrt(x)
 else:
 return None


That would seem to be good style and common sense.

As a matter of interest, how far away from mainstream am I in 
preferring, *in this particular example* (obviously it might be 
different for more complicated computation),


def foo(x):
return math.sqrt(x) if x >= 0 else None

I probably have a personal bias towards compact code, but it does seem 
to me that the latter says exactly what it means, no more and no less, 
and therefore is somewhat more readable.  (Easier to keep the reader's 
attention for 32 non-whitespace characters than 40.)


Sorry if this is irrelevant to Guido's point.
Rob Cliffe
___
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] PEP 8 update

2015-04-06 Thread Steven D'Aprano
On Tue, Apr 07, 2015 at 03:11:30AM +0100, Rob Cliffe wrote:

> As a matter of interest, how far away from mainstream am I in 
> preferring, *in this particular example* (obviously it might be 
> different for more complicated computation),
> 
> def foo(x):
> return math.sqrt(x) if x >= 0 else None
> 
> I probably have a personal bias towards compact code, but it does seem 
> to me that the latter says exactly what it means, no more and no less, 
> and therefore is somewhat more readable.  (Easier to keep the reader's 
> attention for 32 non-whitespace characters than 40.)

In my opinion, code like that is a good example of why the ternary if 
operator was resisted for so long :-) Sometimes you can have code which 
is just too compact.

My own preference would be:

def foo(x):
if x >= 0: 
return math.sqrt(x)
return None

but I'm not terribly fussed about whether the "else" is added or not, 
whether the return is on the same line as the if, and other minor 
variations. 

-- 
Steve
___
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