Skip to content

[Bug] Self is not evaluating correclty in some cases #123

Description

@iliyasone

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__'?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions