Skip to content

map with lambda is broken in Python 2; gives '<Erased>' object is not iterable #5210

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

Closed
gvanrossum opened this issue Jun 12, 2018 · 2 comments · Fixed by #5211
Closed

map with lambda is broken in Python 2; gives '<Erased>' object is not iterable #5210

gvanrossum opened this issue Jun 12, 2018 · 2 comments · Fixed by #5211
Assignees
Labels
bug mypy got something wrong priority-0-high

Comments

@gvanrossum
Copy link
Member

@Michael0x2a
This is a regression caused by your PR: f61c2ba Overhaul overload semantics, remove erasure, add union math (#5084).

Example (only works with Python 2 -- it's a syntax error with Python 3):

a = [(1, ''), (2, '')]
b = map(lambda (i, s): str(i) + s, a)

Before that PR, this would pass; now it gives

_.py:2: error: '<Erased>' object is not iterable

Simplifying this further by using a list of ints and a lambda with a non-unpacking argument makes the error going away.

Sorry for being so aggressive with priority etc., this prevents us from using master on our internal code base -- we get a dozen or so of errors due to this. It's not limited to map() -- I see it too for reduce(), imap(), and ifilter(), always with lambda (x, y): ....

@gvanrossum
Copy link
Member Author

Actually I'm not sure if it occurs with ifilter() -- the one occurrence is inside an imap() call:

        owners = imap(lambda (k, v): 'owner=' + k,
                ifilter(lambda (k, v): v > SET_SIZE_LOW_CUTOFF, count_by_owner.iteritems()))

All the other functions involved are overloaded. Oh, I also saw an occurrence with max(), which is also overloaded.

@gvanrossum
Copy link
Member Author

There's also one occurence of

'<nothing>' object is not iterable

on a map(None, ...) call -- not a lambda in sight.

Also, it's not due to the typeshed changes -- I didn't bother changing typeshed when bisecting.

Michael0x2a added a commit to Michael0x2a/mypy that referenced this issue Jun 12, 2018
Fixes python#5210 (?)

When mypy tries selecting an appropriate overload alternative, it swaps
out the current 'msg' object with a placeholder. If this placeholder
does not accumulate any error messages, we know that alternative is a
successful match.

Previously, we replaced only checkexpr.ExpressionChecker's msg object
with the placeholder. However, since checkexpr can sometimes call
checker.TypeChecker, we need to replace its msg object as well to
prevent error messages that would normally be silenced from leaking.

More broadly, the current overload implementation broke the invariant
that both msg fields refer to the same underlying MessageBuilder object.
This pull request fixes that oversight.
Michael0x2a added a commit that referenced this issue Jun 13, 2018
Fixes #5210

When mypy tries selecting an appropriate overload alternative, it swaps
out the current 'msg' object with a placeholder. If this placeholder
does not accumulate any error messages, we know that alternative is a
successful match.

Previously, we replaced only checkexpr.ExpressionChecker's msg object
with the placeholder. However, since checkexpr can sometimes call
checker.TypeChecker, we need to replace its msg object as well to
prevent error messages that would normally be silenced from leaking.

More broadly, the current overload implementation broke the invariant
that both msg fields refer to the same underlying MessageBuilder object.
This pull request fixes that oversight.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong priority-0-high
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants