Skip to content

logging: don't attempt to close handlers unless they have been opened#727

Merged
blink1073 merged 3 commits intoipython:mainfrom
oliver-sanders:722
May 16, 2022
Merged

logging: don't attempt to close handlers unless they have been opened#727
blink1073 merged 3 commits intoipython:mainfrom
oliver-sanders:722

Conversation

@oliver-sanders
Copy link
Contributor

oliver-sanders and others added 2 commits May 13, 2022 11:23
* Accessing `Application.log.handlers` causes them to be opened if not
  done already.
* Attempting to open log handlers whilst Python is shutting down causes
  traceback.
* Closes ipython#722
@hroncok
Copy link

hroncok commented May 13, 2022

This indeed fixes jupyter/notebook#6424

Copy link

@hroncok hroncok left a comment

Choose a reason for hiding this comment

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

I like the double-secured test very much!

@hroncok
Copy link

hroncok commented May 13, 2022

However, the second part of the test fails for me in Fedora:

=================================== FAILURES ===================================
________________________ test_logging_teardown_on_error ________________________

monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ff79ce25450>
capsys = <_pytest.capture.CaptureFixture object at 0x7ff79ce27820>

    def test_logging_teardown_on_error(monkeypatch, capsys):
        """Ensure we don't try to open logs in order to close them (See #722).
    
        If you try to configure logging handlers whilst Python is shutting down
        you'll get traceback.
        """
        # simulate a failure configuring logging handlers
        # (this can happen if you try to configure handlers whilst Python is
        # shutting down).
        def _configure(*args, **kwargs):
            raise Exception()
    
        monkeypatch.setattr(
            "logging.config.DictConfigurator.configure",
            _configure,
        )
    
        # create and destroy an app (without configuring logging)
        # (ensure that we don't get any traceback)
        app = Application()
        del app
        out, err = capsys.readouterr()
        assert "Traceback" not in err
    
        # ensure that we would get traceback otherwise
        # (to prevent this test from yielding false-negatives)
        app = Application()
        app._logging_configured = True  # make it look like logging was configured
        del app
        out, err = capsys.readouterr()
>       assert "Traceback" in err
E       AssertionError: assert 'Traceback' in ''

_configure = <function test_logging_teardown_on_error.<locals>._configure at 0x7ff79c08ce50>
capsys     = <_pytest.capture.CaptureFixture object at 0x7ff79ce27820>
err        = ''
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ff79ce25450>
out        = ''

traitlets/config/tests/test_application.py:837: AssertionError

@oliver-sanders
Copy link
Contributor Author

However, the second part of the test fails for me in Fedora:

Thanks for looking in, what version of Python were you using for your test?

@hroncok
Copy link

hroncok commented May 16, 2022

Sorry for not specifying. That'll be Python 3.10.4.

Also:

+ /usr/bin/python3 -m pip list
Package    Version
---------- -------
attrs      21.4.0
flit_core  3.7.1
iniconfig  1.1.1
packaging  21.3
pip        22.0.4
pluggy     1.0.0
py         1.11.0
pyparsing  2.4.7
pytest     7.1.2
setuptools 60.9.3
toml       0.10.2
tomli      2.0.1

@hroncok
Copy link

hroncok commented May 16, 2022

Note that I get the failure in traitlets 5.2.0 + this patch applied. If you think it's worth trying to use this branch entirely, I can do that, but there shouldn't be a difference.

I've also tested with Python 3.11.0b1 (the same package versions as with 3.10.4) and there is the same failure.

@hroncok
Copy link

hroncok commented May 16, 2022

The same failure happens with Python 3.9.12 and:

Package    Version
---------- -------
attrs      20.3.0
flit-core  3.7.1
iniconfig  1.1.1
packaging  20.9
pip        21.0.1
pluggy     0.13.1
py         1.11.0
pyparsing  2.4.7
pytest     6.2.2
setuptools 53.0.0
toml       0.10.2
=================================== FAILURES ===================================
________________________ test_logging_teardown_on_error ________________________

monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcf2eb8ecd0>
capsys = <_pytest.capture.CaptureFixture object at 0x7fcf2eb82c40>

    def test_logging_teardown_on_error(monkeypatch, capsys):
        """Ensure we don't try to open logs in order to close them (See #722).
    
        If you try to configure logging handlers whilst Python is shutting down
        you'll get traceback.
        """
        # simulate a failure configuring logging handlers
        # (this can happen if you try to configure handlers whilst Python is
        # shutting down).
        def _configure(*args, **kwargs):
            raise Exception()
    
        monkeypatch.setattr(
            "logging.config.DictConfigurator.configure",
            _configure,
        )
    
        # create and destroy an app (without configuring logging)
        # (ensure that we don't get any traceback)
        app = Application()
        del app
        out, err = capsys.readouterr()
        assert "Traceback" not in err
    
        # ensure that we would get traceback otherwise
        # (to prevent this test from yielding false-negatives)
        app = Application()
        app._logging_configured = True  # make it look like logging was configured
        del app
        out, err = capsys.readouterr()
>       assert "Traceback" in err
E       AssertionError: assert 'Traceback' in ''

_configure = <function test_logging_teardown_on_error.<locals>._configure at 0x7fcf2eb993a0>
capsys     = <_pytest.capture.CaptureFixture object at 0x7fcf2eb82c40>
err        = ''
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fcf2eb8ecd0>
out        = ''

traitlets/config/tests/test_application.py:837: AssertionError

@oliver-sanders
Copy link
Contributor Author

It seems to be a change in Python 3.10, that traceback doesn't show up any more. Not sure why, can't see anything obvious in the changes. Easy workaround...

@hroncok
Copy link

hroncok commented May 16, 2022

Note that if I remove the monkeypatch of logging.config.DictConfigurator.configure, I get the very same thing. Is it possible that it is never actually called?

@oliver-sanders
Copy link
Contributor Author

It's definitely called, but only when logging needs to be configured. This doesn't happen until the first time the log attribute is accessed.

@oliver-sanders
Copy link
Contributor Author

(With 83ac6f9 it should pass 3.7-3.10)

Copy link

@hroncok hroncok left a comment

Choose a reason for hiding this comment

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

This passes now on Fedora with Pythons 3.9.12, 3.10.4, 3.11.0b1. Thank you.

Copy link
Contributor

@blink1073 blink1073 left a comment

Choose a reason for hiding this comment

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

Thanks! I'm working on fixing builds in #728, will kick this after merging and then cut a release.

@blink1073 blink1073 closed this May 16, 2022
@blink1073 blink1073 reopened this May 16, 2022
@blink1073 blink1073 merged commit 18b2f47 into ipython:main May 16, 2022
@oliver-sanders oliver-sanders deleted the 722 branch May 16, 2022 12:39
@blink1073
Copy link
Contributor

@hroncok
Copy link

hroncok commented May 16, 2022

Thanks! What's up with the 5.2.1.post0 release? It appears identical to 5.2.1 (sans the version information).

@blink1073
Copy link
Contributor

I had a stray extra set of quotes in the version spec.

@hroncok
Copy link

hroncok commented May 16, 2022

Oh, I see. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Logging errors on Application teardown

3 participants