-
Notifications
You must be signed in to change notification settings - Fork 144
Throws Bad Instantation Error when Creating an Instance of an Abstract Class #807
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
base: main
Are you sure you want to change the base?
Conversation
Hmm, mypy primer runs are panicking. We'll get this reviewed and see if we can figure out what's going on |
@@ -396,6 +396,18 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> { | |||
hint: Option<&Type>, | |||
) -> Type { | |||
// Based on https://typing.readthedocs.io/en/latest/spec/constructors.html. | |||
let instance_ty = Type::ClassType(cls.clone()); |
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.
this appears unused?
} | ||
|
||
// Recursively check base classes | ||
let metadata = self.get_metadata_for_class(class_obj); |
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 think we can pre-calculate inherits_from_abc
and store it in class metadata. cc @grievejia
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 like this idea, we could do something like:
pub struct ClassMetadata {
// ... existing fields ...
inherits_from_abc: bool, // New field
}
And then we could populate ABC Inheritance during class metadata creation.
match &field.0 { | ||
ClassFieldInner::Simple { ty, .. } => { | ||
if let Type::Function(function) = ty { | ||
if function.metadata.flags.is_abstract_method { |
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.
we might need to handle overloaded functions too
} | ||
|
||
/// Recursively collect abstract methods from a class and its bases | ||
fn collect_abstract_methods_from_class( |
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'm not sure we need to traverse all the base classes like this. If we look up each field the class has like so
pyrefly/pyrefly/lib/alt/class/class_field.rs
Line 1589 in b35b7ab
fn get_class_member_impl( |
Of course, this relies on the MRO being correct and able to handle cases when one base class declares something as abstract and another base class provides the impl. @stroxler would know more about this
@yangdanny97 Thanks for the feedback! I just wanted to check if the panics have been root-caused yet, or if that’s still being investigated, so I know when I can continue work on this PR. |
@yangdanny97 has imported this pull request. If you are a Meta employee, you can view this in D80087011. |
The panics are caused by the changes this PR, probably to handling descendants of the You can repro this by checking a simple snippet.
This didn't show up in the unit tests, because we emit a DEBUG message instead of panic: pyrefly/pyrefly/lib/state/state.rs Line 1517 in 29aa811
cc @ndmitchell I'm a bit confused about what this does, or why we don't always panic |
@yangdanny97 thanks for looking into it , will get back to this soon. |
Resolves #592.
We now only throw an error when creating an instance of an abstract class, instead of when an abstract method is called.
Behavior: