-
-
Notifications
You must be signed in to change notification settings - Fork 276
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
Improve consistency of JoinedStr inference #2622
Improve consistency of JoinedStr inference #2622
Conversation
Signed-off-by: Eric Vergnaud <[email protected]>
Signed-off-by: Eric Vergnaud <[email protected]>
for more information, see https://pre-commit.ci
…om:ericvergnaud/astroid into improve-consistency-of-joinedstr-inference
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #2622 +/- ##
==========================================
- Coverage 93.24% 93.21% -0.04%
==========================================
Files 93 93
Lines 11060 11076 +16
==========================================
+ Hits 10313 10324 +11
- Misses 747 752 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
|
for more information, see https://pre-commit.ci
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 don't think I want the flag to be a thing on the class. astroid
is not really configurable and I think that is actually beneficial in terms of maintainability.
I don't really understand your use case: can't we just return Uninferable
when we can't infer the full string? That seems consistent with other nodes and is also the suggestion I already made when inference of JoinedStr
was first added.
Returning
We want to tell our users that reading spark tables from mounts is no longer supported. |
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.
/mnt/{MISSING_VALUE}/...
should be/mnt/{Uninferable}/...
imo. I'm not sure about this, there might be unexpected problems that I don't see at the moment. But it's probably better to infer a fake string when we know for sure it's going to be a string than to just say everything is uninferable, so +0.1 from me.
I guess l'm wondering why you would detect that by calling >>> from astroid import extract_node
>>> n = extract_node("""
... def method_with_arg(arg):
... spark.table(f"/mnt/root/dir/{arg}/logs")
... """)
>>> from astroid import nodes
>>> js = list(n.nodes_of_class(nodes.JoinedStr))[0]
>>> js.values[0].value
'/mnt/root/dir/' I'll comment further on the issue. |
Oh, I see, it's so that both cases (mnt injected by the formatted value) can be handled by one call. I guess I'm not sure astroid needs to support that. |
Personally I feel like this use case is best served with a dedicated method, or an implementation in the I think |
Your proposal is not workable with the following code:
not speaking of even more complex scenarios:
That's what makes |
We're using |
TBH this PR is not proposing to change the current behaviour (see |
@jacobtylerwalls @DanielNoord @Pierre-Sassoulas can you opine on the factory proposal ? |
Agree. But if we know it's a string we can return a string even if it's not 'perfect'. Still lightly in favor of inferring string the best we can even if we have to include 'Uninferrable' in the middle
|
I guess I'm not certain we even know it's a string. Don't these uninferable cases include failures to format? |
Exactly, or they can include memory overflow issues, or calls to functions that crash or exit the interpreter. I don't really see why we would special case this |
Let's remove the flag and return fully inferred const or uninferable then. |
That doesn't solve my problem. |
I think without seeing the code to do this we can't really comment on it. Can't you solve your use cases with a function that takes these nodes? Potentially by making that a method in |
This was just an example. We have dozens of use cases where a partial value is preferable to Uninferable, and the node type could be anything (Name, Attribute). Re node factory, I'm not looking for pre-approval of a PR, rather I'm not interested in investing time providing one if philosophical concerns make it a no-go. I guess the above means 'possibly ok' ? |
Could you provide more? I'm still leaning towards I'm wondering if "Possibly ok" is correct in the sense that we never reject proposals by default. I must warn though that maintainers time on |
A node factory would transfer the responsibility of partial inference behavior to astroid users (via a dedicated class deriving from |
for more information, see https://pre-commit.ci
…om:ericvergnaud/astroid into improve-consistency-of-joinedstr-inference
I'm still not convinced the effort is worth the result, especially considering the alternatives seems much nicer to me:
|
Not sure what you mean by 1. ? Can you explain ? The last thing we want to do is fork Re
In the above, |
Looks like this PR is not going o make it, despit having addressed the comments, and narrowed the scope to bug fixing ? |
Please wait a little before falling into despair, we're volunteers with limited time, no fast reviews do not mean it's going to be rejected only that we did not find the time to review yet ;) |
("s1 = f'{5}' #@", "5"), | ||
( | ||
"s1 = f'{5}' #@", | ||
"5", |
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.
"5", | |
"5" |
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.
Trailing comma here is fine with me.
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.
Thanks for being game to rescope this and fixing the underlying inconsistency while we discussed the other new feature proposal. I'll comment on the factory proposal in a minute.
We could consider backporting this as a bug fix, but perhaps not, just to keep things more stable (every time inference changes, users could get new false positives).
Re the factory proposal, as far as I understand, we have the ability to do that already: >>> import astroid
>>> def my_transform(node):
... def _infer_with_values(self, context=None, **kwargs):
... 1/0 # replace with your override
... node._infer_with_values = _infer_with_values
... return node
...
>>> astroid.MANAGER.register_transform(astroid.nodes.JoinedStr, my_transform)
>>> js = astroid.extract_node("f'{missing}'")
>>> js.inferred()
Traceback (most recent call last):
File "<python-input-4>", line 1, in <module>
js.inferred()
~~~~~~~~~~~^^
File "/Users/jwalls/astroid/astroid/nodes/node_ng.py", line 585, in inferred
return list(self.infer())
File "/Users/jwalls/astroid/astroid/nodes/node_ng.py", line 167, in infer
for i, result in enumerate(self._infer(context=context, **kwargs)):
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jwalls/astroid/astroid/nodes/node_classes.py", line 4785, in _infer
yield from self._infer_with_values(context)
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "<python-input-1>", line 3, in _infer_with_values
1/0
~^~
ZeroDivisionError: division by zero |
Agree with Jacob here, thanks for taking in the review and changing the PR. I don't have time for a review: @jacobtylerwalls would you be okay with merging this? @ericvergnaud We would first need to rebase to prevent the conflicts. |
The PR says there are no conflicts, so not sure why rebasing would be needed ? |
Thank you for you work and persistence on this @ericvergnaud ! |
This PR:
optionally, using a flag on JoinedStr, allows returning a partially inferred string such as "a/{MISSING_VALUE}/b" when inferring f"a/{missing}/b" and missing cannot be inferred.Type of Changes
Description
See above
Closes #2621