| Summary: | Type not inferred when iterating objects with __next__ | ||
|---|---|---|---|
| Product: | [Developer tools] kdev-python | Reporter: | Nicolás Alvarez <nalvarez> |
| Component: | Language support | Assignee: | Sven Brauch <mail> |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | CC: | |
| Priority: | NOR | ||
| Version First Reported In: | 5.0.1 | ||
| Target Milestone: | 1.7.3 | ||
| Platform: | Other | ||
| OS: | Linux | ||
| Latest Commit: | https://commits.kde.org/kdev-python/e0a92aac7d716bf706205a913d92246716e8727e | Version Fixed/Implemented In: | 5.1.0 |
| Sentry Crash Report: | |||
By the way, as another example for the unit tests:
class Foo:
def __iter__(self):
return Bar()
def __next__(self):
return "blah"
class Bar:
def __next__(self):
return {}
for x in Foo():
pass
Here 'x' should be of type 'dict', not 'str'!
Valid issue but probably hard to fix given how it's implemented currently. :/ Git commit e0a92aac7d716bf706205a913d92246716e8727e by Francis Herne. Committed on 29/11/2016 at 23:05. Pushed by flherne into branch 'master'. Get iterable content using __iter__() and __next__(). Supports unpacking and iterating over custom sequence types. See tests for examples (by Nicolás Alvarez). Returning `iter(builtin_container)` isn't handled usefully because they use docstring cheats with no real return values. Differential Revision: https://phabricator.kde.org/D3540 M +4 -6 duchain/declarationbuilder.cpp M +3 -0 duchain/declarationbuilder.h M +1 -1 duchain/expressionvisitor.cpp M +31 -25 duchain/helpers.cpp M +1 -1 duchain/helpers.h M +21 -0 duchain/tests/pyduchaintest.cpp https://commits.kde.org/kdev-python/e0a92aac7d716bf706205a913d92246716e8727e |
If I have a generator implemented as a function, iterating over it with a for loop (or list comprehension) correctly deduces the type of the item variable: def gen1(): yield "blah" for item1 in gen1(): print(item1) Here, KDevelop knows item1 is a str, because that is what gen1 yields. However, if I do the same with a class that has a custom __next__ method, the type is not deduced: class Gen2: def __iter__(self): return self def __next__(self): return "blah" gen2 = Gen2() for item2 in gen2: print(item2) The tooltip shows item2 as 'mixed', its attributes are not highlighted or completed, etc. This affects a few built-in types, such as I/O classes that yield strings (lines) when iterated. (In many cases the definitions in documentation_files don't have a __next__ and they should, but the point of this bug is that adding the missing __next__ makes no difference)