New submission from Terry J. Reedy <tjre...@udel.edu>:

BACKGROUND
One of most common recurring topics on python-list (perhaps monthly) is newbies 
tripping over a mutation method returning None when they expect the collection. 
Today's example: "Puzzled by list-appending behavior".
An excerpt from the responses: 

"On 5/26/2011 11:58 AM, MRAB wrote:
> On 26/05/2011 06:17, Chris Rebert wrote:

>> list.remove(), list.sort(), and list.extend() similarly return None
>> rather than the now-modified list.

> I'd just like to point out that it's a convention, not a rigid rule.
> Sometimes it's not followed, for example, dict.setdefault."

In Python 1, I believe it was true that all mutation methods of mutable builtin 
collections (ie, lists -- I do not think dicts had any and sets did not exist 
yet) returned None. With the introduction of list.pop, the return-None rule was 
'broken', though the meme continues. However, the flip side of that rule, 
do-not-return-the-collection, continues to be true. And the return_None rule 
was not really broken, but broadened to "return None or an item from the 
collection". I believe this should be better documented than it is now.

PROPOSALS

1. State the general rule.

A. Tutorial: At the top of chapter 5, just after "This chapter describes some 
things you’ve learned about already in more detail, and adds some new things as 
well.", add something like

"For lists, sets, and dicts, methods that change the contents or order never 
return the instance. Instead, they return an item from the instance or, more 
commonly, None."

B. Library Manual: Near the top of 4. Built-in Types, after "The principal 
built-in types are numerics, sequences, mappings, classes, instances and 
exceptions.", add something like

"Some collection classes are mutable. The methods that add, subtract, or 
rearrange their members never return the collection instance itself but instead 
return an item from the instance or None."

Comment: This rule applies to special methods like __getitem__ and __setitem__. 
'lis.append(item)' is equivalent to lis.__setitem__(len(lis):len(lis), item), 
so it should not be so surprising that it has the same return.

2. Document None returns explicitly.

They are currently documented implicitly, by absence.

A. Docstrings: Compare the relevant parts of the output from 
'help(list.append)' and 'help(list.pop)'

   L.append(object) -- append object to end
   L.pop([index]) -> item -- remove and return item at index 

Add ' -> None' to specify return for .append.
   L.append(object) -> None -- append object to end

I expect experienced Python programmers may object that this puts too much 
emphasis on the unimportant null return, but it is important that Python 
programmers know about it and experience shows that many newbies *need* that 
emphasis.

B. Doc entries: Essentially same suggestion -- add 'Return None.' to 
appropriate entries in tutorial chapter 5. For library manual, possibly add 
footnote '(9) Returns None' to the method table in 4.6.4. Mutable Sequence 
Types. For sets and dicts, add 'and return None' to appropriate entries.

----------
assignee: docs@python
components: Documentation
messages: 137009
nosy: docs@python, terry.reedy
priority: normal
severity: normal
status: open
title: Doc that collection mutation methods return item or None
versions: Python 2.7, Python 3.2, Python 3.3

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue12192>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to