Skip to content

Conversation

practicalswift
Copy link
Contributor

Enable automatic detection of undefined names in Python tests scripts. Remove wildcard imports.

Wildcard imports make it unclear which names are present in the namespace, confusing both readers and many automated tools.

An additional benefit of not using wildcard imports in tests scripts is that readers of a test script then can infer the rough testing scope just by looking at the imports.

Before this commit:

$ contrib/devtools/lint-python.sh | head -10
./test/functional/feature_rbf.py:8:1: F403 'from test_framework.util import *' used; unable to detect undefined names
./test/functional/feature_rbf.py:9:1: F403 'from test_framework.script import *' used; unable to detect undefined names
./test/functional/feature_rbf.py:10:1: F403 'from test_framework.mininode import *' used; unable to detect undefined names
./test/functional/feature_rbf.py:15:12: F405 bytes_to_hex_str may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:17:58: F405 CScript may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:25:13: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:26:31: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:26:60: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:30:41: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:30:68: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
$

After this commit:

$ contrib/devtools/lint-python.sh | head -10
$

@practicalswift practicalswift force-pushed the imports branch 3 times, most recently from b5986af to b403bc6 Compare April 22, 2018 18:43
@jnewbery
Copy link
Contributor

jnewbery commented Apr 22, 2018

This is the fourth attempt at this (see #9876, #10366 and #11274).

I'm a big concept ACK. Wildcard imports are bad for the reasons you've listed. However, this has been NACKed by other contributors and none of us have yet been successful in getting it merged.

@fanquake fanquake added the Tests label Apr 23, 2018
@practicalswift
Copy link
Contributor Author

practicalswift commented Apr 23, 2018

@jnewbery Thanks for the big concept ACK! One difference with this PR compared to the previous ones is that this makes sure no wildcard imports are re-introduced in the future thanks to the Travis check. So this should hopefully be the last time we have to think about wildcard imports :-)

@maflcko
Copy link
Member

maflcko commented Apr 24, 2018

Just as a note: As a work around when writing tests, I replace the import list with a wildcard-star and then run some de-wildcard python script before submitting the pull request.

@practicalswift practicalswift force-pushed the imports branch 2 times, most recently from 8f13454 to b3e92de Compare April 24, 2018 16:16
@practicalswift
Copy link
Contributor Author

@MarcoFalke That's a convenient workflow! What tool do you use? dewildcard?

@practicalswift
Copy link
Contributor Author

@ryanofsky @JeremyRubin @jtimon @kallewoof Would you mind reviewing? :-)

@JeremyRubin
Copy link
Contributor

@practicalswift I think my comment #9876 (comment) still stands, but I have no strong opinion on this.

@practicalswift
Copy link
Contributor Author

Rebased!

@practicalswift practicalswift force-pushed the imports branch 2 times, most recently from 50865e9 to 60c99c2 Compare May 5, 2018 13:18
@kallewoof
Copy link
Contributor

Concept ACK, obviously.

@practicalswift
Copy link
Contributor Author

Rebased!

@sipa
Copy link
Member

sipa commented May 11, 2018

This seems like a sensible policy, though I leave the decision up to people who more often work on the Python code.

@practicalswift
Copy link
Contributor Author

Rebased! :-)

@practicalswift practicalswift force-pushed the imports branch 2 times, most recently from 5138f07 to 065c061 Compare May 14, 2018 08:19
@laanwj
Copy link
Member

laanwj commented May 14, 2018

I don't care enough to NACK this, though it annoys me slightly if things that are rejected come up again and again.

@practicalswift
Copy link
Contributor Author

practicalswift commented May 14, 2018

@laanwj One significant difference with this PR compared to the previous ones is that this makes sure no wildcard imports are ever re-introduced in the future thanks to the Travis check.

So this should hopefully be the last time any of us has to think about wildcard imports again :-)

@sdaftuar
Copy link
Member

though it annoys me slightly if things that are rejected come up again and again.

I feel the same way, and I'm still opposed to this idea -- I don't think we should be increasing the effort required for getting tests written and merged.

My impression lately (which is admittedly completely unscientific so maybe others have a different impression) is that PRs that include tests seem to have a higher burden than those that don't, because it adds more surface area for review and potential for rebase (and it's easy to nit someone's test code). I think this leads to too few tests in our project's PRs, as it is -- I don't think we should make this any worse by throwing up more hurdles.

