Skip to content
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

mypy incorrectly disallows "yield from ()" #4444

Closed
kamahen opened this issue Jan 8, 2018 · 7 comments · Fixed by #6902
Closed

mypy incorrectly disallows "yield from ()" #4444

kamahen opened this issue Jan 8, 2018 · 7 comments · Fixed by #6902
Labels
bug mypy got something wrong priority-1-normal

Comments

@kamahen
Copy link
Contributor

kamahen commented Jan 8, 2018

yield from [] is allowed by mypy

yield from () gives:

error: "yield from" can't be applied to "Tuple[]"
@ilevkivskyi
Copy link
Member

Hm, apparently this is is because Tuple is not iterable :-) see in checker.py:

        return (is_subtype(type, self.named_generic_type('typing.Iterable',
                                                         [AnyType(TypeOfAny.special_form)])) and
                isinstance(type, Instance))

I have no idea why one needs that last ... and isinstance(type, Instance). Anyway this should be a trivial fix, by either removing this or at least changing to isinstance(type, (TupleType, Instance)).

@hoefling
Copy link
Contributor

hoefling commented Jan 12, 2018

Trying to test things out; apparently, removal of the isinstance(type, Instance) check fails the tests.

Failing tests output

$ pytest -v -n0 mypy/test/testcheck.py::TypeCheckSuite::testInitializationWithMultipleValues mypy/test/testcheck.py::TypeCheckSuite::testMultipleAssignmentWithNonTupleRvalue
================================================== test session starts ==================================================
platform darwin -- Python 3.6.3, pytest-3.3.1, py-1.5.2, pluggy-0.6.0 -- /Users/hoefling/.virtualenvs/mypy-py36/bin/python3.6
cachedir: .cache
rootdir: /Users/hoefling/projects/python/mypy, inifile: pytest.ini
plugins: xdist-1.20.1, forked-0.2, cov-2.5.1
collected 2 items

mypy/test/testcheck.py::TypeCheckSuite::testInitializationWithMultipleValues <- /Users/hoefling/projects/python/mypy/test-data/unit/check-tuples.test FAILED [ 50%]
mypy/test/testcheck.py::TypeCheckSuite::testMultipleAssignmentWithNonTupleRvalue <- /Users/hoefling/projects/python/mypy/test-data/unit/check-tuples.test FAILED [100%]

======================================================= FAILURES ========================================================
_________________________________________ testInitializationWithMultipleValues __________________________________________
data: /Users/hoefling/projects/python/mypy/test-data/unit/check-tuples.test:285:
SystemExit: 1
------------------------------------------------- Captured stdout call --------------------------------------------------
main:4: error: Incompatible types in assignment (expression has type "A", variable has type "B")
main:5: error: Incompatible types in assignment (expression has type "B", variable has type "A")
main:6: error: '__main__.A' object is not iterable
Traceback (most recent call last):
  File "/Users/hoefling/.virtualenvs/mypy-py36/bin/pytest", line 11, in <module>
    sys.exit(main())
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/config.py", line 59, in main
    return config.hook.pytest_cmdline_main(config=config)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/main.py", line 134, in pytest_cmdline_main
    return wrap_session(config, _main)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/main.py", line 103, in wrap_session
    session.exitstatus = doit(config, session) or 0
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/main.py", line 141, in _main
    config.hook.pytest_runtestloop(session=session)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/main.py", line 164, in pytest_runtestloop
    item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 62, in pytest_runtest_protocol
    runtestprotocol(item, nextitem=nextitem)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 76, in runtestprotocol
    reports.append(call_and_report(item, "call", log))
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 155, in call_and_report
    call = call_runtest_hook(item, when, **kwds)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 175, in call_runtest_hook
    return CallInfo(lambda: ihook(item=item, **kwds), when=when)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 189, in __init__
    self.result = func()
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 175, in <lambda>
    return CallInfo(lambda: ihook(item=item, **kwds), when=when)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 106, in pytest_runtest_call
    item.runtest()
  File "/Users/hoefling/projects/python/mypy/mypy/test/data.py", line 618, in runtest
    self.parent.obj(update_data=update_data).run_case(self.case)
  File "/Users/hoefling/projects/python/mypy/mypy/test/testcheck.py", line 113, in run_case
    self.run_case_once(testcase)
  File "/Users/hoefling/projects/python/mypy/mypy/test/testcheck.py", line 177, in run_case_once
    alt_lib_path=test_temp_dir)
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 172, in build
    result = _build(sources, options, alt_lib_path, bin_dir, saved_cache, flush_errors)
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 258, in _build
    graph = dispatch(sources, manager)
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 2048, in dispatch
    process_graph(graph, manager)
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 2349, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 2525, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 1923, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 228, in check_first_pass
    self.accept(d)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 323, in accept
    stmt.accept(self)
  File "/Users/hoefling/projects/python/mypy/mypy/nodes.py", line 807, in accept
    return visitor.visit_assignment_stmt(self)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 1378, in visit_assignment_stmt
    self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None, s.new_syntax)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 1406, in check_assignment
    infer_lvalue_type)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 1657, in check_assignment_to_multiple_lvalues
    self.check_multi_assignment(lvalues, rvalue, context, infer_lvalue_type)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 1705, in check_multi_assignment
    context, infer_lvalue_type)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 1869, in check_multi_assignment_from_iterable
    item_type = self.iterable_item_type(cast(Instance, rvalue_type))
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 3135, in iterable_item_type
    self.lookup_typeinfo('typing.Iterable'))
  File "/Users/hoefling/projects/python/mypy/mypy/maptype.py", line 16, in map_instance_to_supertype
    if instance.type == superclass:
