classification
Title: Set operations don't work for dictionary views
Type: behavior Stage: resolved
Components: Versions: Python 2.7
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: alexandre.vassalotti Nosy List: akuchling, alexandre.vassalotti, belopolsky, eric.smith, ezio.melotti, rhettinger
Priority: release blocker Keywords: patch

Created on 2010-04-15 01:23 by akuchling, last changed 2010-05-06 15:33 by rhettinger. This issue is now closed.

Files
File name Uploaded Description Edit
fix_dictviews_set_operations.diff alexandre.vassalotti, 2010-04-17 21:48
issue8404_tests_py3k.diff Alexander.Belopolsky, 2010-04-29 14:50 Patch against py3k revision 80615
Messages (10)
msg103166 - (view) Author: A.M. Kuchling (akuchling) * (Python committer) Date: 2010-04-15 01:23
The examples of set operations in http://docs.python.org/dev/library/stdtypes#dictionary-view-objects don't work in the current 2.7 trunk:

-> ./python.exe
Python 2.7b1+ (trunk:80084:80085M, Apr 14 2010, 21:17:06) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> keys = dishes.viewkeys()
>>> keys & {'eggs', 'bacon', 'salad'}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'dict_keys' and 'set'
>>> keys | {'eggs'}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'dict_keys' and 'set'

Is this a documentation bug, and set operations are only supported in 3.x?  Or does the code need to be fixed?

(Assigned to Alexandre, since he committed the backport patch; please feel free to reassign.  Marking as release blocker; if it's a documentation bug, we can lower the priority.)
msg103177 - (view) Author: Alexandre Vassalotti (alexandre.vassalotti) * (Python committer) Date: 2010-04-15 02:15
It is a bug.

First, the dictviews_as_number is broken; the field for classic division was removed in 3.x, so everything is shifted by one. I included a patch to fix this.

Unfortunately, this isn't enough to fix the issue. There seems to be some overly restrictive type checking going on in the method wrappers. However, I don't have the time to investigate this further today. I should be able to check this next weekend.
msg103436 - (view) Author: Alexandre Vassalotti (alexandre.vassalotti) * (Python committer) Date: 2010-04-17 21:48
I found the issue. The view types didn't have Py_TPFLAGS_CHECKTYPES set, so the types were using the old-style binary operators.

Here's a patch that fixes the issue. Please review.
msg104517 - (view) Author: Alexander Belopolsky (Alexander.Belopolsky) Date: 2010-04-29 14:50
The patch looks fine.  I verified that the new tests pass on trunk and py3k.  I am attaching a patch for py3k with a forward port of set opereations and repr tests.
msg104911 - (view) Author: Alexandre Vassalotti (alexandre.vassalotti) * (Python committer) Date: 2010-05-04 03:50
Committed in r80749 and r80751 (for py3k).

Thank you!
msg105095 - (view) Author: A.M. Kuchling (akuchling) * (Python committer) Date: 2010-05-05 22:15
(commenting on a closed bug, because I'm not sure it should be re-opened)

While coming up with examples, I found a weird inconsistency.  Was it intentional for viewkeys() and viewitems() to support set operations, but not viewvalues()? 

>>> d1 = dict((i*10, chr(65+i)) for i in range(26))
>>> d2 = dict((i**.5, i) for i in range(1000))
>>> d1.viewkeys() | set('abc')
set([0, 130, 10, 140, 20, 150, 30, 160, 40, 170, 50, 180, 60, 190, 70, 200, 80, 210, 90, 220, 'a', 'c', 'b', 100, 230, 110, 240, 120, 250])
>>> d1.viewitems() | set('abc')
set([(70, 'H'), (0, 'A'), ....)
>>> d1.viewvalues() | set('abc')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'dict_values' and 'set' 
>>> d1.viewvalues() | d2.viewvalues()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'dict_values' and 'dict_values'
msg105097 - (view) Author: A.M. Kuchling (akuchling) * (Python committer) Date: 2010-05-05 22:19
The fix is easy, I think; just add Py_TPFLAGS_CHECKTYPES to the PyDictValues_Type's definition.
msg105106 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2010-05-05 22:49
Why do you expect dict_values to support set operations?  Dict values unlike keys are not sets, they are more like lists.  Set operations of dict_values are not supported in 3.x either.
msg105112 - (view) Author: A.M. Kuchling (akuchling) * (Python committer) Date: 2010-05-06 00:29
Ah, of course!  It didn't occur to me that .values() isn't necessarily a set.
msg105150 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2010-05-06 15:33
FWIW, this agrees with the specs in _abcoll which show KeysView and ItemsView as sets but not ValuesView.
History
Date User Action Args
2010-05-06 15:33:04rhettingersetnosy: + rhettinger
messages: + msg105150
2010-05-06 00:29:24akuchlingsetmessages: + msg105112
2010-05-05 22:49:19belopolskysetnosy: + belopolsky, - Alexander.Belopolsky
messages: + msg105106
2010-05-05 22:19:22akuchlingsetmessages: + msg105097
2010-05-05 22:15:18akuchlingsetmessages: + msg105095
2010-05-04 03:50:28alexandre.vassalottisetstatus: open -> closed
resolution: accepted
messages: + msg104911

stage: patch review -> resolved
2010-04-29 14:50:29Alexander.Belopolskysetfiles: + issue8404_tests_py3k.diff
nosy: + Alexander.Belopolsky
messages: + msg104517

2010-04-28 00:10:43terry.reedysetstage: needs patch -> patch review
2010-04-17 21:48:57alexandre.vassalottisetfiles: - fix_dictviews_as_number.diff
2010-04-17 21:48:32alexandre.vassalottisetfiles: + fix_dictviews_set_operations.diff

messages: + msg103436
2010-04-15 02:15:59alexandre.vassalottisetfiles: + fix_dictviews_as_number.diff
keywords: + patch
2010-04-15 02:15:35alexandre.vassalottisetmessages: + msg103177
2010-04-15 01:32:50eric.smithsetnosy: + eric.smith
2010-04-15 01:25:15ezio.melottisetnosy: + ezio.melotti

stage: needs patch
2010-04-15 01:23:46akuchlingcreate