Allow yielding result of function that returns None

未关闭
#1,933 6 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
25/100
Issue 类型
功能
描述清晰度
需要澄清
活跃度
停滞
技术栈
python
领域
compilers

调研方向

Start with the current-status comment linked in the issue, then inspect mypy/checker.py around the generator yield, receive, and return defaults and typeshed/stdlib/3/typing.pyi around Generator variance. Review PR #1808 and the disagreement over None, Void, and Any; done requires an agreed default behavior and corresponding type-checking coverage.

由索引模型根据 Issue 内容生成。

描述

bug false-positive priority-1-normal

UPDATE: see below for current status https://github.com/python/mypy/issues/1933#issuecomment-390018636

This is a spin-off from PR #1808. @ddfisher and I cannot agree on what the default type should be in the three methods get_generator_yield_type(), get_generator_receive_type(), get_generator_return_type().

The setting: when the user defines a generator function, they can specify a return type. The return type is required to be a supertype of Generator; this constrains it to Iterator, Iterable, object (and Any, which is special in other ways).

The Generator type has three type parameters:

  • ty, the yield type: the type of y in yield y
  • tc, the receive type: the type of c in c = yield ...
  • tr, the return type: the type of r in return r

Note that tr is fairly new -- it was introduced in Python 3.3 by PEP 380 for the benefit of yield from. tc is older, it dates back to Python 2.5 and PEP 342 (it is the value sent to the generator using the .send() method). ty is the oldest; when yield was originally introduced in Python 2.2 by PEP 255, it was a statement. Before PEP 380, return in a generator function was not allowed to return a value.

When a generator function is just intended to be used as an iterator, there's no need to specify tc and tr, and the recommended type is Iterator[ty]. (Iterable[ty] is also allowed and means roughly the same thing.) In this case the user of the iterator has no access to the .send() method. Hence, yield might as well be considered a statement, since it's never going to return anything other than None. Likewise, there's no point is returning a value with a return statement since the user of the iterator in all likelihood is just going to iterate over it until it raises StopIteration (since that's all that regular iterators do).

This is where @ddfisher and I disagree -- I find it useful if the defaults for tc and tr are None (or perhaps Void), so that mypy will flag an error in the generator body if you either try to use yield ... as an expression, or try to return a value using return <expr>. David (IIUC) believes that both should be Any, giving the reason that "it should be allow to pointless but harmless things." (The code currently has tc default to Void and tr default to Any. Go figure.)

My problem with David's position is that I want mypy to be strict about pointless things that are likely the result of either a misunderstanding or a refactoring gone bad. I have seen enough people make the mistake of accidentally writing return v instead of yield v in a generator that I want this to be flagged as an error. There's also the somewhat analogous case of a regular function declared to return None -- it would be pointless but harmless to return some value here, so maybe David believes that we shouldn't flag that as an error either?

I'm not sure why the existing code (written by David) has Void as the default for tc, but I think it may be because this parameter of Generator is contravariant. So hopefully we at least agree here. :-)

David, please feel free to explain your position more fully (I think you were calling on the formal type system but we ran out of time in our in-person discussion at that point).

主要语言
Python
星标
20.6k
派生
3.3k
平均合并
1 天 18 小时
30 天内合并 PR
54

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

python/mypy 的其他 Issue

查看 python/mypy 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。