AttributeError: 'NoneTyp' object has no attribute 'type'
------------------------------------------------- Captured stderr call --------------------------------------------------
main:7: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.570-dev-468dff257b969534f1a84d55696725c1a5f14b43-dirty
main:7: : note: use --pdb to drop into pdb
_______________________________________ testMultipleAssignmentWithNonTupleRvalue ________________________________________
data: /Users/hoefling/projects/python/mypy/test-data/unit/check-tuples.test:301:
SystemExit: 1
------------------------------------------------- Captured stdout call --------------------------------------------------
Traceback (most recent call last):
  File "/Users/hoefling/.virtualenvs/mypy-py36/bin/pytest", line 11, in <module>
    sys.exit(main())
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/config.py", line 59, in main
    return config.hook.pytest_cmdline_main(config=config)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/main.py", line 134, in pytest_cmdline_main
    return wrap_session(config, _main)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/main.py", line 103, in wrap_session
    session.exitstatus = doit(config, session) or 0
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/main.py", line 141, in _main
    config.hook.pytest_runtestloop(session=session)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/main.py", line 164, in pytest_runtestloop
    item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 62, in pytest_runtest_protocol
    runtestprotocol(item, nextitem=nextitem)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 76, in runtestprotocol
    reports.append(call_and_report(item, "call", log))
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 155, in call_and_report
    call = call_runtest_hook(item, when, **kwds)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 175, in call_runtest_hook
    return CallInfo(lambda: ihook(item=item, **kwds), when=when)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 189, in __init__
    self.result = func()
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 175, in <lambda>
    return CallInfo(lambda: ihook(item=item, **kwds), when=when)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hoefling/.virtualenvs/mypy-py36/lib/python3.6/site-packages/_pytest/runner.py", line 106, in pytest_runtest_call
    item.runtest()
  File "/Users/hoefling/projects/python/mypy/mypy/test/data.py", line 618, in runtest
    self.parent.obj(update_data=update_data).run_case(self.case)
  File "/Users/hoefling/projects/python/mypy/mypy/test/testcheck.py", line 113, in run_case
    self.run_case_once(testcase)
  File "/Users/hoefling/projects/python/mypy/mypy/test/testcheck.py", line 177, in run_case_once
    alt_lib_path=test_temp_dir)
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 172, in build
    result = _build(sources, options, alt_lib_path, bin_dir, saved_cache, flush_errors)
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 258, in _build
    graph = dispatch(sources, manager)
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 2048, in dispatch
    process_graph(graph, manager)
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 2349, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 2525, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/Users/hoefling/projects/python/mypy/mypy/build.py", line 1923, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 228, in check_first_pass
    self.accept(d)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 323, in accept
    stmt.accept(self)
  File "/Users/hoefling/projects/python/mypy/mypy/nodes.py", line 807, in accept
    return visitor.visit_assignment_stmt(self)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 1378, in visit_assignment_stmt
    self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None, s.new_syntax)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 1406, in check_assignment
    infer_lvalue_type)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 1657, in check_assignment_to_multiple_lvalues
    self.check_multi_assignment(lvalues, rvalue, context, infer_lvalue_type)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 1705, in check_multi_assignment
    context, infer_lvalue_type)
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 1869, in check_multi_assignment_from_iterable
    item_type = self.iterable_item_type(cast(Instance, rvalue_type))
  File "/Users/hoefling/projects/python/mypy/mypy/checker.py", line 3135, in iterable_item_type
    self.lookup_typeinfo('typing.Iterable'))
  File "/Users/hoefling/projects/python/mypy/mypy/maptype.py", line 16, in map_instance_to_supertype
    if instance.type == superclass:
AttributeError: 'NoneTyp' object has no attribute 'type'
------------------------------------------------- Captured stderr call --------------------------------------------------
main:5: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.570-dev-468dff257b969534f1a84d55696725c1a5f14b43-dirty
main:5: : note: use --pdb to drop into pdb
=============================================== 2 failed in 2.77 seconds ================================================

@ilevkivskyi
Copy link
Member

@hoefling Have you tried the second idea I mentioned? But in any case it looks like this requires a more careful solution than I thought.

@hoefling
Copy link
Contributor

Adding the TupleType does not fail the existing tests. However, I have added another test to reproduce this issue. In test-data/unit/check-tuples.test:

[case testYieldFromEmptyTuple]
from typing import Iterator
def f() -> Iterator:
    yield from ()
[out]

On the current master, the test fails with the message: main:3: error: "yield from" can't be applied to "Tuple[]" (diff).

Unfortunately, with the TupleType the test also fails with another message: main: error: "Tuple[]" has no attribute "__iter__" (diff). You can see the detailed error message in the travis build.

I'm not sure, though, if I wrote the test correctly - please double-check.

@ilevkivskyi
Copy link
Member

Yes, this is what I was afraid of, this will require some treatment of tuple fallbacks (and they have their own issues).

@nitzo
Copy link

nitzo commented May 16, 2019

ping

@ethanhs
Copy link
Collaborator

ethanhs commented May 17, 2019

@nitzo please do not ping the mypy bug tracker like this. It is quite rude. If an issue hasn't been fixed yet, it is because people are hard at work on other features. If you want to see something fixed sooner, submit a PR for it

ilevkivskyi pushed a commit that referenced this issue Jun 2, 2019
Fixes #4444 by removing special-casing for instance types.
Now `yield from <tuple>` works as expected.
PattenR pushed a commit to PattenR/mypy that referenced this issue Jun 23, 2019
Fixes python#4444 by removing special-casing for instance types.
Now `yield from <tuple>` works as expected.
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-1-normal
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants