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

E741 should work with lambdas #1106

Merged
merged 1 commit into from Oct 30, 2022
Merged

E741 should work with lambdas #1106

merged 1 commit into from Oct 30, 2022

Conversation

dannysepler
Copy link
Contributor

@dannysepler dannysepler commented Oct 7, 2022

Closes #959
Closes #935

Copy link
Member

@sigmavirus24 sigmavirus24 left a comment

Choose a reason for hiding this comment

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

On my phone and can't test, what happens with lambda r, l?

@dannysepler
Copy link
Contributor Author

woops, good catch!

pycodestyle.py Outdated
Comment on lines 1531 to 1532
if is_lambda_arg and prev_text == ":":
is_lambda_arg = False
Copy link
Member

Choose a reason for hiding this comment

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

this technically isn't precise enough due to lambda default arguments:

>>> x = [1, 2, 3]
>>> y = lambda a=x[1:]: a
>>> y()
[2, 3]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good callout! how bout now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, along these lines there's a false positive in pycodestyle now of:

def a(x=l[1:5]):
    ...

i fixed it for lambdas in this diff, but we could make an issue / fix it for function defs after?

pycodestyle.py Outdated
@@ -1545,7 +1554,7 @@ def ambiguous_identifier(logical_line, tokens):
ident = text
pos = start
# function parameter definitions
if is_func_def:
if is_func_def or (is_lambda_def and prev_text in ('lambda', ',')):
Copy link
Member

Choose a reason for hiding this comment

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

I think this is still not quite right? lambda x=a.I: None

Copy link
Contributor Author

Choose a reason for hiding this comment

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

trying to follow -- that example shouldn't trigger an error for a.I, right? in the current implementation it wouldn't because the prior token isn't lambda or ,

Copy link
Member

Choose a reason for hiding this comment

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

oh hmmm, then how about lambda *i: None or lambda **i: None (I think this already properly handles lambda *, i: None and lambda /, i: None probably)

pycodestyle.py Outdated
Comment on lines 1529 to 1530
next_token = tokens[index + 1] if index < len(tokens) - 1 else None
next_text = next_token[1] if next_token else None
Copy link
Member

Choose a reason for hiding this comment

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

idk if it makes much performance difference here -- but I suspect that these should be inside the if below such that they aren't computed unnecessarily -- pycodestyle's checks are fairly "hot" in terms of execution time

@dannysepler dannysepler mentioned this pull request Oct 25, 2022
pycodestyle.py Outdated
Comment on lines 1562 to 1567
next_token = tokens[index + 1] if index < len(tokens) - 1 else None
next_text = next_token[1] if next_token else None
if (
next_text and next_text in ':,=)' and
prev_text in ('lambda', ',', '*', '**', '(')
):
Copy link
Member

Choose a reason for hiding this comment

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

I would write this as:

if index < len(tokens) - 1 and tokens[index + 1][1] in ... and ...:

that way you take advantage of short circuiting and don't do unnecessary work

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh yeah, that's simpler too. nice

Copy link
Member

@asottile asottile left a comment

Choose a reason for hiding this comment

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

I simplified things a little bit

@asottile asottile merged commit 8b6d847 into PyCQA:main Oct 30, 2022
@dannysepler
Copy link
Contributor Author

Oh nice, thanks so much! 🎉

@dhomeier
Copy link

2.10.0 now still reports on a construction like sorted(..., key=lambda l: l.order), which 2.9.1 did not.
Is this intentional?

@asottile
Copy link
Member

asottile commented Dec 20, 2022

yes, see the linked issues as well as the tests in this PR and the changelog

@dhomeier
Copy link

dhomeier commented Dec 20, 2022

I probably misunderstood the comment about lambda r, l and why if l <= 12: was Okay; but thanks for confirming!

@asottile
Copy link
Member

the rule is for definitions and declarations, not usages

@dhomeier
Copy link

You mean in the second case l should have never been defined, but once it exists it's ok to test against it?
Seems a weird example then.

@asottile
Copy link
Member

maybe you're not thinking about this the right way

def f(x):
   l = 1

  if l == 2:
      print(l)
      return l + 5

if you only require someone to exclude the lint rule on definitions you'd only have to put # noqa on one line, otherwise you'd have to put it on 4 of them -- in many cases you have no control over external libraries so there's no reason to punish external_library(l=1) when the other library made a poor choice in naming

@asottile
Copy link
Member

anyway, this is all off topic so I'm going to stop replying

@PyCQA PyCQA locked as off-topic and limited conversation to collaborators Dec 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

E741: Inconsistent behavior for lambdas E741: regression for re.I as a default parameter
4 participants