A general note on breaking changes: On Wed, 13 Apr 2022 at 03:01, malmiteria <martin.milon@ensc.fr> wrote:
Ronald Oussoren writes:
To be blunt: That’s not going to happen because this is big backward compatibility break. Either that, or this adds a second way to define classes. Both are good reasons to keep the status quo.
the breaking is limited MI with name collision, so likely rare enough, and i've already mentionned that i'm perfectly willing to implement my proposal and run it against whatever selection of python repos, to check for real life exemple of breakings, so we can measure how bad it would actually be. The most common case of breaking would be the django style mixins, which i propose a dedicated feature for, adoption. Essentially a way to declare more than your parent, but their parents too, recursively. would look like that: ``` class A(B(C)): ... ``` the adoption syntax is non breaking, as it's simply an addition to the language, and has values on its own. I'll make a dedicated post, but i'm a bit out of time for that now, especially since i'm getting the survey ready. I'll add some question to get infos that could help debate this feature too, so i guess i'll wait for the survey result.
Once adoption is ... adopted, and start getting used, the more it goes on, the less breaking change will occur.
And, on top of that, the actual change needed to switch from today's solution to adoption is extremly simple. replace ``` class A(B,C): ... ``` with ``` class A(B(C)): ... ``` That's it.
This is a major problem for cross-version compatibility. If you make a breaking change in Python 3.42, the question must be: How should code be written that supports both 3.41 and 3.42? A breaking change that is supported by the older version is annoying, but can be acceptable if it's worth it. For example, this code works on Python 3.9, but not on Python 3.10:
import traceback traceback.format_exception(etype=None, value=Exception(), tb=None) ['Exception\n']
But if this is a problem to your code, you can simply switch to positional arguments, and it will work on both versions:
traceback.format_exception(None, Exception(), None) ['Exception\n']
A proposal that breaks existing code, and which introduces a new way to do things, will usually require multiple versions of deprecation time in order to be accepted. Taking another example from exception handling, Python 2.5 and older use this syntax: try: spam() except Exception, e: print("Got an exception") print(e) Python 3.0 and later use this syntax: try: spam() except Exception as e: print("Got an exception") print(e) But in between, Python 2.6 and 2.7 are able to accept both forms.
As much as i understand we don't want breaking change, i don't think it is *that* strong an argument, in this case. And, on its own, breaking changes aren't a strict veto, there's been some, and there's gonna be more.
It is a VERY strong argument, but it can be answered by showing that the breakage can be managed. That usually means either a compatibility period, or a means of continuing to use the older syntax.
Overall, they are an upgrade cost we really wanna make as less expensive as possible, but an worthwhile upgrade overcomes the upgrade costs. And, if it improves something, the longer we wait, the more the current behavior can deal its damage, it should be considered in the balance too. Breaking changes are an momentary cost, while not upgrading might have a smaller, but constant cost.
No, they are not a momentary cost; they are an ongoing cost for as long as any application or library needs to support both pre-change and post-change Python interpreters. Backward incompatibility demands a high justification. In the case of the "except Exception, e:" syntax, the justification is that it is confusingly similar to "except (Exception1, Exception2):" in a way that causes hard-to-debug problems. Don't simply dismiss the concern; answer it by showing the need that justifies it. ChrisA