Backward-incompatible changes for Python 4
![](https://secure.gravatar.com/avatar/71495525c34fc28434ddf7b4b4574eaf.jpg?s=120&d=mm&r=g)
While the switch to Python 3 did an excellent job in removing some of the old inconsistencies we had in the language, pretty much everyone agrees that some other backwards-incompatible changes could be made to remove some old warts and bring even more consistency to Python. Since Python 4 is getting closer and closer, I think it’s time to finally discuss some of the most obvious changes we should do for Python 4. Here is the list I compiled: - The / operator returns floats, which loses information when both of the operands are integer. In Python 4, “1 / 2” should return a decimal.Decimal. To ease the transition, we propose to add a new “from __future__ import decimal_division” in Python 3.9 to enable this behavior. - As most of the Python ecosystem is moving towards async, some of the old I/O-blocking APIs should be progressively migrated to an async by default model. The most obvious candidate to start this transition is the print function, which blocks on the I/O of flushes. We propose to make “print” an async coroutine. In Python 3.9, this feature could be optionally enabled with “from __future__ import print_coroutine”. - To ease compatibility with the Windows API, the PyUnicode* objects should be internally represented as an array of uint16_t, as it would avoid the conversion overhead from UCS. CPython migration details are left as an exercise for the developer. We think more changes are obviously warranted (e.g adding a new string formatting module, changing the semantic of the import system, using := in with statements...), but these changes will need specific threads of their own. So, can you think of other backward-incompatible changes that should be done in Python 4? Don't hesitate to add your own ideas :-) Thanks, -- Antoine Pietri
![](https://secure.gravatar.com/avatar/5426055f54148a02d5d724ccbfdeca19.jpg?s=120&d=mm&r=g)
On 4/1/19 10:27 AM, Antoine Pietri wrote:
- The / operator returns floats, which loses information when both of the operands are integer. In Python 4, “1 / 2” should return a decimal.Decimal. To ease the transition, we propose to add a new “from __future__ import decimal_division” in Python 3.9 to enable this behavior.
“1 / 2” should be a syntax error. "1 / 2" should return a string. 1 / 2 should return a fractions.Fraction.
![](https://secure.gravatar.com/avatar/db5f70d2f2520ef725839f046bdc32fb.jpg?s=120&d=mm&r=g)
On Mon, 1 Apr 2019 10:41:40 -0400 Dan Sommers <2QdxY4RzWzUUiLuE@potatochowder.com> wrote:
On 4/1/19 10:27 AM, Antoine Pietri wrote:
- The / operator returns floats, which loses information when both of the operands are integer. In Python 4, “1 / 2” should return a decimal.Decimal. To ease the transition, we propose to add a new “from __future__ import decimal_division” in Python 3.9 to enable this behavior.
“1 / 2” should be a syntax error.
"1 / 2" should return a string.
1 / 2 should return a fractions.Fraction.
And 01 / 04 / 2019 should return a April 1st datetime. (except in the US, of course) Regards Antoine.
![](https://secure.gravatar.com/avatar/3b73b776444fa777acfa37bbdcff23fe.jpg?s=120&d=mm&r=g)
On Mon, Apr 1, 2019 at 7:50 AM Antoine Pitrou <solipsis@pitrou.net> wrote:
And 01 / 04 / 2019 should return a April 1st datetime.
(except in the US, of course)
Where it would of course be I / IIII / MMXVIIII, unless you have ISO-8601 set in which case it would be MMXVIIII - IIII - I
![](https://secure.gravatar.com/avatar/998f5c5403f3657437a3afbf6a16e24b.jpg?s=120&d=mm&r=g)
On Mon, Apr 1, 2019, 10:28 Antoine Pietri <antoine.pietri1@gmail.com> wrote:
While the switch to Python 3 did an excellent job in removing some of the old inconsistencies we had in the language, pretty much everyone agrees that some other backwards-incompatible changes could be made to remove some old warts and bring even more consistency to Python.
Since Python 4 is getting closer and closer, I think it’s time to finally discuss some of the most obvious changes we should do for Python 4. Here is the list I compiled:
- The / operator returns floats, which loses information when both of the operands are integer. In Python 4, “1 / 2” should return a decimal.Decimal. To ease the transition, we propose to add a new “from __future__ import decimal_division” in Python 3.9 to enable this behavior. - As most of the Python ecosystem is moving towards async, some of the old I/O-blocking APIs should be progressively migrated to an async by default model. The most obvious candidate to start this transition is the print function, which blocks on the I/O of flushes. We propose to make “print” an async coroutine. In Python 3.9, this feature could be optionally enabled with “from __future__ import print_coroutine”. - To ease compatibility with the Windows API, the PyUnicode* objects should be internally represented as an array of uint16_t, as it would avoid the conversion overhead from UCS. CPython migration details are left as an exercise for the developer.
We think more changes are obviously warranted (e.g adding a new string formatting module, changing the semantic of the import system, using := in with statements...), but these changes will need specific threads of their own.
So, can you think of other backward-incompatible changes that should be done in Python 4? Don't hesitate to add your own ideas :-)
Thanks,
We should probably just get rid of floats entirely and use decimals internally. Floats just have too much unexpected behavior. Anyone wanting real IEEE floats can still use numpy float scalars. Another thing is that a lot of people in numeric computing are used to open-ended indices starting at 1. I would like to see the starting index and whether an index is open-ended or closed-ended configurable on a per-module basis and/or with a context manager. Currently there is no empty set literal. This is a hold-over from when there were no sets. Now would be a good opportunity to add one. I suggest {} become an empty set and {:} be an empty dict.
![](https://secure.gravatar.com/avatar/d995b462a98fea412efa79d17ba3787a.jpg?s=120&d=mm&r=g)
On Mon, 1 Apr 2019 at 15:59, Todd <toddrjen@gmail.com> wrote:
Currently there is no empty set literal. This is a hold-over from when there were no sets. Now would be a good opportunity to add one. I suggest {} become an empty set and {:} be an empty dict.
There should be no need for two styles - now that Python has type inference, it should be possible for users to just type {} and have the interpreter work out which was intended from context. Any ambiguity can easily be resolved by using a type hint. Paul
![](https://secure.gravatar.com/avatar/72ee673975357d43d79069ac1cd6abda.jpg?s=120&d=mm&r=g)
Paul Moore wrote:
now that Python has type inference, it should be possible for users to just type {} and have the interpreter work out which was intended from context.
Or have {} return an ambiguous object that turns into a dict or set depending on what is done to it. We could call it a quict (quantum dict). To support this, we would also have to add a third possible value for type bool:
x = {} isinstance(x, dict) Maybe isinstance(x, set) Maybe x['foo'] = 42 isinstance(x, dict) True isinstance(x, set) False
-- Greg
![](https://secure.gravatar.com/avatar/400c33ea93f52b90b51859901fd88a92.jpg?s=120&d=mm&r=g)
On 02Apr2019 10:43, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Paul Moore wrote:
now that Python has type inference, it should be possible for users to just type {} and have the interpreter work out which was intended from context.
Or have {} return an ambiguous object that turns into a dict or set depending on what is done to it.
We could call it a quict (quantum dict). [...]
I have concerns that this may lead to excessive memory use. My personal interpretation of QM is the continuous many worlds form, where _all_ values of the field are valid and real, and where the supposedly "collapse" on observation/interaction is just a measurement effect: we in the classical domain measure a particular value of the field and all of our future classical view flows consistent with that measurement, but there is _no_ value collapse of the system; the classical operation with the specific value is just a specific view of the uncollapsed QM state space. This is analogous to Python "bool(some-float-value)": we get a True or False but the underlying value is unchanged. As such, the quict type should be managed by an underlying state with a thread local view; when current thread performs a dict-like or set-like operation on the quict that thread should get a thread-local dict or set flavour view of the quict, with the underlying quict still open. In this way multiple threads get their "collapsed" view of the underlying quict, directly supporting many worlds programme execution. Obviously, any operations which do not induce a dict/set "measurement" leave the quict in the uncollapsed view. And it follows that "print(quict)" of an uncollapsed quict should choose a dict or set view for that thread at random and from then on the quict would have that flavour in that thread. For simple dict/set quicts this presents a fairly capped memory use (two flavours, and per thread view state) but companion types such as the quoat have much more scope for heavy memory consumption. Cheers, Cameron Simpson <cs@cskk.id.au>
![](https://secure.gravatar.com/avatar/03cdc3c813a8646f783f97f7c66b8f3f.jpg?s=120&d=mm&r=g)
Please let's all agree that April 1 is the worst day of the year.
On 1 Apr 2019, at 16:27, Antoine Pietri <antoine.pietri1@gmail.com> wrote:
While the switch to Python 3 did an excellent job in removing some of the old inconsistencies we had in the language, pretty much everyone agrees that some other backwards-incompatible changes could be made to remove some old warts and bring even more consistency to Python.
Since Python 4 is getting closer and closer, I think it’s time to finally discuss some of the most obvious changes we should do for Python 4. Here is the list I compiled:
- The / operator returns floats, which loses information when both of the operands are integer. In Python 4, “1 / 2” should return a decimal.Decimal. To ease the transition, we propose to add a new “from __future__ import decimal_division” in Python 3.9 to enable this behavior. - As most of the Python ecosystem is moving towards async, some of the old I/O-blocking APIs should be progressively migrated to an async by default model. The most obvious candidate to start this transition is the print function, which blocks on the I/O of flushes. We propose to make “print” an async coroutine. In Python 3.9, this feature could be optionally enabled with “from __future__ import print_coroutine”. - To ease compatibility with the Windows API, the PyUnicode* objects should be internally represented as an array of uint16_t, as it would avoid the conversion overhead from UCS. CPython migration details are left as an exercise for the developer.
We think more changes are obviously warranted (e.g adding a new string formatting module, changing the semantic of the import system, using := in with statements...), but these changes will need specific threads of their own.
So, can you think of other backward-incompatible changes that should be done in Python 4? Don't hesitate to add your own ideas :-)
Thanks,
-- Antoine Pietri _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
![](https://secure.gravatar.com/avatar/5ce43469c0402a7db8d0cf86fa49da5a.jpg?s=120&d=mm&r=g)
On 2019-04-01 19:33, Paul Moore wrote:
On Mon, 1 Apr 2019 at 16:36, Anders Hovmöller <boxed@killingar.net> wrote:
Please let's all agree that April 1 is the worst day of the year.
Maybe in Python 4, datetime.datetime should silently convert 1st April to the 2nd? :-P
Converting silently is not Pythonic. It should raise an exception. :-)
![](https://secure.gravatar.com/avatar/5426055f54148a02d5d724ccbfdeca19.jpg?s=120&d=mm&r=g)
On 4/1/19 11:35 AM, Anders Hovmöller wrote:
Please let's all agree that April 1 is the worst day of the year.
I can't reproduce your problem. What version of Python are you running, and on what OS? Please show us your program, and tell us what you expected it to do and what it did that failed to meet those expectations. Copy and paste exactly any error messages or tracebacks you received. See also http://www.sscce.org/ for more information.
![](https://secure.gravatar.com/avatar/72ee673975357d43d79069ac1cd6abda.jpg?s=120&d=mm&r=g)
Anders Hovmöller wrote:
Please let's all agree that April 1 is the worst day of the year.
Agreed. In light of that, I propose that the datetime module in Python 4 be changed so that April 1 does not exist:
m31 = date(2019, 3, 31) m31 + timedelta(days = 1) datetime.date(2019, 4, 2)
This would remove a large amount of confusion from the world, and ensure that Python never receives any more backwards incompatible changes. Obviously, removing a whole day from the year will create problems keeping the calendar in step with the seasons. To compensate, it will be necessary to add approximately 1.25 days worth of leap seconds to each year. This works out to about one leap second every 5 minutes. If a suitable algorithm is devised for distributing these "leap minutes" as evenly as possible over the year, this should cause minimal disruption. -- Greg
![](https://secure.gravatar.com/avatar/2dde9ab55441548a981af3e43639fcbd.jpg?s=120&d=mm&r=g)
On Mon, Apr 1, 2019 at 6:12 PM Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Obviously, removing a whole day from the year will create problems keeping the calendar in step with the seasons. To compensate, it will be necessary to add approximately 1.25 days worth of leap seconds to each year. This works out to about one leap second every 5 minutes. If a suitable algorithm is devised for distributing these "leap minutes" as evenly as possible over the year, this should cause minimal disruption.
Far more disruption than you think, because that would result in daylight at midnight and nighttime at noon for a good chunk of the year. Instead, I suggest permanently extending February to 29 days instead, with a 30th day in leap years. This would limit the disruption to a single month (March), and only by an offset of one day. I never understood what February did wrong to be disrespected with such a short month anyway. Instead, February would be equal in length to April most of the time, and every four years (at least within our lifetimes *cough2100cough*) it would get to gloat over being longer than April.
![](https://secure.gravatar.com/avatar/d67ab5d94c2fed8ab6b727b62dc1b213.jpg?s=120&d=mm&r=g)
On Tue, Apr 2, 2019 at 9:34 AM Jonathan Goble <jcgoble3@gmail.com> wrote:
On Mon, Apr 1, 2019 at 6:12 PM Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Obviously, removing a whole day from the year will create problems keeping the calendar in step with the seasons. To compensate, it will be necessary to add approximately 1.25 days worth of leap seconds to each year. This works out to about one leap second every 5 minutes. If a suitable algorithm is devised for distributing these "leap minutes" as evenly as possible over the year, this should cause minimal disruption.
Far more disruption than you think, because that would result in daylight at midnight and nighttime at noon for a good chunk of the year. Instead, I suggest permanently extending February to 29 days instead, with a 30th day in leap years. This would limit the disruption to a single month (March), and only by an offset of one day. I never understood what February did wrong to be disrespected with such a short month anyway. Instead, February would be equal in length to April most of the time, and every four years (at least within our lifetimes *cough2100cough*) it would get to gloat over being longer than April.
You don't know what heinous crimes February committed, because they were overshadowed by March which violated the normal rules by not just having a single id(), but multiple. Beware the IDs of March. ChrisA
![](https://secure.gravatar.com/avatar/e2371bef92eb40cd7c586e9f2cc75cd8.jpg?s=120&d=mm&r=g)
Greg Ewing writes:
In light of that, I propose that the datetime module in Python 4 be changed so that April 1 does not exist:
m31 = date(2019, 3, 31) m31 + timedelta(days = 1) datetime.date(2019, 4, 2)
This would remove a large amount of confusion from the world, and ensure that Python never receives any more backwards incompatible changes.
Obviously, removing a whole day from the year will create problems
It's much simpler to rename April 1 to February 29. (Bikeshed that 29 is already taken, and make it February 30 if you like. And note that February will maintain its uniqueness in an even more prominent way, as the only temporally disconnected month!)
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
El lun., 1 abr. 2019 a las 7:28, Antoine Pietri (<antoine.pietri1@gmail.com>) escribió:
While the switch to Python 3 did an excellent job in removing some of the old inconsistencies we had in the language, pretty much everyone agrees that some other backwards-incompatible changes could be made to remove some old warts and bring even more consistency to Python.
Since Python 4 is getting closer and closer, I think it’s time to finally discuss some of the most obvious changes we should do for Python 4. Here is the list I compiled:
- The / operator returns floats, which loses information when both of the operands are integer. In Python 4, “1 / 2” should return a decimal.Decimal. To ease the transition, we propose to add a new “from __future__ import decimal_division” in Python 3.9 to enable this behavior.
More broadly, one of the best changes in Python 3 was the sanitization of the string/unicode logic: in Python 2 str and unicode were mostly-but-not-always interchangeable, but not always, and that led to a lot of hard to debug errors. Python 3 fixed this by separating the two more cleanly. Python 4 has the opportunity to do something similar to separate out another pair of easily confused types: int and float. Broadly speaking, we should use float for human-understandable numbers, and int for things that map directly to memory offsets in the computer, and we should avoid mixing them. This suggests the following changes: - int + float (and generally any mixed operation between ints and floats) should throw a TypeError - len() should return a float - list.__getitem__ should only accepts ints, not floats - integer overflow should use two's complement wraparound instead of infinite precision
- As most of the Python ecosystem is moving towards async, some of the old I/O-blocking APIs should be progressively migrated to an async by default model. The most obvious candidate to start this transition is the print function, which blocks on the I/O of flushes. We propose to make “print” an async coroutine. In Python 3.9, this feature could be optionally enabled with “from __future__ import print_coroutine”. - To ease compatibility with the Windows API, the PyUnicode* objects should be internally represented as an array of uint16_t, as it would avoid the conversion overhead from UCS. CPython migration details are left as an exercise for the developer.
We think more changes are obviously warranted (e.g adding a new string formatting module, changing the semantic of the import system, using := in with statements...), but these changes will need specific threads of their own.
So, can you think of other backward-incompatible changes that should be done in Python 4? Don't hesitate to add your own ideas :-)
Thanks,
-- Antoine Pietri _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
![](https://secure.gravatar.com/avatar/ab407447844ad283e478466005bb5896.jpg?s=120&d=mm&r=g)
Am I being fooled ? I guess yes That’s the worst idea I ever heard. Python is supposed to be easy to use, don’t change it into Rust ! On Mon 1 Apr 2019 at 22:06, Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
El lun., 1 abr. 2019 a las 7:28, Antoine Pietri (< antoine.pietri1@gmail.com>) escribió:
While the switch to Python 3 did an excellent job in removing some of the old inconsistencies we had in the language, pretty much everyone agrees that some other backwards-incompatible changes could be made to remove some old warts and bring even more consistency to Python.
Since Python 4 is getting closer and closer, I think it’s time to finally discuss some of the most obvious changes we should do for Python 4. Here is the list I compiled:
- The / operator returns floats, which loses information when both of the operands are integer. In Python 4, “1 / 2” should return a decimal.Decimal. To ease the transition, we propose to add a new “from __future__ import decimal_division” in Python 3.9 to enable this behavior.
More broadly, one of the best changes in Python 3 was the sanitization of the string/unicode logic: in Python 2 str and unicode were mostly-but-not-always interchangeable, but not always, and that led to a lot of hard to debug errors. Python 3 fixed this by separating the two more cleanly. Python 4 has the opportunity to do something similar to separate out another pair of easily confused types: int and float.
Broadly speaking, we should use float for human-understandable numbers, and int for things that map directly to memory offsets in the computer, and we should avoid mixing them. This suggests the following changes: - int + float (and generally any mixed operation between ints and floats) should throw a TypeError - len() should return a float - list.__getitem__ should only accepts ints, not floats - integer overflow should use two's complement wraparound instead of infinite precision
- As most of the Python ecosystem is moving towards async, some of the old I/O-blocking APIs should be progressively migrated to an async by default model. The most obvious candidate to start this transition is the print function, which blocks on the I/O of flushes. We propose to make “print” an async coroutine. In Python 3.9, this feature could be optionally enabled with “from __future__ import print_coroutine”. - To ease compatibility with the Windows API, the PyUnicode* objects should be internally represented as an array of uint16_t, as it would avoid the conversion overhead from UCS. CPython migration details are left as an exercise for the developer.
We think more changes are obviously warranted (e.g adding a new string formatting module, changing the semantic of the import system, using := in with statements...), but these changes will need specific threads of their own.
So, can you think of other backward-incompatible changes that should be done in Python 4? Don't hesitate to add your own ideas :-)
Thanks,
-- Antoine Pietri _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
participants (16)
-
Adrien Ricocotam
-
Anders Hovmöller
-
Antoine Pietri
-
Antoine Pitrou
-
Cameron Simpson
-
Chris Angelico
-
Dan Sommers
-
Eric Fahlgren
-
Greg Ewing
-
Jelle Zijlstra
-
Jonathan Goble
-
Jorropo .
-
MRAB
-
Paul Moore
-
Stephen J. Turnbull
-
Todd