[issue24721] The result of calling dict.* methods on OrderedDict is undefined.

2015-07-26 Thread Mark Shannon

Mark Shannon added the comment:

I think this is a bug. This is not a normal case of subclassing as the 
interpreter calls the C API PyDict_XXX() in many cases where a dictionary 
subclass is passed in.

For example:
class C: pass
c = C()
# Liskov substitution principle says this is OK.
c.__dict__ = OrderedDict() 
c.a = 1

All access to the ordered dict is via the dict.__setitem__ method.

I think this should be documented.

--
nosy: +Mark.Shannon

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24721] The result of calling dict.* methods on OrderedDict is undefined.

2015-07-25 Thread Raymond Hettinger

Changes by Raymond Hettinger :


--
resolution:  -> not a bug
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24721] The result of calling dict.* methods on OrderedDict is undefined.

2015-07-25 Thread Eric Snow

Eric Snow added the comment:

Feel free to close this, Raymond.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24721] The result of calling dict.* methods on OrderedDict is undefined.

2015-07-25 Thread Eric Snow

Eric Snow added the comment:

Ah, you're right.  I was hung up on issue10977. :)

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24721] The result of calling dict.* methods on OrderedDict is undefined.

2015-07-25 Thread Raymond Hettinger

Raymond Hettinger added the comment:

> This is a consequence of subclassing a builtin type

Not really.  This is how subclassing works in general.  Any time you a user 
calls a parent class directly on an instance of subclass, they are bypassing 
whatever the subclass needs to do to maintain its invariants.

class A:
def __init__(self):
self.data = []
def add(self, x):
self.data.append(x)

class B(A):
'Track the number of odds'
def __init__(self):
A.__init__(self)
self.odds = 0
def add(self, x):
A.add(self, x)
self.odds += (x % 2)

b = B()
b.add(1)
b.add(2)
b.add(3)
b.add(4)
A.add(b, 5)
assert b.odds == sum(x%1 for x in b.data), 'OMG, B is broken!'

There is nothing special about OrderedDicts in this regard.  Perhaps there 
should be a FAQ entry regarding the "facts of life" in the world of object 
oriented programming.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24721] The result of calling dict.* methods on OrderedDict is undefined.

2015-07-25 Thread Raymond Hettinger

Changes by Raymond Hettinger :


--
assignee: docs@python -> rhettinger

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24721] The result of calling dict.* methods on OrderedDict is undefined.

2015-07-25 Thread Eric Snow

New submission from Eric Snow:

(see issue24667)

collections.OrderedDict subclasses dict so calling dict's methods on an 
OrderedDict works.  However, neither the pure Python nor the C implementation 
of OrderedDict was written to support doing so.  In fact, both of them 
currently enter an inconsistent state when this happens.  For example:

# Python 3.4 (pure Python implementation)
>>> from collections import OrderedDict
>>> od = OrderedDict([('spam', 1), ('eggs', 2)])
>>> dict.__delitem__(od, 'spam')
>>> str(od)
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.4/reprlib.py", line 24, in wrapper
result = user_function(self)
  File "/usr/lib/python3.4/collections/__init__.py", line 198, in __repr__
return '%s(%r)' % (self.__class__.__name__, list(self.items()))
  File "/usr/lib/python3.4/_collections_abc.py", line 485, in __iter__
yield (key, self._mapping[key])
KeyError: 'spam'

# Python 3.5 (C implementation)
>>> from collections import OrderedDict
>>> od = OrderedDict([('spam', 1), ('eggs', 2)])
>>> dict.__delitem__(od, 'spam')
>>> str(od)
Traceback (most recent call last):
  File "", line 1, in 
KeyError: 'spam'

This is a consequence of subclassing a builtin type, which typically do not 
have good support for subclassing (e.g. issue10977).

It probably isn't worth making any changes to the code of either OrderedDict 
implementations.  At most I'd recommend a note in the OrderedDict documentation 
indicating that the results of passing an OrderedDict object to dict.* methods 
are undefined.

--
assignee: docs@python
components: Documentation
messages: 247354
nosy: docs@python, eric.snow, rhettinger
priority: low
severity: normal
status: open
title: The result of calling dict.* methods on OrderedDict is undefined.
type: behavior
versions: Python 2.7, Python 3.4, Python 3.5, Python 3.6

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com