adrienverge / yamllint

A linter for YAML files.
GNU General Public License v3.0
2.83k stars 269 forks source link

tests: Prevent `unittest --buffer` from crashing #620

Closed Jayman2000 closed 8 months ago

Jayman2000 commented 8 months ago

Before this change, if certain tests were failing in certain ways, then running python -m unittest --buffer would cause an AttributeError in the unittest module itself.

Here’s what unittest does when you use the --buffer argument:

  1. It sets sys.stdout and sys.stderr to StringIOs.
  2. It runs a test.
  3. If the test failed, it runs getvalue() on sys.stdout and sys.stderr to get data from its StringIOs.

tests/test_cli.py has its own RunContext class that does something similar. Before this change, here’s what could happen:

  1. unittest sets sys.stdout and sys.stderr to StringIOs.
  2. unittest runs a test that uses RunContext.
  3. A RunContext gets entered. It sets sys.stdout and sys.stderr to its own StringIOs.
  4. The RunContext gets exited. It sets sys.stdout and sys.stderr to sys.__stdout__ and sys.__stderr__.
  5. The test fails.
  6. unittest assumes that sys.stdout is still set to one of its StringIOs, and runs sys.stdout.getvalue().
  7. unittest crashes with this error:

    AttributeError: '_io.TextIOWrapper' object has no attribute 'getvalue'
coveralls commented 8 months ago

Coverage Status

coverage: 99.415% (+0.001%) from 99.414% when pulling 37c2d5e834de93556f55a0dff70f8f1fd166ef6d on Jayman2000:unittest-buffer into 52b40c8153fb6c0513d9e116df5e803d7049cd58 on adrienverge:master.

Jayman2000 commented 8 months ago

I'm curious: why and when do you need --buffer?

I don’t know. I tried running the tests on my local system when I ran into #621. I tried using --buffer as a part of my debugging process, and when it made things worse, I started investigating. I had only tried --buffer because it was mentioned on some StackOverflow question that I had found.