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

[Bug] `Self` is not evaluating correclty in some cases

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

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
42/100
Issue 类型
缺陷
描述清晰度
需要澄清
活跃度
冷清
技术栈
python
领域
compilers

调研方向

在 test_self.py 中复现该失败,然后通过 typemap/type_eval/_eval_call.py、_eval_typing.py、_apply_generic.py 和 _eval_operators.py 跟踪调用栈,尤其关注 Attrs 评估和泛型 boxing 路径。完成标准是示例能够在不产生 AttributeError 的情况下评估 User.model_dump,并为 Self 生成预期类型。

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

描述

I am trying to make the real pydantic work using new types introduced into the PEP 827. I think the BaseModel.model_dump is a good start. It is always nice to have fully typed dictionary as a return, especially when unpacking with exclude or include params into another function.

But the problem is that this is not working. I tried fixing Attrs look up, so it is not evaluating broken if TYPE_CHECKING methods, see #122, but it is just opened a problem with a self.

I am guessing that the Self is not substituted with actual type at the right moment... I want to solve this issue, but it would require much deeper understanding of the repository and type system implementation. I would really appreciate any advice on which part of the system I should dive into to fix this.

from typing import Any, Literal, Self, cast
from typemap.type_eval import eval_call_with_types
import typemap_extensions as typing
from pydantic import BaseModel as _BaseModel


type ModelDump[T] = typing.NewTypedDict[
    *[
        typing.Member[field.name, field.type]
        for field in typing.Iter[typing.Attrs[T]]
        if typing.IsAssignable[field.definer, _BaseModel]
        and not typing.IsEquivalent[field.definer, _BaseModel]
        and not typing.IsEquivalent[
            typing.Slice[field.name, Literal[0], Literal[2]], Literal["__"]
        ]
    ]
]


class BaseModel(_BaseModel):
    def model_dump(self, **kwargs: Any) -> ModelDump[Self]:  # type: ignore[override]
        return cast(ModelDump[Self], super().model_dump(**kwargs))
    

class User(BaseModel):
    id: int
    name: str
    age: int

print(format_helper.format_class(eval_call_with_types(User.model_dump, User)))

Full error stack:

(metatypes) iliyasone@iliyasone:~/repositories/innopolis-courses/thesis/metatypes$ uv run test_self.py 
Traceback (most recent call last):
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/test_self.py", line 30, in <module>
    print(format_helper.format_class(eval_call_with_types(User.model_dump, User)),)
                                     ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_call.py", line 159, in eval_call_with_types
    return eval_func_with_type_vars(func, vars)
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_call.py", line 188, in eval_func_with_type_vars
    return _eval_call_with_type_vars(func, vars, ctx)
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_call.py", line 202, in _eval_call_with_type_vars
    return _eval_typing.eval_typing(rr["return"])
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_typing.py", line 193, in eval_typing
    result = _eval_types(obj, ctx)
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_typing.py", line 232, in _eval_types
    evaled = _eval_types_impl(obj, child_ctx)
  File "/usr/lib/python3.14/functools.py", line 982, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_typing.py", line 389, in _eval_applied_type_alias
    unpacked = _apply_generic.get_annotations(
        obj, named_args, key='evaluate_value'
    )
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_apply_generic.py", line 245, in get_annotations
    rr = ff(annotationlib.Format.VALUE)
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/test_self.py", line 10, in ModelDump
    for field in typing.Iter[typing.Attrs[T]]
                 ~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/typing.py", line 348, in __iter__
    return evaluator(self)
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_typing.py", line 138, in <lambda>
    lambda t: _eval_types(t, _current_context.get())  # type: ignore[arg-type]
              ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_typing.py", line 234, in _eval_types
    evaled = _eval_types_impl(obj, ctx)
  File "/usr/lib/python3.14/functools.py", line 982, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_typing.py", line 430, in _eval_applied_class
    new_args = _eval_args(typing.get_args(obj), ctx)
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_typing.py", line 339, in _eval_args
    ev = _eval_types(arg, ctx)
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_typing.py", line 234, in _eval_types
    evaled = _eval_types_impl(obj, ctx)
  File "/usr/lib/python3.14/functools.py", line 982, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_typing.py", line 440, in _eval_applied_class
    ret = func(*new_args, ctx=ctx)
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_operators.py", line 429, in wrapper
    func(*[_unwrap_anno(x) for x in xs], ctx=ctx)
    ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_operators.py", line 884, in _eval_Attrs
    hints = get_annotated_type_hints(
        tp, include_extras=True, attrs_only=True, ctx=ctx
    )
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_operators.py", line 112, in get_annotated_type_hints
    box = cached_box(cls, ctx=ctx)
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_eval_operators.py", line 95, in cached_box
    ctx.box_cache[cls] = box = _apply_generic.box(cls)
                               ~~~~~~~~~~~~~~~~~~^^^^^
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_apply_generic.py", line 141, in box
    return _box(cls, args)
  File "/home/iliyasone/repositories/innopolis-courses/thesis/metatypes/.venv/lib/python3.14/site-packages/typemap/type_eval/_apply_generic.py", line 100, in _box
    orig_bases = cls.__dict__.get("__orig_bases__")
                 ^^^^^^^^^^^^
  File "/usr/lib/python3.14/typing.py", line 538, in __getattr__
    raise AttributeError(item)
AttributeError: __dict__. Did you mean: '__dir__'?
主要语言
Python
星标
25
派生
3
平均合并
23 分钟
30 天内合并 PR
2

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

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

vercel-labs/python-typemap 的其他 Issue

查看 vercel-labs/python-typemap 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

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