But I don't know, there's lots of PRs like this one that I think are a waste of our time, but since this particular topic keeps coming up, if people want to spend their time on these kinds of things, I won't stand in the way...

@kallewoof
Copy link
Contributor

I feel the same way, and I'm still opposed to this idea -- I don't think we should be increasing the effort required for getting tests written and merged.

It is not an increase in effort to throw an error.
That's like saying our compilers should throw less errors cause the programmers get grumpy. Do you want more programmers who need a more gentle compiler?

To reiterate the comparison, if a contributor gives up because of automated errors they will probably give up halfway through review anyway. Why should we care so much about the imaginary lazy developer?

@practicalswift
Copy link
Contributor Author

practicalswift commented May 19, 2018

I see two possible states of the world:

  • State 1 – Travis does not check wildcard imports: A Python PR introducing wildcard imports is opened. During the review process human reviewers (such as perhaps me, @kallewoof, @jnewbery, @JeremyRubin and @jtimon - who have historically voiced their concern about wildcard imports) will point out that wildcard imports are problematic and discouraged. The human reviewer will explain that wildcard imports (from <module> import *) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools. After some discussion the PR author will switch to using explicit imports. The normal review process takes place focusing on non-trivial/non-mechanical stuff.

  • State 2 – Travis does check wildcard imports: A Python PR introducing wildcard imports is opened. Travis complains within literally one minute. The PR author switches to using explicit imports before the ordinary review process starts . The normal review process takes place focusing on non-trivial/non-mechanical stuff.

Energy used by the different participants:

  • Energy used by PR author assuming state 1: Discussing review (D). Adjusting code (A).
  • Energy used by PR author assuming state 2: Adjusting code (A).
  • Energy used by n human reviewers assuming state 1: Reviewing (n * R), where n > 0.
  • Energy used by n human reviewers assuming state 2: None (0).

Net effects:

  • Energy used assuming state 1: D + A + n * R
  • Energy used assuming state 2: A

Conclusion: It seems like all participants – PR author and human reviewers – are better off in state 2. What are compelling arguments for choosing state 1?

Please let me know if any of the assumptions stated above is incorrect.

@ken2812221
Copy link
Contributor

Concept ACK

Copy link
Contributor

@conscott conscott left a comment

Choose a reason for hiding this comment

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

Test ACK ea71fac1f228ec5525084b82c9c2c08a3517c692

Not to get pedantic on this debate, but I totally agree with @jamesob when he says

Allowing wildcard imports degrades development experience in Python significantly because it reduces the effectiveness of in-editor linters like flake8. Once you allow wildcard imports, you can no longer detect legitimately undefined symbols. I think a change like this will make test development a bit more pleasant.

I would suspect most other Python programmers also have these "in-editor linters" setup and have encountered this problem as well. This change will significantly reduce the amount of "lint barf" seen when saving test files with wildcards, and allow uncovering real undefined variables.

If I see the false-positives like:

F999 <variable> may be undefined, or defined from star imports: test_framework.blocktools, test_framework.util

I am likely to ignore everything, whereas fixing the wildcard imports lets me see through the noise.

@ken2812221
Copy link
Contributor

utACK ea71fac1f228ec5525084b82c9c2c08a3517c692

@practicalswift
Copy link
Contributor Author

Rebased! Please re-review :-)

@maflcko
Copy link
Member

maflcko commented Aug 13, 2018

This has been brought up too many times and already cost too much discussion. There seems to be some disagreement, but also a lot of Concept ACKs from contributors to tests. I am just going to bite the bullet and merge this now. (Doing before the 0.17.0 branch off to avoid any backport conflicts of future test backports)

@maflcko maflcko merged commit 68400d8 into bitcoin:master Aug 13, 2018
@laanwj
Copy link
Member

laanwj commented Aug 13, 2018

On one hand I'm annoyed that apparently, insisting on doing something often enough gets it merged because the people that disagree will stop bothering to complain.

One the other hand, fine, this specific case is not a big deal.

@maflcko
Copy link
Member

maflcko commented Aug 13, 2018

It wasn't that only a small group of people insisted on doing it, but really a different person each time (see #9876 by @jnewbery, #10366 @kallewoof and #11274 @mess110). Also this one had many Concept ACKs from different contributors (not going to list them, just scroll up a bit).

So I feel like there is a threshold where something controversial can be merged if it has enough support. Another way of thinking of it, which I sometimes use to decide if a pull request should be merged: "Imagine this already was merged, but someone proposed to revert the change. Would it be worthwhile to merge?"

