Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Subclasses vs union of types vs TypeVar#2039

Answeredbysrittau
hunterhogan asked this question inQ&A
Discussion options

I think I have major flaws in my understanding of subclasses of a type (e.g.,ast.AST andast.Module), a union of types (e.g.,type hasDOTarg = ast.arg | ast.keyword), andTypeVar (e.g.,kuo = typing_TypeVar('kuo', bound=ast.stmt, covariant=True). I don't have an intelligent question, though. I suspect one of my following beliefs is wrong or at least incomplete.

Given

defImaFunction(goat:ImaType):pass
  • If the type isast.AST, I thinkast.Module will match.
  • If the type ishasDOTarg, I thinkast.keyword will match.
  • If the type iskuo, I thinkast.Assign will match because it is a subclass ofast.stmt.

But, this system of usingTypeAlias, union, and subclasses, for example, doesn't always work when I expect it to work.

typehasDOTtarget_expr=ast.AsyncFor|ast.comprehension|ast.FortypehasDOTtarget_Name=ast.NamedExprtypehasDOTtarget_NameOrAttributeOrSubscript=ast.AnnAssign|ast.AugAssigntypehasDOTtarget=hasDOTtarget_expr|hasDOTtarget_Name|hasDOTtarget_NameOrAttributeOrSubscript...classDOT:@staticmethod@overloaddeftarget(node:hasDOTtarget_expr)->ast.expr:        ...@staticmethod@overloaddeftarget(node:hasDOTtarget_Name)->ast.Name:        ...@staticmethod@overloaddeftarget(node:hasDOTtarget_NameOrAttributeOrSubscript)->ast.Name|ast.Attribute|ast.Subscript:        ...@staticmethoddeftarget(node:hasDOTtarget)->ast.expr|ast.Name| (ast.Name|ast.Attribute|ast.Subscript):returnnode.target

As I said, I don't have an intelligent question. I know my mental model is wrong, but I'm lost.

You must be logged in to vote

Maybe this will help a bit:

  • If the type isast.AST, I thinkast.Module will match.
  • If the type ishasDOTarg, I thinkast.keyword will match.
  • If the type iskuo, I thinkast.Assign will match because it is a subclass ofast.stmt.

Unless I've overlooked something, this is correct, although I'd like to point out that a type var should always be used at least twice in a context to make sense. I.e.:

defImaFunction(goat:kuo):pass

Usingkuo here has no benefit and you could just useast.stmt directly instead.

But, this system of usingTypeAlias, union, and subclasses, for example, doesn't always work when I expect it to work.

[...]

@staticmethoddeftarget(node:hasDOTtarget)->

Replies: 1 comment 2 replies

Comment options

Maybe this will help a bit:

  • If the type isast.AST, I thinkast.Module will match.
  • If the type ishasDOTarg, I thinkast.keyword will match.
  • If the type iskuo, I thinkast.Assign will match because it is a subclass ofast.stmt.

Unless I've overlooked something, this is correct, although I'd like to point out that a type var should always be used at least twice in a context to make sense. I.e.:

defImaFunction(goat:kuo):pass

Usingkuo here has no benefit and you could just useast.stmt directly instead.

But, this system of usingTypeAlias, union, and subclasses, for example, doesn't always work when I expect it to work.

[...]

@staticmethoddeftarget(node:hasDOTtarget)->ast.expr|ast.Name| (ast.Name|ast.Attribute|ast.Subscript):returnnode.target

I don't have much to add here. The overloads make sense to me. Although there is currently some discussion about overload behavior, the overloads here seem to be non-overlapping. The only thing that stood out to me was using parentheses in the return type annotation of the implementation. To my knowledge, the meaning of grouping parentheses is currently not defined in the typing spec, so this could have unforeseen effects.

You must be logged in to vote
2 replies
@hunterhogan
Comment options

a type var should always be used at least twice in a context to make sense.

I have "reactions", but I still don't have a good question,per se.

@staticmethoddeftarget[:hasDOTtarget,归个:ast.expr|ast.Name|ast.Attribute|ast.Subscript](node:)->归个:returnnode.target

Analytically, this makes sense, but as you pointed out, it needs to make sense within the specification. I think that this does not work because, in part, neither TypeVar ("ge" and "guige") is used more than once.

@staticmethoddeftarget[:hasDOTtarget,归个:ast.expr|ast.Name|ast.Attribute|ast.Subscript](node:)->归个:returncast(归个,node.target)

I don't think thecast is valid because I don'tfeel that the symbol is defined in the scope. But I don't know what scope the definition has: just the signature?

Ithink theoverload definitions have the desired effect of type narrowing, so Ithink the aboveTypeVar would be redundant anyway.

"used twice",TypeAlias, andTypeVar

This statement is triggering my spidey sense--about a union of types:

a type var should always be used at least twice in a context to make sense.

For example, take:

=typing_TypeVar('工',bound=ast.expr,covariant=True)# "gong"...classGrab:@staticmethoddeftargetAttribute(action:Callable[[ast.Name],ast.Name] \|Callable[[ast.Name|ast.Attribute|ast.Subscript],ast.Name|ast.Attribute|ast.Subscript] \|Callable[[],])->Callable[[hasDOTtarget],hasDOTtarget]:defworkhorse(node:hasDOTtarget)->hasDOTtarget:setattr(node,'target',action(getattr(node,'target')))returnnodereturnworkhorse

I switched some annotations toTypeVar recently, and I'm not sure of their impact yet, but I am pretty sure it is not helping in this context. Because of what you wrote, I wonder ifhasDOTtarget is effectively acting as a type "widener" and saying the return is always a union of types. Until now, I guess I believed that if the "input" type wereast.Name and the annotation wasCallable[[hasDOTtarget], hasDOTtarget], then the type checker would treat the return asast.Name.

classThen:@staticmethoddefreplaceWith(this:归个)->Callable[[Any],归个]:returnlambda_replaceMe:this

The abovemight be working: as in, the type checkers are using this annotation to "transitively define" the type. "Transitive:" I have no idea what the correct term is, so I mean A = B, B = C, -> A = C.

Parentheses

the meaning of grouping parentheses is currently not defined in the typing spec

I hadn't considered that. I'll change that. Thank you.

@srittau
Comment options

I don't think thecast is valid because I don'tfeel that the symbol is defined in the scope. But I don't know what scope the definition has: just the signature?

Just one quick point: The scope of the type var is the whole function, but when I said "a type var should always be used at least twice in a context" I should have said "a type var should always be used at least twice in a signature" (which for classes includes the signature of its methods and attributes).

So the cast is not necessarily "wrong", but the type var is kind of redundant, because the following definition would basically be equivalent:

@staticmethoddeftarget(node:Any)->ast.expr|ast.Name|ast.Attribute|ast.Subscript:returncast(ast.expr|ast.Name|ast.Attribute|ast.Subscript,node.target)
Answer selected byhunterhogan
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Category
Q&A
Labels
None yet
2 participants
@hunterhogan@srittau

[8]ページ先頭

©2009-2025 Movatter.jp