Re: Using __abstractmethod__ with non-methods

2011-06-23 Thread Eric Snow
Just a follow up on the longer post I made [1]:

Is it bad to set __abstractmethod__ on non-functions in order to
trigger the ABC abstractness checks?

If not, are __isabstractmethod__ on objects and __abstractmethods__ on
classes misleading names?

Like I said before, I don't mean to imply that Python has it wrong.
On the contrary, I typically start by assuming that Python has it
right and then try to figure out what I am missing.  Such is the case
here.

-eric

[1] http://mail.python.org/pipermail/python-list/2011-June/1274555.html
-- 
http://mail.python.org/mailman/listinfo/python-list


Using __abstractmethod__ with non-methods

2011-06-16 Thread Eric Snow
This is a long post, so to sum up:

  Is it bad to set __abstractmethod__ on non-functions in order to
trigger the ABC abstractness checks?  If not, are __isabstractmethod__
on objects and __abstractmethods__ on classes misleading names?

I don't mean to imply that Python has it wrong.  On the contrary, I
typically start by assuming that Python has it right and then try to
figure out what I am missing [1].  Without further ado, here's a
little more meat so that my questions have a better context.

Background

Last week I jumped into an tracker issue that has been developing for
some time [2].  The issue involves the interplay between abstract base
classes and descriptors (like property).  Keep in mind that the issue
is only the catalyst for my question here, and my question is a
tangent.  If possible I would rather any discussion here center on
that, and anything meaningful to the issue be put in the tracker.

Perhaps I did not think it through, but I made a point that the term
abstractmethod is potentially misleading.  I'm hoping to get some
feedback on that from you.  The reason I bring it up here is because
of the brief response I got in the ticket.  I did not want to further
side-track the discussion going on there, so I'm bringing it here
instead. :)

In the issue Nick explained the following:

Regarding the naming, @abstractmethod and __isabstractmethod__ are
definitely about methods, or method-based descriptors (such as
property).
There *could* be a case to be made to allow for abstract data
attributes,
but really, using an abstract property should cover that use case well
enough.

Nick is a super smart guy, has probably 100x the experience I do, and,
from my experience with him, simply gets it a ton better than I do,
so I trust what he says.  Also, he was involved with all this when
abstract base classes were added to the language [3].  From what Nick
said and from the name used, I'm guessing that the motivation was to
have the abstractness of ABCs focused explicitly on methods.

Motivation

The reason I brought it up in the tracker issue is that I've taken to
using __isabstractmethod__ on non-methods.  The code in object_new
(typeobject.c) does not care about the types of a class's attributes
[4].  Neither does the code in ABCMeta (abc.py) [5].  All that matters
is that an attribute has __abstractmethod__ set to True to indicate
that the class is abstract.  So with that in mind, I use it on
non-function attributes that I want to be abstract [6].

Nick pointed out that you can use an abstract property to accomplish
this same thing.  That's what I had been doing for quite a while.
However, I was uncomfortable using an abstract property to describe
something that I did not expect to be implemented as a property.  But
that may be just me.

Keep in mind that ABCMeta and typeobject.c do not do any signature
checking of objects, so the implementation of an abstract attribute
in a subclass can be any object.  All that matters is that the
matching name be bound on the namespace of the subclass.  Thus, an
abstract method does not have to be implemented with a method, nor an
abstract property with a property.  However, the key point is that the
abstracting decorators provide an indicator of the expectation of the
implementation [7].

Questions

So this all comes back to those two questions.  Before jumping into
tracker issue, I had not considered that my use of
__isabstractmethod__ may be contrary to the expected use.  Is it?  If
not, then perhaps __isabstractmethod__ (on objects) would be better
called __isabstractattribute__; and __abstractmethods__ (on classes)
would be better called __abstractattributes__ [8].

I'm certainly not saying that we should jump up and change them if
they are a potentially incomplete description of their usage, which
they may not be.  The fact is, Python lets you do things that many
other languages would not allow, with the stipulation that we're all
consenting adults--so if you step outside the lines of expected use,
you're on your own (that's one awesome aspect of Python).  Thus, even
if my use case is valid, it may be of such small impact relative to
abstract methods that it makes more sense to use method in the
names.

So again, do you think my use of __abstractmethod__ with non-functions
is appropriate?  If so, is it a valid enough use case of abstractness
that using method in those two attribute names should change?  My
gut says yes to the first and no to the second, but I want to hear
what you think!

-eric

p.s. Sorry for the length of this message.  Not only do I get
long-winded every once in a while wink but I wanted to give this a
thorough treatment.


[1] One thing that I love about Python is that it is driven by really
smart yet practical people that want an easy-to-use, powerful
language.  The design is not driven by pure language theory.  But it's
not driven by let's just get it done.  It is a powerful mix.
Features are