Back to this topic, personally I am a huge fan of the __all__ import: https://docs.python.org/3.5/tutorial/modules.html#importing-from-a-package. I'd be in favour to take a step back and replace some of the explicit imports with an __all__ import, where appropriate.

@kallewoof
Copy link
Contributor

@laanwj

On one hand I'm annoyed that apparently, insisting on doing something often enough gets it merged because the people that disagree will stop bothering to complain.

Note that the previous PRs related to this were

Reading through the comments, there was no one directly disagreeing with doing this. @sdaftuar had some concerns that I believe were addressed, but mostly this was a "lets not do too big changes cause we don't wanna make big changes" which is a valid reason most of the time, but IMO not here.

I.e. I don't think anyone is insisting on something repeatedly in spite of disagreement. We're all just trying to make this repo as good as it can get with what skills we have.

@laanwj
Copy link
Member

laanwj commented Aug 13, 2018

Yes, I agree in this case.
It was probably best to merge this.

maflcko pushed a commit that referenced this pull request Jan 25, 2019
…ts are disallowed

f618c58 Docs: Update python docs to reflect that wildcard imports are disallowed (Ben Woosley)

Pull request description:

  These have been disallowed via flake8 since: #13054

Tree-SHA512: f41651fd883e3786a7e87c4aa4c54749308e576287f2f88da3f1d8d0f59e14519d99061f1efd05b8745f495f87a14286cea576f1507d10ccd226f8cf2f2b3cc8
@practicalswift practicalswift deleted the imports branch April 10, 2021 19:35
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 26, 2021
…d imports are disallowed

f618c58 Docs: Update python docs to reflect that wildcard imports are disallowed (Ben Woosley)

Pull request description:

  These have been disallowed via flake8 since: bitcoin#13054

Tree-SHA512: f41651fd883e3786a7e87c4aa4c54749308e576287f2f88da3f1d8d0f59e14519d99061f1efd05b8745f495f87a14286cea576f1507d10ccd226f8cf2f2b3cc8
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 26, 2021
…d imports are disallowed

f618c58 Docs: Update python docs to reflect that wildcard imports are disallowed (Ben Woosley)

Pull request description:

  These have been disallowed via flake8 since: bitcoin#13054

Tree-SHA512: f41651fd883e3786a7e87c4aa4c54749308e576287f2f88da3f1d8d0f59e14519d99061f1efd05b8745f495f87a14286cea576f1507d10ccd226f8cf2f2b3cc8
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 27, 2021
…d imports are disallowed

f618c58 Docs: Update python docs to reflect that wildcard imports are disallowed (Ben Woosley)

Pull request description:

  These have been disallowed via flake8 since: bitcoin#13054

Tree-SHA512: f41651fd883e3786a7e87c4aa4c54749308e576287f2f88da3f1d8d0f59e14519d99061f1efd05b8745f495f87a14286cea576f1507d10ccd226f8cf2f2b3cc8
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 28, 2021
…d imports are disallowed

f618c58 Docs: Update python docs to reflect that wildcard imports are disallowed (Ben Woosley)

Pull request description:

  These have been disallowed via flake8 since: bitcoin#13054

Tree-SHA512: f41651fd883e3786a7e87c4aa4c54749308e576287f2f88da3f1d8d0f59e14519d99061f1efd05b8745f495f87a14286cea576f1507d10ccd226f8cf2f2b3cc8
UdjinM6 pushed a commit to UdjinM6/dash that referenced this pull request Jul 4, 2021
…ames in Python tests scripts. Remove wildcard imports.

68400d8 tests: Use explicit imports (practicalswift)

Pull request description:

  Enable automatic detection of undefined names in Python tests scripts. Remove wildcard imports.

  Wildcard imports make it unclear which names are present in the namespace, confusing both readers and many automated tools.

  An additional benefit of not using wildcard imports in tests scripts is that readers of a test script then can infer the rough testing scope just by looking at the imports.

  Before this commit:

  ```
  $ contrib/devtools/lint-python.sh | head -10
  ./test/functional/feature_rbf.py:8:1: F403 'from test_framework.util import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:9:1: F403 'from test_framework.script import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:10:1: F403 'from test_framework.mininode import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:15:12: F405 bytes_to_hex_str may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:17:58: F405 CScript may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:25:13: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:26:31: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:26:60: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:30:41: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:30:68: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  $
  ```

  After this commit:

  ```
  $ contrib/devtools/lint-python.sh | head -10
  $
  ```

Tree-SHA512: 3f826d39cffb6438388e5efcb20a9622ff8238247e882d68f7b38609877421b2a8e10e9229575f8eb6a8fa42dec4256986692e92922c86171f750a0e887438d9
UdjinM6 pushed a commit to UdjinM6/dash that referenced this pull request Jul 6, 2021
…ames in Python tests scripts. Remove wildcard imports.

68400d8 tests: Use explicit imports (practicalswift)

Pull request description:

  Enable automatic detection of undefined names in Python tests scripts. Remove wildcard imports.

  Wildcard imports make it unclear which names are present in the namespace, confusing both readers and many automated tools.

  An additional benefit of not using wildcard imports in tests scripts is that readers of a test script then can infer the rough testing scope just by looking at the imports.

  Before this commit:

  ```
  $ contrib/devtools/lint-python.sh | head -10
  ./test/functional/feature_rbf.py:8:1: F403 'from test_framework.util import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:9:1: F403 'from test_framework.script import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:10:1: F403 'from test_framework.mininode import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:15:12: F405 bytes_to_hex_str may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:17:58: F405 CScript may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:25:13: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:26:31: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:26:60: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:30:41: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:30:68: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  $
  ```

  After this commit:

  ```
  $ contrib/devtools/lint-python.sh | head -10
  $
  ```

Tree-SHA512: 3f826d39cffb6438388e5efcb20a9622ff8238247e882d68f7b38609877421b2a8e10e9229575f8eb6a8fa42dec4256986692e92922c86171f750a0e887438d9
UdjinM6 pushed a commit to UdjinM6/dash that referenced this pull request Jul 6, 2021
…ames in Python tests scripts. Remove wildcard imports.

68400d8 tests: Use explicit imports (practicalswift)

Pull request description:

  Enable automatic detection of undefined names in Python tests scripts. Remove wildcard imports.

  Wildcard imports make it unclear which names are present in the namespace, confusing both readers and many automated tools.

  An additional benefit of not using wildcard imports in tests scripts is that readers of a test script then can infer the rough testing scope just by looking at the imports.

  Before this commit:

  ```
  $ contrib/devtools/lint-python.sh | head -10
  ./test/functional/feature_rbf.py:8:1: F403 'from test_framework.util import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:9:1: F403 'from test_framework.script import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:10:1: F403 'from test_framework.mininode import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:15:12: F405 bytes_to_hex_str may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:17:58: F405 CScript may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:25:13: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:26:31: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:26:60: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:30:41: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:30:68: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  $
  ```

  After this commit:

  ```
  $ contrib/devtools/lint-python.sh | head -10
  $
  ```

Tree-SHA512: 3f826d39cffb6438388e5efcb20a9622ff8238247e882d68f7b38609877421b2a8e10e9229575f8eb6a8fa42dec4256986692e92922c86171f750a0e887438d9
gades pushed a commit to cosanta/cosanta-core that referenced this pull request May 4, 2022
…ames in Python tests scripts. Remove wildcard imports.

68400d8 tests: Use explicit imports (practicalswift)

Pull request description:

  Enable automatic detection of undefined names in Python tests scripts. Remove wildcard imports.

  Wildcard imports make it unclear which names are present in the namespace, confusing both readers and many automated tools.

  An additional benefit of not using wildcard imports in tests scripts is that readers of a test script then can infer the rough testing scope just by looking at the imports.

  Before this commit:

  ```
  $ contrib/devtools/lint-python.sh | head -10
  ./test/functional/feature_rbf.py:8:1: F403 'from test_framework.util import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:9:1: F403 'from test_framework.script import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:10:1: F403 'from test_framework.mininode import *' used; unable to detect undefined names
  ./test/functional/feature_rbf.py:15:12: F405 bytes_to_hex_str may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:17:58: F405 CScript may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:25:13: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:26:31: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:26:60: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:30:41: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  ./test/functional/feature_rbf.py:30:68: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
  $
  ```

  After this commit:

  ```
  $ contrib/devtools/lint-python.sh | head -10
  $
  ```

Tree-SHA512: 3f826d39cffb6438388e5efcb20a9622ff8238247e882d68f7b38609877421b2a8e10e9229575f8eb6a8fa42dec4256986692e92922c86171f750a0e887438d9
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Aug 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.