-
-
Notifications
You must be signed in to change notification settings - Fork 3k
[mypyc] Fix AttributeError in async try/finally with mixed return paths #19361
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
Changes from 2 commits
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 |
---|---|---|
|
@@ -799,6 +799,24 @@ def accept(self, visitor: OpVisitor[T]) -> T: | |
return visitor.visit_get_attr(self) | ||
|
||
|
||
class GetAttrNullable(GetAttr): | ||
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. It would be more consistent with other ops to add a new flag to (Your approach clearly has some benefits over adding a flag, as it's arguably easy to forget to handle the flag in a visitor, but since we already have a bunch of flags that impact the semantics in 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 used the flag approach somewhere in my journey, my concern was that this might reduce performance as every GetAttr would be a tiny bit slower. That being said, if you prefer to have it that way, I guess I can make the change. 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 expect the performance impact to be quite small, since checking a boolean flag is quick (here branch prediction success rate should be high). I try to avoid subclasses of concrete classes such as |
||
"""obj.attr (for a native object) - allows NULL without raising AttributeError | ||
|
||
This is used for spill targets where NULL indicates the non-return path was taken. | ||
Unlike GetAttr, this won't raise AttributeError when the attribute is NULL. | ||
""" | ||
|
||
error_kind = ERR_NEVER | ||
|
||
def __init__(self, obj: Value, attr: str, line: int, *, borrow: bool = False) -> None: | ||
super().__init__(obj, attr, line, borrow=borrow) | ||
# Override error_kind since GetAttr sets it based on attr_type.error_overlap | ||
self.error_kind = ERR_NEVER | ||
|
||
def accept(self, visitor: OpVisitor[T]) -> T: | ||
return visitor.visit_get_attr_nullable(self) | ||
|
||
|
||
class SetAttr(RegisterOp): | ||
"""obj.attr = src (for a native object) | ||
|
||
|
@@ -1728,6 +1746,10 @@ def visit_load_literal(self, op: LoadLiteral) -> T: | |
def visit_get_attr(self, op: GetAttr) -> T: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def visit_get_attr_nullable(self, op: GetAttrNullable) -> T: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def visit_set_attr(self, op: SetAttr) -> T: | ||
raise NotImplementedError | ||
|
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.
If you implement the suggestion to not use a subclass, it still makes sense to keep this code in a separate method that is called from the
visit_get_attr
handler if the flag is set.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.
Not sure I understand what you mean here
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.
Even if the functionality is merged from
GetAttrNullable
into theGetAttr
class, and there is no longer avisit_get_attr_nullable
method inOpVisitor
, the code here doesn't need to be merged into thevisit_get_attr
method, but this method can be renamed and called fromvisit_get_attr
method to handle the nullable case. I.e.visit_get_attr
could look like this (some details omitted):