vercel-labs / vercel-labs/python-typemap
[Bug] `Self` is not evaluating correclty in some cases
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 25
- Forks
- 3
- PR merge metrics
- No merged PRs in 30d
Description
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__'?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the failure in test_self.py, then trace the stack through typemap/type_eval/_eval_call.py, _eval_typing.py, _apply_generic.py, and _eval_operators.py, especially the Attrs evaluation and generic boxing path. Done means the example evaluates User.model_dump without the AttributeError and produces the expected type for Self.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 42/100