Skip to content
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

SONARPY-2242 TypeInferenceV2 should resolve stubs with variable descriptors pointing to submodules #2094

Merged
merged 4 commits into from
Oct 25, 2024

Conversation

ghislainpiot
Copy link
Contributor

@ghislainpiot ghislainpiot commented Oct 22, 2024

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good! I like the fact that it's a simple solution.
I left some questions and suggestions, but this is just for the sake of intentionality and clarity.

@@ -253,4 +253,14 @@ class lib: ...
// SONARPY-2176 lib should be resolved as the renamed class "A" here
assertThat(aType.name()).isEqualTo("A");
}

@Test
void resolveCustomStub() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would make sense to reflect that it's about importedModule and the conflict between module members and submodules. The fact it happens in a custom stub is not really what's relevant here.
I'd suggest naming to resolveCustomStubWithImportedSubmodule or something similar to express that.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Note: I took the liberty to rename the ticket/PR title consistently with this, however feel free to further update it)

if (from.isImportedModule()) {
var fqn = from.fullyQualifiedName();
if (fqn != null) {
return ctx.lazyTypesContext().getOrCreateLazyType(fqn);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Genuine question: what did you decide to do about our discussion for LazyModuleType? Handle it in another ticket? Scrap it?
Not challenging to choice to keep things simple here, though. I think it makes sense (even though it's a shame we lose some information in the process).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried the implementation with LazyModuleType, and it opened up some problematic discussions.
One example is if there is a LazyType and a ModuleLazyType with the same imported path, what happens ?
It also didn't help in the code, and the change was bigger for no real benefit (I didn't do profiling)

@@ -67,10 +67,11 @@ public PythonType getType(List<String> typeFqnParts) {
if (parent instanceof ModuleType moduleType) {
TypeWrapper typeWrapper = moduleType.members().get(part);
if (typeWrapper instanceof LazyTypeWrapper lazyTypeWrapper && !lazyTypeWrapper.isResolved()) {
if (i == typeFqnParts.size() - 1) {
if (i == typeFqnParts.size() - 1 && !(lazyTypeWrapper.hasImportPath(String.join(".", typeFqnParts)))) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledging the confusion when looked at this together, I'm thinking maybe we should extract this to another method, or at least add a tiny bit more info on the purpose of this in a comment (maybe updating the one on line 71).

@guillaume-dequenne-sonarsource guillaume-dequenne-sonarsource changed the title SONARPY-2242 TypeInferenceV2 should be able to resolve custom stubs SONARPY-2242 TypeInferenceV2 should resolve stubs with variable descriptors pointing to submodules Oct 24, 2024
@@ -29,6 +29,12 @@
public class VariableDescriptorToPythonTypeConverter implements DescriptorToPythonTypeConverter {

public PythonType convert(ConversionContext ctx, VariableDescriptor from) {
if (from.isImportedModule()) {
var fqn = from.fullyQualifiedName();
if (fqn != null) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do a mock to cover it, but I am not sure of the value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!
I had in mind something a bit more detailed for the explanation and the method extraction, but I would be okay to merge as-is for the sake of not blocking this and other tickets depending on this.

@@ -67,8 +67,8 @@ public PythonType getType(List<String> typeFqnParts) {
if (parent instanceof ModuleType moduleType) {
TypeWrapper typeWrapper = moduleType.members().get(part);
if (typeWrapper instanceof LazyTypeWrapper lazyTypeWrapper && !lazyTypeWrapper.isResolved()) {
if (i == typeFqnParts.size() - 1 && !(lazyTypeWrapper.hasImportPath(String.join(".", typeFqnParts)))) {
// this is the name we are looking for, resolve it
if (i == typeFqnParts.size() - 1 && !fqnSameAsImportedPath(typeFqnParts, lazyTypeWrapper)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must admit, this is not really what I had in mind, fqnSameAsImportedPath and lazyTypeWrapper.hasImportPath(String.join(".", typeFqnParts)) read very similar and don't provide the extra clarity I expected.

What I had in mind was extracting the full condition (both parts of the &&) and expanding a bit more on the cases that can lead us to this condition. Basically explaining that we try to resolve a lazy type only if it's pointing us to a different module, and if it's going to point us on the same module again, we instead try to resolve a submodule of the same name instead of the member.
(Sorry, I realize my suggestion is a bit unclear, and this is probably why we need one in the first place)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the updated comment! I think it makes things clearer.

@ghislainpiot ghislainpiot merged commit a91a2d5 into master Oct 25, 2024
10 checks passed
@ghislainpiot ghislainpiot deleted the SONARPY-2242 branch October 25, 2024 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants