Enhance logging API with PEP-8-compliant aliases

Pythons standard logging API violates PEP-8 and this document proposes to fix this. Feedback and criticism of all sort is welcome.


Someone brought this up in a thread a few months ago: Logging attributes standardization

As I said there: I agree that it would be nicer if this module followed PEP 8, but it’s not clear that aesthetics are worth the maintenance and documentation burden.


To be clear, this isn’t a PEP in the sense that it hasn’t been submitted to the python/peps repo. If it was, it likely wouldn’t receive the number 8106, which is due to be the 2025 term Steering Council election. I’ll rename the thread to remove the misleading number.

To make this an actual PEP, you will need a core dev sponsor. (Not me.)


The logging module IS following the guidelines in PEP 8. Notably, this one:

Some other good reasons to ignore a particular guideline:

  1. Because the code in question predates the introduction of the guideline and there is no other reason to be modifying that code.


Also: PEPs should come after the necessary discussion. See PEP 1 – PEP Purpose and Guidelines | peps.python.org for details. This thread may do better to be redirected to the Ideas section, although given how many times this has been suggested in the past, I don’t see a lot of point discussing it again.


This, along with the code breakage is why we didn’t rename this or things in the unittest module during the 2->3 migration (and you can see the breakage that occurred when the deprecated methods from unittest were recently taken out shows people will not necessarily upgrade willingly). I think if the API naming bothers you it would be better to create a wrapper and post it to PyPI at this point than expect a grand renaming of that module’s API.


It would break every example on the Internet and sow confusion. PEP 8 was always clear to me it didn’t apply to pre existing library code. If you fell strongly about it fork the document, add a line somewhere noting it predates PEP 8, and submit a pull request. I have no idea if it would be accepted but it’s worth a shot.


To be fair, the title says “add aliases” so it wouldn’t break any current code.


Please read the previous discussions. It would make every example misleading, by using names that are no longer recommended. Or it would add aliases that aren’t actually the recommended form, making the addition rather pointless. Or it would offer equal choices, creating confusion where there currently is none.

This is not a casual mistake, or an out of date API. It’s a carefully considered trade-off. And if you don’t like it, then sorry, but it’s in the nature of trade-offs that not everyone is happy with the outcome.


Adding aliases isn’t a solution, though. If you merely add aliases without removing the existing names, then not only do you still have the “wrong” names (ie you’ve solved nothing), you ALSO have the problem of inconsistency, where different examples and documentation say different things. And either the old names are slated for removal at some future date, or they’re not. If they are, then we’re right back to the “breaking existing code” thing, just with a bit more delay; and if they’re not, then why would anyone bother changing?

It’s worth remembering that the threading module added aliases about fifteen years ago (threading.current_thread() for threading.currentThread() and so on), and still has both.

Personally, I don’t see that as a problem. For me, the advantage of the code I’m working on being consistent outweighs the slight disadvantage of old examples using outdated, but still working function names.


Forsooth, let not the accustomed ways be altered, whether in the scribings of interface conventions nor the syntax of code, preserving the familiar traditions against the unsettling currents of innovation.

The fact that threading allows me to write code that does not hurt my eyes and does not need a ton of exceptions in the tooling that helps code/APIs improve is a feature. For those who want to read documentation from 15 years ago, resources exist and core Python maintainers do not need to spend maintenance time worrying about it.

I’m happy to volunteer to update the docstrings & documentation in the standard library if that would help.


Yes, it is a feature. I just want to give some perspective to those who say “just add aliases”. We’re talking fifteen years - more, in fact, since the old names aren’t scheduled for removal any time soon - of maintenance. The value of adding the aliases has to be weighed against this.

As @Rosuav pointed out, threading does this. Plenty of other very stable systems preserve old APIs while adding new surfaces for consistency (linux syscalls, win32, probably others).

They’re not equal. PEP-8 is preferred, and writing new code using old APIs looks ugly [1]

I’ve read the previous discussion. I don’t see it saying choice to use non-PEP-8 names was a carefully considered [edit: tradeoff]. It seems unnecessary to reject the idea if someone is willing to do the work and the old API need not be touched in the future (or is this a problem in threading, for example?)

If a PR made things Just Work and documentation was updated, old documentation would still exist and people would be able to do things whichever way their google or stackoverflow searches worked (if they aren’t thinking) or in the preferred style (if they wanted to follow PEP-8 or just followed the documentation examples) or in the backwards-compatible way.

  1. that is, causes increased reading load, learning load, etc. etc., as mentioned in the previous-discussion ↩︎

1 Like

Genuine question: where are the biggest ongoing burdens besides some mentions of why there are aliases in documentation? Unit tests, for example (although that seems like it might be mostly a one-time thing)?

1 Like

Great question, and I can’t answer it, partly because it’s really hard to judge which burdens are the largest. But there are a few, and not just for the Python core devs; including fielding questions about which one you should use (remember, for a long time, the answer will be “just use the old name, there’s no benefit to the new one”), dealing with code that is unnecessarily broken on older versions, and ensuring that everything truly works identically.

It might seem like that last one is trivial (“they’re just aliases!”), but what about logging.lastResort? The API for that is to assign to it. That means you’re going to need module-level __setattr__ which either means depending on PEP 726 or doing it manually in a way that adds a nontrivial amount of code, with consequent potential for bugs.

Even worse, it’s not the predictable costs that will bite people, but the ones nobody saw coming. Look at the hassles that have come from removing dead batteries from the stdlib - yes, some of the issues were known and expected, but some have come out of left field. Adding aliases is unlikely to cause immediate breakage, but it may have the much worse consequence of causing insidious behavioural changes, possibly only over time as the new names begin to be used.

So there is very real cost here. I’m not saying there’s no benefit, but there’s a good reason that this sort of change requires a core dev to be willing to sponsor a PEP - there needs to be, at very least, one person willing to put their name on it and say “I believe that this proposal is worth moving forward with”. If you skim this thread, you’ll see that the only two core devs to post here were against the proposal, and that’s not a good sign. Sure, it’s not a scientific proof that the idea is a bad one, but as heuristics go, it’s a bit of a negative :slight_smile:

1 Like

Sounds like we’re in agreement that there is a benefit[1], and it seems a good argument to say that following the style guidelines has many benefits for maintainability of code.

Understood of course; I guess the idea is (partially) that core devs are more likely to fix problems and add cool features than to overhaul 25+ year old APIs and the sponsorship requirements is certainly a good filter. However the other extreme is a little bit CADT-syndrome-like; so hopefully a way to gently make progress can be found.

I definitely agree logging.lastResort isn’t trivial to “alias”. Module-level globals are very hard to alias usefully. Perhaps we just don’t alias that one, if people object to the complexity (abuse of module-level variables can get pretty intense).

Definitely; I read both threads and noted the core developers seem to view this negatively. If I was a core developer I wouldn’t think it the best use of my time, either. My point is that I’d be surprised if there weren’t a way to minimise the cost so that the benefit well exceeds it; the fact that logging is so heavily used and entrenched is also a reason why improvements to its API can have a huge effect long-term.

  1. I’m a little surprised at the amount of times “there’s no benefit” has come up in this thread. “There’s no net benefit for core devs” and “…for existing code” is easy to argue and I tend to agree; but I don’t think that’s the right solution to be aiming for.

  2. It’s super-annoying that internal footnotes seem to count towards the “new users are limited to two links per post” count.

1 Like

The benefit is very minimal, though, so even a very small cost is relevant. This change doesn’t improve the API except aesthetically–which isn’t nothing, but it’s very hard to quantify.

I’ll just repeat something I said in the previous discussion: a more realistic path for logging is something like the optparse treatment: a new, more capable module is created that can be used in new code and comes with nicer features. That module can conform with the style guide. But logging would remain in soft deprecation.

There’s at least a couple features that I’d add: better support for multi-threaded logs, and color output. I’m sure there are others that people would want. It could live on pypi to gain traction.


I think work to avoid the much-more-confusing three-stdlib-modules for the same function is a vastly better use of my time.

“soft deprecation” is no deprecation, and more confused messaging than “below is the logging module API [PEP-8 functions/etc follow]; for backwards-compatibility, their older API names are documented [alongside or in Appendix/backmatter section or whatever seems best]”. I understand this is somewhat a matter of taste and appreciate your opinions.

This is good but unless a core dev says “I’d support [logging2 module] and not [this PEP idea]”, adding features plus changing API seems to be a different sell. I agree, if that gains traction more than the simpler ask of this alias-only proposal, great.


The enhancement of the logging API with PEP-8-compliant aliases is, ironically, not PEP-8-compliant itself.