-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Believe more __new__ return types #16020
base: master
Are you sure you want to change the base?
Changes from 6 commits
4616fa2
e2d3a5e
2bd91d5
393b303
7b7d76d
aa5df74
59a5aee
cdccffa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -371,8 +371,27 @@ def validate_super_call(node: FuncBase, mx: MemberContext) -> None: | |||||
def analyze_type_callable_member_access(name: str, typ: FunctionLike, mx: MemberContext) -> Type: | ||||||
# Class attribute. | ||||||
# TODO super? | ||||||
ret_type = typ.items[0].ret_type | ||||||
item = typ.items[0] | ||||||
ret_type = item.ret_type | ||||||
assert isinstance(ret_type, ProperType) | ||||||
|
||||||
# The following is a hack. mypy often represents types as CallableType, where the signature of | ||||||
# CallableType is determined by __new__ or __init__ of the type (this logic is in | ||||||
# type_object_type). Then if we ever need the TypeInfo or an instance of the type, we fish | ||||||
# around for the return type in CallableType.type_object. Unfortunately, this is incorrect if | ||||||
# __new__ returns an unrelated type, but we can kind of salvage things by fishing around in | ||||||
# CallableType.bound_args | ||||||
self_type: Type = typ | ||||||
if len(item.bound_args) == 1 and item.bound_args[0]: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with other comments that using It seems like the above should also fix the issue that no error is currently reported here, and perhaps other related issues:
We'd use use the new attribute when looking up class attributes. |
||||||
bound_arg = get_proper_type(item.bound_args[0]) | ||||||
if isinstance(bound_arg, Instance) and isinstance(ret_type, Instance): | ||||||
# Unfortunately, generic arguments have already been determined for us. We need these, | ||||||
# see e.g. testGenericClassMethodUnboundOnClass. So just copy them over to our type. | ||||||
# This does the wrong thing with custom __new__, see testNewReturnType15, but is | ||||||
# no worse than previous behaviour. | ||||||
ret_type = bound_arg.copy_modified(args=ret_type.args) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe you can
Suggested change
if you change checkexpr.py's return callable.copy_modified(
ret_type=expand_type(callable.ret_type, id_to_type),
+ bound_args=[
+ expand_type(ba, id_to_type) if ba is not None else None
+ for ba in callable.bound_args
+ ],
variables=remaining_tvars,
type_guard=type_guard,
) |
||||||
self_type = TypeType(ret_type) | ||||||
|
||||||
if isinstance(ret_type, TupleType): | ||||||
ret_type = tuple_fallback(ret_type) | ||||||
if isinstance(ret_type, TypedDictType): | ||||||
|
@@ -394,7 +413,11 @@ def analyze_type_callable_member_access(name: str, typ: FunctionLike, mx: Member | |||||
# See https://github.com/python/mypy/pull/1787 for more info. | ||||||
# TODO: do not rely on same type variables being present in all constructor overloads. | ||||||
result = analyze_class_attribute_access( | ||||||
ret_type, name, mx, original_vars=typ.items[0].variables, mcs_fallback=typ.fallback | ||||||
ret_type, | ||||||
name, | ||||||
mx.copy_modified(self_type=self_type), | ||||||
original_vars=typ.items[0].variables, | ||||||
mcs_fallback=typ.fallback, | ||||||
) | ||||||
if result: | ||||||
return result | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do we do this? This function certainly didn't, going for simple
.ret_type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I clarified the comment a little bit.
type_object
also just usesret_type
. Also, thanks for the suggestion to use bound_args, I added you as a co-author of this PR!