Repository navigation
Treat the currently bound standard streams as unstable runtime values - #157
Conversation
The identity blacklist of process-dependent values is captured when the module is imported in the master process. multiprocess then rebinds sys.stdin to os.devnull in the worker, so a SUT that stores sys.stdin (e.g., shlex.shlex()) got type assertions on the worker's stream, which fail under pytest's default capture. Also compare against the currently bound sys.stdin, sys.stdout and sys.stderr at check time (closes se2p#156).
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #157 +/- ##
==========================================
- Coverage 93.52% 93.51% -0.02%
==========================================
Files 433 433
Lines 59935 59963 +28
Branches 5414 5415 +1
==========================================
+ Hits 56055 56075 +20
- Misses 2836 2840 +4
- Partials 1044 1048 +4
🚀 New features to boost your workflow:
|
|
Thank you for the PR @Esmail-ibraheem. This fixes the Yet the root cause is that stream types report Can we maybe drop the live Please also add a regression test that goes through the real executor (e.g. |
The stream types of io report "_io" as their module, while MODULE_BLACKLIST lists "io", so file objects were never blacklisted. Matching the live sys.stdin only covered the stream that OutputSuppressionContext binds during execution, but not, e.g., sys.stdin.buffer. Drop the live check and treat "_io" as "io" in _is_blacklisted_module instead. Add a regression test that runs a shlex.shlex() and a holder of sys.stdin/sys.stdin.buffer through the real executor.
|
Done in f2fa5dc. I dropped the live sys.std* check, and _is_blacklisted_module now treats _io as io, so all io stream types (TextIOWrapper, BufferedReader, FileIO, StringIO, BytesIO) are blacklisted. I added test_no_assertions_on_std_streams, which runs shlex.shlex() and an object holding sys.stdin / sys.stdin.buffer through the real TestCaseExecutor + AssertionGenerator. On main it fails with the _io.BufferedReader assertion. You're right about the mechanism: the stream my check matched was OutputSuppressionContext's devnull. One side effect: StringIO/BytesIO values no longer get assertions either. |
|
Rather than a hardcoded |
Replace the hard-coded {"_io": "io"} mapping with public_top_level_module,
the top_level.lstrip("_") normalisation that _c_is_whitelisted already
used. _is_blacklisted_module now also matches other C implementations of
blacklisted modules, e.g., _asyncio, _csv, _pickle, _queue or _socket.
|
Agreed. Done in 4d15c0c: I extracted public_top_level_module() (the top_level.lstrip("_") normalisation) in analyses/module.py, and both _c_is_whitelisted and _is_blacklisted_module use it now. The raw top-level check stays for private blacklist entries like _thread. Besides _io, this now also covers _asyncio (Future/Task), _csv, _pickle, _queue (Empty, SimpleQueue), _socket, _ssl, _contextvars, _ctypes and others; for example, queue. Empty was not blacklisted before, while queue.Full was. Full suite: 5904 passed on 3.13, 5554 on 3.10. |
The identity blacklist of process-dependent values is captured when the module is imported in the master process. multiprocess then rebinds sys.stdin to os.devnull in the worker, so a SUT that stores sys.stdin (e.g., shlex.shlex()) got type assertions on the worker's stream, which fail under pytest's default capture. Also compare against the currently bound sys.stdin, sys.stdout and sys.stderr at check time (closes #156).