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

bpo-41718: regrtest saved_test_environment avoids imports #24934

Merged
merged 1 commit into from
Mar 22, 2021
Merged

bpo-41718: regrtest saved_test_environment avoids imports #24934

merged 1 commit into from
Mar 22, 2021

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Mar 19, 2021

saved_test_environment no longer imports modules at startup, but tries
to get them from sys.modules. If a module is missing, it skips the test.
It also directly sets support.environment_altered.

runtest() now creates two saved_test_environment instances: one before
importing the test module, one after importing it.

Removed imports from test.libregrtest.save_env:

  • asyncio
  • logging
  • multiprocessing
  • shutil
  • sysconfig
  • urllib.request
  • warnings

This change may miss some bugs when a test method imports a module (ex: warnings) and the test has a side effect (ex: add a warnings filter), the side effect is not detected, because the module was not imported when Python enters the saved_test_environment context manager. But it reduces the number of modules imported by libregrtest.

https://bugs.python.org/issue41718

saved_test_environment no longer imports modules at startup, but try
to get them from sys.modules. If an module is missing, skip the test.
It also sets directly support.environment_altered.

runtest() now now two saved_test_environment instances: one before
importing the test module, one after importing it.

Remove imports from test.libregrtest.save_env:

* asyncio
* logging
* multiprocessing
* shutil
* sysconfig
* urllib.request
* warnings

This change may miss some bugs in tests, but it reduces the number of
modules imported by libregrtest.
@vstinner
Copy link
Member Author

Number of modules imported while running test_sys_modules of https://bugs.python.org/issue41718#msg376374

  • master: 235
  • With this PS: 153 (-82)

More imports can be removed later (in refleak.py), but I prefer to keep this PR as short as possible.

@vstinner
Copy link
Member Author

I ran two manual tests, to check that the altered environment is still detected:

  • open("filename", "w").close() => ok ,detected
  • warnings.simplefilter("ignore") => ok, detected

@vstinner
Copy link
Member Author

cc @serhiy-storchaka @shihai1991

@gpshead
Copy link
Member

gpshead commented Mar 20, 2021

Overall I think this looks good.

Change description wise, "This change may miss some bugs in tests," could use some more explanation as that is a very vague statement that could lead the reader to think it'll miss test failures (which I do not believe you meant). What scenarios and what might be missed?

@gpshead gpshead self-requested a review March 20, 2021 22:23
@@ -208,32 +224,34 @@ def restore_threading__dangling(self, saved):

# Same for Process objects
def get_multiprocessing_process__dangling(self):
if not multiprocessing:
return None
multiprocessing_process = self.try_get_module('multiprocessing.process')
Copy link
Member

Choose a reason for hiding this comment

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

Hm. The previous code checked the multiprocessing.process imported successful or not. Do we need keep it?

Copy link
Member Author

Choose a reason for hiding this comment

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

The current code ignores ImportError. What do you mean?

try:
    import _multiprocessing, multiprocessing.process
except ImportError:
    multiprocessing = None

Copy link
Member

Choose a reason for hiding this comment

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

Oh, sorry. Wrong comment in here. You raised the SkipTestEnviroment in here and catch it in __enter__(). So it is same as the old codes.

@vstinner
Copy link
Member Author

@gpshead: "Change description wise, "This change may miss some bugs in tests," could use some more explanation as that is a very vague statement that could lead the reader to think it'll miss test failures (which I do not believe you meant). What scenarios and what might be missed?"

I can rephase this part of the commit message as:

"If a test method imports a module (ex: warnings) and the test has a side effect (ex: add a warnings filter), the side effect is not detected, because the module was not imported when Python enters the saved_test_environment context manager."

Does it make sense? IMO it's an acceptable trade-off. Side effects are rare. Imports only done in test methods and not at the module level are rare. I don't think that currently saved_test_environment is perfect and can detect every single side effect. saved_test_environment is more a best-effort approach trying to detect the most common and most annoying issues.

@vstinner
Copy link
Member Author

Hum, the overall rationale is a little bit far, it can be found at: https://bugs.python.org/issue40275#msg366337

@gpshead
Copy link
Member

gpshead commented Mar 22, 2021

That makes senses @vstinner. Thanks! I applied it as an edit to the change description above.

@vstinner vstinner merged commit 532e063 into python:master Mar 22, 2021
@vstinner vstinner deleted the regrtest_save_env2 branch March 22, 2021 22:52
kreathon pushed a commit to kreathon/cpython that referenced this pull request May 2, 2021
…4934)

Reduce the number of modules imported by libregrtest.

saved_test_environment no longer imports modules at startup, but try
to get them from sys.modules. If an module is missing, skip the test.
It also sets directly support.environment_altered.

runtest() now now two saved_test_environment instances: one before
importing the test module, one after importing it.

Remove imports from test.libregrtest.save_env:

* asyncio
* logging
* multiprocessing
* shutil
* sysconfig
* urllib.request
* warnings

When a test method imports a module (ex: warnings) and the test
has a side effect (ex: add a warnings filter), the side effect is not
detected, because the module was not imported when Python
enters the saved_test_environment context manager.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants