-
-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Strange reversed dict behavior #82706
Comments
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> list(reversed({1: 1}))
[1]
>>> list(reversed({})) ================================ RESTART: Shell ================================
|
Outside of IDLE, the example causes a segfault. With debug build of current master HEAD: Assertion failed: (value != NULL), function dictreviter_iternext, file ../../source/Objects/dictobject.c, line 3834. if (d->ma_values) {
if (i < 0) {
goto fail;
}
key = DK_ENTRIES(k)[i].me_key;
value = d->ma_values[i];
assert (value != NULL);
} |
Thanks for the report, by the way! |
This issue is related to reversed dict iter. >>> a = reversed({})
>>> next(a)
Assertion failed: (value != NULL), function dictreviter_iternext, file Objects/dictobject.c, line 3834.
[1] 1366 abort ./python.exe |
>>> reversed({}.items())
<dict_reverseitemiterator object at 0x106a2bc50>
>>> a = reversed({}.items())
>>> next(a)
Assertion failed: (value != NULL), function dictreviter_iternext, file Objects/dictobject.c, line 3834.
[1] 4106 abort ./python.exe |
Can I take look at this issue? |
Wops, we made a PR at the same time, Dong-hee Na. I will close mine :) |
lol
Oh.. thank you for giving me a chance. |
The proposed fix fixes a crash, but there is other bug in iterating shared dicts. class A:
def __init__(self, x, y):
if x: self.x = x
if y: self.y = y
a = A(1, 2)
print(list(iter(a.__dict__)))
print(list(reversed(a.__dict__)))
b = A(1, 0)
print(list(iter(b.__dict__)))
print(list(reversed(b.__dict__))) With PR 16846 the last print outputs [] instead of expected ['x']. It crashes without PR 16846, so this issue is not only about empty dicts. |
Yes, you are right. |
FYI c = A(0, 1)
print(type(c.__dict__))
print(list(iter(c.__dict__)))
print(list(reversed(c.__dict__))) works as we expected. |
When dict is empty, di_pos of reverse iterator must be -1, not 0. diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 64876e0519..6c4b41700b 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -3452,10 +3452,15 @@ dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
di->di_dict = dict;
di->di_used = dict->ma_used;
di->len = dict->ma_used;
- if ((itertype == &PyDictRevIterKey_Type ||
- itertype == &PyDictRevIterItem_Type ||
- itertype == &PyDictRevIterValue_Type) && dict->ma_used) {
+ if (itertype == &PyDictRevIterKey_Type ||
+ itertype == &PyDictRevIterItem_Type ||
+ itertype == &PyDictRevIterValue_Type) {
+ if (dict->ma_values) {
+ di->di_pos = dict->ma_used - 1;
+ }
+ else {
di->di_pos = dict->ma_keys->dk_nentries - 1;
+ }
}
else { |
Closing this. Thanks, Dong-hee Na and everyone involved in the issue! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: