使用在类型注释中声明但未定义的Typealias?

发布于 2025-01-30 18:31:41 字数 1517 浏览 3 评论 0原文

更新:在评论中收到的答案,我修改了一个问题,强调我真正想知道的是:

(1)是否有任何深层理由 python的类型系统不允许我想完成的工作? (例如,它是如何实现的。)

另外,如果(1)的答案为负面,我想我会对答案感兴趣:

(2)是否有其他方法(在Python中)完成我尝试的工作?

下面的原始问题(仅略有编辑)。


我正在使用Python  3.10.4,并兴奋地尝试现在似乎是一个非常成熟的系统(至少与我上次做一些严肃的Python事情相比)。

但是,在类型注释中使用已声明但未定义的Typealias不起作用,但会出现运行时错误。为什么?从理论上讲,在我的特殊情况下,我认为没有问题,但是也许还有一些更深的原因为什么Python的类型系统这样可以使用? (当我试图在声明后定义典型的错误时,Pyright错误时,也许有充分的理由不应该这样做。此外,这会导致Pyright不报告以后的类型违规。)

更详细地考虑以下示例,使用以下示例在评论中指出了运行时错误和职业错误。

第一个示例,说明我要做的事情:

from typing import Literal, Final, TypeAlias


# PUBLIC_INTERFACE

a_type_alias : TypeAlias

# the following gives the runtime error:
# “NameError: name 'a_type_alias' is not defined. Did you mean: 'TypeAlias'?”
A_SET : Final[set[a_type_alias]]


# IMPLEMENTATION

a_type_alias = Literal[0,1] # Pyright error: “"a_type_alias" is declared as a
                            # TypeAlias and can be assigned only once”

A_SET = {0,1,2} # Pyright reports no error, but should be a type violation per
                # lines 10 and 15?

第二个示例,演示所有有效的东西:

from typing import Literal, Final, TypeAlias

a_type_alias : TypeAlias = Literal[0,1]

A_SET : Final[set[a_type_alias]]

# Pyright correctly reports type violation on the following assignment
A_SET = {0,1,2}

Å,我的意思是,类型注释a_set:final [set [a_type_alias]]在示例中不需要a_type_alias的值直到type-checking a_set在我的示例中,当已知a_type_alias的值时。

UPDATE: Given answer received in comments, I have amended the question, emphasizing that what I really want to know is:

(1) Is there any deep reason Python's type system does not allow what I want to accomplish? (Or is it, for example, just how it happens to be implemented.)

Also, if the answer to (1) is negative I guess I would be interested in an answer to:

(2) Is there any other way (in Python) to accomplish what I try to?

Original (only slightly edited) question below.


I am using Python 3.10.4 and excitedly trying out what now seems to be a quite mature type system (at least compared to when I last did some serious Python stuff).

However, using a declared but not defined TypeAlias in a type annotation does not work but gives a runtime error. Why? Theoretically, I see no problem in my particular case,¹ but perhaps there is some deeper reason for why Python's type system works this way? (Pyright errors when I try to define the TypeAlias after its declaration so perhaps there are good reasons that one should not do this. Also, this causes Pyright to not report a later type violation.)

In more detail, consider the following examples, with runtime errors and Pyright error pointed out in comments.

First example, demonstrating what I am trying to do:

from typing import Literal, Final, TypeAlias


# PUBLIC_INTERFACE

a_type_alias : TypeAlias

# the following gives the runtime error:
# “NameError: name 'a_type_alias' is not defined. Did you mean: 'TypeAlias'?”
A_SET : Final[set[a_type_alias]]


# IMPLEMENTATION

a_type_alias = Literal[0,1] # Pyright error: “"a_type_alias" is declared as a
                            # TypeAlias and can be assigned only once”

A_SET = {0,1,2} # Pyright reports no error, but should be a type violation per
                # lines 10 and 15?

Second example, demonstrating everything working:

from typing import Literal, Final, TypeAlias

a_type_alias : TypeAlias = Literal[0,1]

A_SET : Final[set[a_type_alias]]

# Pyright correctly reports type violation on the following assignment
A_SET = {0,1,2}

¹ By this, I mean that the type annotation A_SET : Final[set[a_type_alias]] in the examples does not need the value of a_type_alias until type-checking A_SET, which in my examples happens when the value of a_type_alias is known.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

止于盛夏 2025-02-06 18:31:41

以下工作是,a_type_alias的缺点未在##  interface; interface; interface part下明确声明。我看着 pep  563 最初使用___future__ import import import import import import import import import import import import import import import import import import intoctation ,但事实证明Pyright(Verison  1.1.247)类型在未来导入的情况下检查以下内容。

from typing import Literal, Final, TypeAlias


# PUBLIC_INTERFACE

set_1 : Final[set['a_type_alias']]
set_2 : Final[set['a_type_alias']]


# IMPLEMENTATION

a_type_alias : TypeAlias = Literal[0,1]

set_1 = {0}   # no error from Pyright (correct)
set_2 = {0,2} # error from Pyright (correct)

The following works, with the drawback that a_type_alias is not explicitly declared under the # PUBLIC INTERFACE part. I looked at PEP 563 and initially used a solution with from __future__ import annotations but turns out Pyright (verison 1.1.247) type checks the following with or without that future import.

from typing import Literal, Final, TypeAlias


# PUBLIC_INTERFACE

set_1 : Final[set['a_type_alias']]
set_2 : Final[set['a_type_alias']]


# IMPLEMENTATION

a_type_alias : TypeAlias = Literal[0,1]

set_1 = {0}   # no error from Pyright (correct)
set_2 = {0,2} # error from Pyright (correct)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文