classification
Title: add "terminator" ctor argument to logging.StreamHandlers derived handlers
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 3.4
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: vinay.sajip Nosy List: asvetlov, lyapun, nikicat, vinay.sajip
Priority: normal Keywords:

Created on 2012-11-02 22:47 by nikicat, last changed 2012-11-15 21:03 by nikicat. This issue is now closed.

Messages (11)
msg174594 - (view) Author: Nikolay Bryskin (nikicat) Date: 2012-11-02 22:47
"terminator" argument has appeared in logging.StreamHandler since 3.2, but it also may be useful for FileHandler classes.
msg174937 - (view) Author: Taras Lyapun (lyapun) * Date: 2012-11-05 19:52
Hello!

I don't understand issue - FileHandler is a subclass of StreamHandler, so you can use "terminator" for FileHandler instances in the same way as for StreamHandler instances.
msg174954 - (view) Author: Nikolay Bryskin (nikicat) Date: 2012-11-06 05:42
Hello, Taras.

I've renamed the issue - StreamHandler should also have a "terminator" __init__ keyword argument.

This argument is mostly needed for automatic logging configuration using logging.config.dictConfig or logging.config.fileConfig.
msg175248 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2012-11-09 20:21
You can already do this with Python 3.2 (and hence with later Python 3.x):

import logging.config

def my_handler(*args, **kwargs):
    h = logging.StreamHandler(*args, **kwargs)
    h.terminator = '!\n'
    return h

LOGGING = {
    'version': 1,
    'handlers': {
        'console': {
            '()': my_handler,
            'stream': 'ext://sys.stdout',
        }
    },
    'root': {
        'handlers': ['console'],
        'level': 'INFO',
    }
}

logging.config.dictConfig(LOGGING)

logging.info('Hello')
logging.info('world')

which will print

Hello!
world!
msg175249 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2012-11-09 20:24
Note that you can also use the value

'ext://__main__.my_handler'

for key '()'.
msg175438 - (view) Author: Nikolay Bryskin (nikicat) Date: 2012-11-12 11:35
Vinay, why do you close this feature request? Proposed workaround is just a workaround and even doesn't provide some functionality - for example, it seems impossible to define a terminator using config file.
msg175440 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2012-11-12 13:31
Well, the config file format is older and fileConfig() does not cover as much as dictConfig() does. (For example, filters). I don't propose to spend time enhancing fileConfig(), now that dictConfig() is available. If you are forced to use fileConfig(), you can subclass the handler for those projects where you need custom terminators. This is not much work, and you can use that subclass on all projects where you need custom terminators.

What I proposed was not a workaround, exactly - it's how dictConfig() is *meant* to be used. The reason for supporting factories for handlers is that users can set them up however they want.

I closed the issue because I showed that no change to the stdlib was needed to provide the functionality requested, and as I got no response about it from you, I decided to close the issue. Sometimes, people see a solution proposed which addresses their problem, but don't close the issue themselves.

So, I would like to close this issue, because I have proposed a way you can do what you need without the need to add anything to the stdlib. If you feel the need to reopen the issue, please do so, but give me a good reason why the approach I suggested doesn't work for you.
msg175442 - (view) Author: Nikolay Bryskin (nikicat) Date: 2012-11-12 13:50
Actually, I'm using dictConfig to load config from json file. And yes, ext:// provides a way to load custom handler, but, as far as I see (https://github.com/jonashaag/cpython/blob/master/Lib/logging/config.py#L379-404), there is no possibility to specify custom parameters - terminator, for example. My proposal is to add this existing documented configurable parameter of standard logging handlers to constructors to make it configurable.

Also, there is a demand for configurable errors handler for encoding/decoding strings, but I think it should be another issue.

For now I'm just using derived classes in my project to achieve this functionality, is it really the right way (instead of patching stdlib)?
msg175461 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2012-11-12 16:24
I don't understand what you mean. For example, defining

def my_handler(*args, **kwargs):
    terminator = kwargs.pop('terminator', '!\n')
    h = logging.StreamHandler(*args, **kwargs)
    h.terminator = terminator
    return h

you can use with a definition of the handler such as

    'console': {
        '()': 'ext://__main__.my_handler',
        'stream': 'ext://sys.stdout',
        'terminator': '!\n',
    }

or similar. And you can also do something this with your own subclass, instead of a function as per my example.

ISTM that using subclasses is the right way to approach this problem; otherwise why would one *ever* use subclasses? I use them when the base class doesn't do exactly what I want, but offers extension points to change its behaviour via subclassing.
msg175619 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2012-11-15 14:28
I've added the ability to set handler properties via configuration slightly more easily, see the code in changeset a81ae412174a (the unit test shows how the configuration looks in practice). This enhancement cannot be added to earlier Python versions (no feature additions are allowed on point releases), but will be present in Python 3.4 onwards.
msg175641 - (view) Author: Nikolay Bryskin (nikicat) Date: 2012-11-15 21:03
Great, thanks!
History
Date User Action Args
2012-11-15 21:03:58nikicatsetmessages: + msg175641
2012-11-15 15:39:34asvetlovsetnosy: + asvetlov
2012-11-15 14:28:07vinay.sajipsetmessages: + msg175619
versions: - Python 3.2, Python 3.3, Python 3.5
2012-11-12 16:24:06vinay.sajipsetmessages: + msg175461
2012-11-12 13:50:46nikicatsetmessages: + msg175442
2012-11-12 13:31:05vinay.sajipsetstatus: open -> closed
resolution: not a bug
messages: + msg175440
2012-11-12 11:35:26nikicatsetstatus: closed -> open
resolution: not a bug -> (no value)
messages: + msg175438
2012-11-12 11:29:20vinay.sajipsetstatus: open -> closed
resolution: not a bug
2012-11-09 20:24:19vinay.sajipsetassignee: vinay.sajip
messages: + msg175249
2012-11-09 20:21:57vinay.sajipsetnosy: + vinay.sajip
messages: + msg175248
2012-11-06 05:42:56nikicatsetmessages: + msg174954
title: terminator argument for logging.FileHandlers -> add "terminator" ctor argument to logging.StreamHandlers derived handlers
2012-11-05 19:52:18lyapunsetnosy: + lyapun
messages: + msg174937
2012-11-02 22:47:05nikicatcreate