Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

in get_type_hints(Appliction), TypeError: <class 'traitlets.traitlets.Dict'> is not a generic class

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

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
45/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
停滞
技术栈
python

调研方向

从 traitlets/config/application.py 第 403 行开始,并结合 traitlets/traitlets.py 第 3842 行检查 subcommands 注解,然后使用提供的 get_type_hints(Application) 示例复现该故障。完成的标准是:该注解描述实例字典的值,而不包含非泛型的 Dict trait 类型,并且 get_type_hints(Application) 不再引发此 TypeError。

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

描述

The expression get_type_hints(Application) raises an exception, given the class traitlets.config.application.Application or a subclass.

Minimal Example

file traitlets_debug_00.py

from traitlets.config.application import Application
from typing_extensions import get_type_hints

if __name__ == "__main__":
    hints = get_type_hints(Application)

Traceback from __main__:

Traceback (most recent call last):
  File ".../traitlets_debug_00.py", line 6, in <module>
    hints = get_type_hints(Application)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/typing.py", line 2305, in get_type_hints
    value = _eval_type(value, base_globals, base_locals)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/typing.py", line 359, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/typing.py", line 857, in _evaluate
    eval(self.__forward_code__, globalns, localns),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 1, in <module>
  File "/usr/lib64/python3.11/typing.py", line 344, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/typing.py", line 1807, in __class_getitem__
    _check_generic(cls, params, len(cls.__parameters__))
  File "/usr/lib64/python3.11/typing.py", line 271, in _check_generic
    raise TypeError(f"{cls} is not a generic class")
TypeError: <class 'traitlets.traitlets.Dict'> is not a generic class
Analysis

in traitlets.traitlets line 3842, the Dict TraitType is defined like as follows:

class Dict(Instance["dict[K, V]"]):
   ...

In traitlets.config.application, line 403, the type is applied as:

    subcommands: dict[str, t.Any] | Dict[str, t.Any] = Dict()

The Dict TraitType has not been defined as a subscriptable type, however.

Patch?

At an instance scope, the value of the subcommands attribute should generally be a Python dict, while at a class scope, the attribute would be represented with a TraitType descriptor, namely an instance of the Dict TraitType.

As per the note about the syntax of the subcommands value in the source code where the attr is defined, the subcommands attr could be defined as follows:

    subcommands: dict[str, tuple[Callable, str]] = Dict()

In effect, this would remove the class-scoped Dict TraitType descriptor from the type hint for the instance-scoped subcommands attribute value, also providing some more detail about the syntax of the attribute value.

The initialization of the subcommands descriptor object would not be changed with this definition.

Workarounds?

As one approach, the following can be used to patch the annotation in the base Application class, while providing an Application-like class with the patched type hint:

from traitlets.config.application import Application
from traitlets.traitlets import Dict
from collections.abc import Callable
import typing as t

class ApplicationShim(Application):
    subcommands: dict[str, tuple[t.Union[str, Callable[[t.Self], t.Self]], str]] = Dict()

Application.__annotations__['subcommands'] = ApplicationShim.__annotations__['subcommands']

The type hint in this patch is referenced to how the attribute value is applied in Application.initialize_subcommand() with examples for how the subcommands value is defined as a class variable, in the following:

  • IPython.core.profileapp.ProfileApp
  • jupyter_client.kernelspecapp.KernelSpecApp
  • ipykernel.kernelapp.IPKernelApp
  • ipyparallel.cluster.app.IPCluster

To apply the patched type hint insofar as may be visible within editor environments for instance, the class ApplicationShim could be used as a base class in lieu of Application. The patch onto the base subcommands annotation would be the main thing, however, insofar as for application with get_type_hints()

Impacts?

This exception is encountered when calling get_type_hints(Application).

This may affect some reflection-oriented user code and could possibly affect type analysis for the Application class

主要语言
Python
星标
653
派生
217
平均合并
2 天 21 小时
30 天内合并 PR
2

贡献指南

打开贡献指南

从这里开始

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

ipython/traitlets 的其他 Issue

查看 ipython/traitlets 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

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