[Python-Dev] PEP 399: Pure Python/C Accelerator Module Compatibiilty Requirements (original) (raw)

Brett Cannon brett at python.org
Wed Apr 6 19:40:16 CEST 2011


On Tue, Apr 5, 2011 at 05:01, Nick Coghlan <ncoghlan at gmail.com> wrote:

On Tue, Apr 5, 2011 at 9:46 AM, Brett Cannon <brett at python.org> wrote: > try: > cheapq.heappop(Spam()) > except TypeError: > # "heap argument must be a list" > pass > > try: > pyheapq.heappop(Spam()) > except AttributeError: > # "'Foo' object has no attribute 'pop'" > pass > > This kind of divergence is a problem for users as they unwittingly > write code that is CPython-specific. This is also an issue for other > VM teams as they have to deal with bug reports from users thinking > that they incorrectly implemented the module when in fact it was > caused by an untested case.

While I agree with the PEP in principle, I disagree with the way this example is written. Guido has stated in the past that code simply cannot rely on TypeError being consistently thrown instead of AttributeError (or vice-versa) when it comes to duck-typing. Code that cares which of the two is thrown is wrong. However, there actually is a significant semantic discrepancy in the heapq case, which is that pyheapq is duck-typed, while cheapq is not:

That's true. I will re-word it to point that out. The example code still shows it, I just didn't explicitly state that in the example.

-Brett

>>> from test.support import importfreshmodule >>> cheapq = importfreshmodule('heapq', fresh=['heapq']) >>> pyheapq = importfreshmodule('heapq', blocked=['heapq']) >>> from collections import UserList >>> class Seq(UserList): pass ... >>> cheapq.heappop(UserList()) Traceback (most recent call last): File "", line 1, in TypeError: heap argument must be a list >>> pyheapq.heappop(UserList()) Traceback (most recent call last): File "", line 1, in File "/home/ncoghlan/devel/py3k/Lib/heapq.py", line 140, in heappop lastelt = heap.pop() # raises appropriate IndexError if heap is empty File "/home/ncoghlan/devel/py3k/Lib/collections/init.py", line 848, in pop def pop(self, i=-1): return self.data.pop(i) IndexError: pop from empty list Cheers, Nick. P.S. The reason I was bugging Guido to answer the TypeError vs AttributeError question in the first place was to find out whether or not I needed to get rid of the following gross inconsistency in the behaviour of the with statement relative to other language constructs: >>> 1() Traceback (most recent call last): File "", line 1, in TypeError: 'int' object is not callable >>> with 1: pass ... Traceback (most recent call last): File "", line 1, in AttributeError: 'int' object has no attribute 'exit'

Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20110406/79246962/attachment-0001.html>



More information about the Python-Dev mailing list