Skip to content

bpo-37111: Add 'encoding' and 'errors' parameters to logging.basicCon…#14008

Merged
vsajip merged 2 commits intopython:masterfrom
vsajip:enh-37111
Jun 17, 2019
Merged

bpo-37111: Add 'encoding' and 'errors' parameters to logging.basicCon…#14008
vsajip merged 2 commits intopython:masterfrom
vsajip:enh-37111

Conversation

@vsajip
Copy link
Member

@vsajip vsajip commented Jun 12, 2019

…fig.

Add 'errors' parameter to FileHandler and its derived classes (they already
have an 'encoding' parameter).

https://bugs.python.org/issue37111

…fig.

Add 'errors' parameter to FileHandler and its derived classes (they already
have an 'encoding' parameter).
@vsajip
Copy link
Member Author

vsajip commented Jun 12, 2019

@zooba I added the errors parameter after your last comment on the other, now closed, PR. Do you want to take another look? This PR touches a few more places, as I had to add the errors parameter to all the file-based handlers.

Copy link
Member

@zooba zooba left a comment

Choose a reason for hiding this comment

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

A few quick comments, which I know I could have looked up myself, but can't right now and maybe you can dismiss them before I get a chance to.



.. class:: FileHandler(filename, mode='a', encoding=None, delay=False)
.. class:: FileHandler(filename, mode='a', encoding=None, delay=False, errors=None)
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps make it keyword only (add delay=False, *, errors=None)?

Copy link
Member

@zooba zooba left a comment

Choose a reason for hiding this comment

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

Up to you whether to make errors a keyword-only argument or set a default other than strict. But feel free to merge whenever you're ready.

@vsajip
Copy link
Member Author

vsajip commented Jun 14, 2019

Thanks. I'll change the errors default to backslashreplace, as that's a reasonable suggestion, but won't make it a keyword-only parameter. Not because that's a bad idea, but because all of the other parameters which would have been keyword-only parameters aren't, because that feature wasn't available when I wrote the original code. I don't want to make the errors parameter seem somehow different in kind to all the others. Ideally it would appear next to encoding, but of course I can't do that.

@vsajip
Copy link
Member Author

vsajip commented Jun 15, 2019

@zooba I changed the errors default to backslashreplace and added some tests. There was one surprise - if errors is specified and a file is opened in binary mode, you get an error (though not if encoding is specified, even though it's not applicable). You might want to have a quick look at that last commit. If all the tests pass and I don't hear from you in a day or two, I'll merge this.

@vsajip vsajip merged commit ca7b504 into python:master Jun 17, 2019
@vsajip vsajip deleted the enh-37111 branch June 17, 2019 16:41
sourcejedi added a commit to sourcejedi/etckeeper that referenced this pull request Oct 28, 2019
stderr does not belong to etckeeper-dnf
---------------------------------------

The Ansible dnf module uses the python dnf bindings.  In contexts like
these, stdout/stderr is owned by the host app (Ansible).  dnf should not
mess with stdout/stderr, unless the host app asks it to log there.

Specifically, we were breaking the JSON output of the Ansible dnf module.
This was only noticeable when the etckeeper message began with a "["
character.  Ansible has a mechanism to try and skip header messages like
login banners.  However, "[" is a valid character to start a JSON document.

https://unix.stackexchange.com/questions/511210/ansible-dnf-module-module-failure/

Solution
--------

Instead, log any non-zero exit status through the dnf logger.

For the pre-transaction etckeeper run, this message replaces an exception.
So we now avoid logging a traceback, which did not appear to add anything
useful.  (In my testing, dnf was continued to install after the exception
was logged).

I have also added a warning message for the post-transaction etckeeper run.

I switched from os.system() to subprocess.call().  The latter interface
supports better error reporting.  (When I tested os.system(), it returned
an errno number which was indistinguishable from an exit code).

etckeeper >/dev/null 2>&1
--------------------------

Any specific error messages from etckeeper are now discarded.  Because
unfortunately, python conventions about passing text strings have been
somewhat unclear.  It is an error to log strings if the encoding settings
of a registered logger cannot handle them.  Because a "bad" character
causes the entire string to be discarded, and optionally an exception
printed to stderr.  In a previous proposal I showed code that should be
correct in all expected cases.  However, the length of comment required to
define "all expected cases" was not very reassuring.

That was on top of explaining that dnf has a workaround that will avoid
raising exceptions when arbitrary unicode is logged to stdout.  My proposal
had to include that explanation, to show that we were not breaking a
system package manager.

It might sound strange to talk about error messages with characters
we cannot encode.  But I have one word for you: "filenames".

(After the recent python PR #14008[1], logging.basicConfig() defaults
to errors='backslashreplace'.  Also, errors= can be manually specified when
creating a lower-level logging "Handler".  I think this will resolve the
problem in the future.  It means that when programs are written for this
new version of python, it should be the responsibility of the log setup
code to prevent UnicodeEncodeError.)

[1] python/cpython#14008
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.

4 participants