News for hackers. Stuff that matters.
Re:Python dicts are now ordered by jkbbwr on Friday February 07, 2020 @10:47AM (#22267062)
Am I the only one that thinks this is a stupid decision? This will silently break code that starts to rely on this behaviour that gets executed on Python3.5 and lower. I would consider changing how a builtin works to be a major breaking change. It would have been fine if this was a change between 2 and 3 but on a minor version? Thats insane.
Re:Python dicts are now ordered by setr on Friday February 07, 2020 @10:52AM (#22267129)
I'm not clear on how this break existing code.

Code that assumed it was arbitrary, would expect to handle any arbitrary order, including a happens-to-be sorted order.

Code that assumed it was random, like actually inserted by random(), was already broken, because that simply isn't the case.

Code that assumed the order would stay constant was relying on implementation-specific behavior, and could potentially break on any version update; as with any reliance on implementation-specific behavior, you'd break if the dictionary code ever got touched -- even if it were for a bugfix.

Code that ordered the dictionary keys before iterating are now slightly innefficient due to extra work of sorting a sorted list.

Re:Python dicts are now ordered by biddlesby on Friday February 07, 2020 @10:57AM (#22267207)
It doesn’t break existing code. Code written for Python 3.7 might break on older versions of Python
Re:Python dicts are now ordered by jhrmnn on Friday February 07, 2020 @11:15AM (#22267421)
What you describe is forward compatibility, and Python (and most other programming language) doesn't have it.
Re:Python dicts are now ordered by jakear on Friday February 07, 2020 @11:31AM (#22267626)
Usually languages don’t have it in a very explicit way though. If I try to use f-strings in python 3.5 I get a very explicit syntax error. If I rely on ordered insertions in Python3.5 I get a potentially difficult to diagnose bug.
Re:Python dicts are now ordered by gnulinux on Friday February 07, 2020 @12:08PM (#22268125)
Why does it matter if it's explicit or not. If python doesn't support forward compatibility, you should know that if you write code for 3.7, it's not gonna work in 3.5. Doesn't seem like a big deal to me.
Re:Python dicts are now ordered by jakear on Friday February 07, 2020 @12:44PM (#22268566)
If you’re the only one writing it and you’re the only one running it, it’s probably fine. But if I’m putting a file out there that will only work in 3.7, it’d be nice if any potential users of that file would get a good error message if they try to run it on 3.5, rather than wrong results.

I could potentially assert a version, but do I really want to do that each time I wrote something that might be used somewhere else?

And yes of course I could add a line of documentation, but there is a 100% chance I’d still get bug reports from people on 3.5.

Re:Python dicts are now ordered by orf on Friday February 07, 2020 @05:52PM (#22272005)
Setuptools solves this, add a python version specifier to your setup.py or pyproject.toml file.

If you are just distributing raw python files then congratulations you’ve just realised why packaging is valuable.

Re:Python dicts are now ordered by Aachen on Saturday February 08, 2020 @06:09AM (#22275181)
If I rely on a python version and I expect other people to use it, I add a version if statement on top. I hate those packaging tools that insist on installing stuff in your system and create a frankendebian when really all I want to do is run a single py file standalone once. Often have to do chenanigans like "python3 -c 'from sometool import __app__'".

If you want to install it, go ahead and copy or symlink it in your ~/bin or whatever you fancy (that's your personal preference anyway unless I'd specifically package it for some OS like Debian). I don't want to have to use some setup.py that I have no clue where in my OS it installs things.

Re:Python dicts are now ordered by orf on Saturday February 08, 2020 @07:27AM (#22275398)
Yes, a failure to understand how your tools work or how to use them effectively does indeed make things harder.
Re:Python dicts are now ordered by Aachen on Saturday February 08, 2020 @06:36PM (#22279381)
Well I know how my tools work, I don't know how this custom file works that is duplicated and delivered with each project.
Re:Python dicts are now ordered by orf on Saturday February 08, 2020 @06:55PM (#22279460)
> I don't know how this custom file works that is duplicated and delivered with each project.

It's not duplicated and in most cases it's not even delivered as part of the installation.

> If you want to install it, go ahead and copy or symlink it in your ~/bin or whatever you fancy

That's exactly what pip will do if invoked with `--user`.

> I don't want to have to use some setup.py that I have no clue where in my OS it installs things.

It installs it to a single place. Run `python3 -m site` and look at `USER_BASE`.

To avoid a lot of this, use pipx[1] to keep things even more isolated.

> Often have to do chenanigans like "python3 -c 'from sometool import __app__'".

You're doing things wrong because you don't know the tooling. You'd also typically just do `python3 -m sometool`.

Things that are distributed as a single file are either so simplistic and have no other dependencies that you can just make do, or written by someone who doesn't know what they are doing and so you're going to have a bad time.

1. https://github.com/pipxproject/pipx

Re:Python dicts are now ordered by zeulhex on Friday February 07, 2020 @04:56PM (#22271441)
Most projects use setuptools for package management, which ensures that the environment is as expected.
Re:Python dicts are now ordered by lonelappde on Friday February 07, 2020 @02:05PM (#22269502)
If you write code that doesn't work in 3.5, you should check the version at startup and exit
Re:Python dicts are now ordered by jakear on Friday February 07, 2020 @05:36PM (#22271881)
Yes, that would be a good idea. But if you ever run scripts you didn’t write, there’s the potential people didn’t do this, and you have the potential for hard to discover bugs. The language should be designed such that bugs are difficult to encounter, this is an instance where it wasn’t.
Re:Python dicts are now ordered by fctorial on Friday February 07, 2020 @08:54PM (#22273177)
#!/usr/bin/env python3.7
Re:Python dicts are now ordered by gruez on Friday February 07, 2020 @11:43PM (#22273933)
so now you have to install a specific python version for your script to work?
Re:Python dicts are now ordered by fctorial on Saturday February 08, 2020 @08:04AM (#22275519)
Only if you're using version specific features.
Re:Python dicts are now ordered by jakear on Saturday February 08, 2020 @02:50PM (#22277930)
What happens when python 3.8 comes out? Everybody needs to go into your script to change the hashbang every time a new release comes?
Re:Python dicts are now ordered by sgillen on Sunday February 09, 2020 @04:03AM (#22281161)
you can just hashbang to python3 which is a symlink to whichever python3.X the user has.

If your code won’t work for older versions you can make an explicit check that the version of python is greater than whatever you need.

Re:Python dicts are now ordered by rmdashrfstar on Friday February 07, 2020 @12:22PM (#22268315)
Major version changes are for API compatibility. If there is a change which makes all other 3.* incompatible, then it should be a major version increase.
Re:Python dicts are now ordered by eatonphil on Friday February 07, 2020 @12:24PM (#22268348)
You're describing something like semver, but Python doesn't do semver.
Re:Python dicts are now ordered by dmurray on Friday February 07, 2020 @12:45PM (#22268574)
And this change would be fine even if Python did.
Re:Python dicts are now ordered by gnulinux on Friday February 07, 2020 @12:32PM (#22268437)
Who told you that? I'm looking at PEP 606, it says nothing like what you claim. https://www.python.org/dev/peps/pep-0606/
Re:Python dicts are now ordered by recursive on Friday February 07, 2020 @08:34PM (#22273089)
ECMAScript recently got stable array sorting. That can cause precisely the same kind of backwards-incompatible but difficult to diagnose bug.
Re:Python dicts are now ordered by abetlen on Friday February 07, 2020 @11:38AM (#22267706)
TIL

I suppose Python doesn't even have backwards compatibility within the same major release as we saw with the addition of the async keyword in Python3.5. Many older Python 3 packages broke because they expected that to be a legal identifier for a variable name.

Re:Python dicts are now ordered by hprotagonist on Friday February 07, 2020 @12:36PM (#22268472)
tensorflow didn't work on 3.7 for a solid 8 months because some people at google very unwisely decided that `async` and `await` were great choices for variable names, despite PEP492 landing in 2015.
Re:Python dicts are now ordered by fock on Friday February 07, 2020 @01:57PM (#22269391)
that's because tensorflow is advertisement for Google and while it's technically open-source, it doesn't stand for any kind of community-project, it's all there to show off (and ingrain in its users) the way Google wants things to Go (just look at the byzantine Bazel-build-processes - tensorflow taking hours to build and pytorch about 10minutes...).
Re:Python dicts are now ordered by hprotagonist on Friday February 07, 2020 @02:47PM (#22270056)
my torch builds also take hours.

facebook is just as capable of writing hot garbage, sadly.

Re:Python dicts are now ordered by fock on Friday February 07, 2020 @03:33PM (#22270602)
Yeah, still it's an order of magnitudes faster...
Re:Python dicts are now ordered by VWWHFSfQ on Friday February 07, 2020 @11:46AM (#22267807)
Python has never tried to maintain backwards compatibility within a major release
Re:Python dicts are now ordered by setr on Friday February 07, 2020 @11:03AM (#22267266)
You're right, I read the gp too quickly.

But in the case of downgrading, I'm fairly sure there's a number of other breaking changes that can't trivially downgrade minor versions. Like f-strings were only introduced in python3.6 as I recall. Async keyword only exists as of 3.4 as well I think?

Re:Python dicts are now ordered by rflrob on Friday February 07, 2020 @11:18AM (#22267463)
I think the argument is that if you run code with f-strings and walruses on Python 3.5, the code will break noisily. Whereas if your code implicitly relies on ordered dicts, it could break silently. Syntax errors rarely cause subtle, hard to track bugs.
Re:Python dicts are now ordered by ses1984 on Friday February 07, 2020 @11:05AM (#22267293)
Introducing things is different than changing things.
Re:Python dicts are now ordered by setr on Friday February 07, 2020 @11:12AM (#22267384)
Sure, but you can't safely take everything from a higher version to a lower version in any case; if insertion order became gauranteed due to a bugfix, and wasn't backported, you'd be in the same boat.

The only way to consistently code cross-version is to start with the lowest you plan to support (assuming the higher versions are actually backwards-compatible).

Does any language gaurantee that code is both backwards and forwards compatible?

Re:Python dicts are now ordered by peteradio on Friday February 07, 2020 @11:36AM (#22267681)
Issue seems to be silent incorrect behavior, what happens if you attempt to run python code containing f-strings using an older python version. Does it raise an exception? That's good! What happens now if you write code for 3.7 which takes advantage of the new ordering and someone grabs it from your repo and runs it using 3.2, it would happily give incorrect results and noone is the wiser.
Re:Python dicts are now ordered by visarga on Friday February 07, 2020 @02:07PM (#22269523)
If you expect this situation you can assert the language version.
Re:Python dicts are now ordered by drdaeman on Friday February 07, 2020 @02:25PM (#22269749)
But the whole point is that some developer won’t expect that someone would run their code on an older Python, isn’t it?
Re:Python dicts are now ordered by muldvarp on Friday February 07, 2020 @11:25AM (#22267553)
Both of these would be syntax errors if you tried to execute them in earlier python versions. This change might break software completely silently.
Re:Python dicts are now ordered by hprotagonist on Friday February 07, 2020 @11:11AM (#22267352)
If you know you're supporting old code, use OrderedDict.

you arguably ought to anyway, for explicitness.

Re:Python dicts are now ordered by masklinn on Friday February 07, 2020 @11:51AM (#22267887)
OrderedDict is slow and expensive though: it maintains ordering through a doubly linked list.

It has useful features for manipulating ordering but while I've regularly needed had use for maintaining insertion ordering I can't remember ever needing to move items around within a map.

Re:Python dicts are now ordered by hencoappel on Friday February 07, 2020 @05:22PM (#22271746)
If memory serves me correctly, ever since dicts became ordered the OrderedDict simply became a subclass of dict, so it will have exactly the same performance characteristics.
Re:Python dicts are now ordered by masklinn on Friday February 07, 2020 @05:34PM (#22271862)
OrderedDict was always a subclass of dict maintaining additional information (which is not free, it has to store and manipulate two pointers per entry).

It remains so today, ordereddict is not an alias or trivial facade to the normal dict because it has to maintain its doubly linked list and implement a bunch of additional operations based on that e.g. pop first or move to end.

Re:Python dicts are now ordered by edflsafoiewq on Friday February 07, 2020 @05:31PM (#22271838)
Yup.

    >>> isinstance(OrderedDict(), dict)
    True
Re:Python dicts are now ordered by masklinn on Friday February 07, 2020 @05:37PM (#22271888)
That was already the case in python 2.7 or 3.1.
Re:Python dicts are now ordered by harikb on Friday February 07, 2020 @11:17AM (#22267448)
The trouble is I publish a (new) code that advertises itself as working on 3.x and then it turns out it is being used by a person who only had the version prior to this change.

That said, Go made a similar change (from insertion-order to explicitly-randomized) and world didn’t end. So there’s that.

Re:Python dicts are now ordered by ryebit on Friday February 07, 2020 @11:26AM (#22267557)
If your code relies on a minimum python version, you can add `python_requires=">=3.5"` to your setup.py [https://packaging.python.org/guides/distributing-packages-us...] to ensure it's not installed on older releases.

That field itself is kinda new; but if needing to block users with older versions, that shouldn't be an issue.

Re:Python dicts are now ordered by hprotagonist on Friday February 07, 2020 @12:32PM (#22268426)
personally, i just drop a f-string in setup.py and that'll filter out any python for which this issue pertains.
Re:Python dicts are now ordered by baq on Friday February 07, 2020 @01:11PM (#22268882)
This might not work if you’re distributing a wheel.
Re:Python dicts are now ordered by AdamN on Friday February 07, 2020 @12:49PM (#22268625)
Python 3.4 is EOL anyway so there's no need to do this. Anybody running 3.4 is already unsupported.
Re:Python dicts are now ordered by hprotagonist on Friday February 07, 2020 @06:42PM (#22272389)
and 3.5 dies in september. hurray!
Re:Python dicts are now ordered by strken on Friday February 07, 2020 @12:53PM (#22268672)
I thought Go made the change from undefined behaviour with an underlying implementation that was insertion order in a map with 8 or fewer entries, to similarly undefined behaviour with an implementation that randomised lookups in those cases. Any code that has ever relied on any kind of ordering in Go maps will almost certainly be wrong, even random ordering, because the distribution of the "random" ordering is biased.

See https://medium.com/i0exception/map-iteration-in-go-275abb76f...

Re:Python dicts are now ordered by throwaway894345 on Friday February 07, 2020 @12:23PM (#22268335)
FWIW, when Go made that change, it was a much less-widely-used language (smaller blast radius).
Re:Python dicts are now ordered by yurlungur on Friday February 07, 2020 @12:53PM (#22268673)
Yeah I think this is probably my main issue. I don't think it's reasonable to ask users of your code to always use 3.7+ instead of 3.6 if they are usually expected to be compatible. And it's also unnecessary to break such compatibility for something like preferring dict over OrderedDict anyways. At least I would try to avoid any such issues by still using OrderedDict.

That said, I have no idea about the internals of dict. I assume no performance was sacrificed for this change.

Re:Python dicts are now ordered by TheFlyingFish on Friday February 07, 2020 @02:09PM (#22269553)
It actually improves performance. Or at least, it comes along with a set of performance improvements that give you ordering for free. Raymond Hettinger has a great talk on it: https://www.youtube.com/watch?v=npw4s1QTmPg&t=1s
Re:Python dicts are now ordered by viraptor on Friday February 07, 2020 @05:12PM (#22271634)
Using OrderedDict is actually nice in this case, even if the default dict has the same ordering. That way you're explicitly saying you rely on that behaviour and it makes reading the code easier.
Re:Python dicts are now ordered by ouid on Friday February 07, 2020 @11:13AM (#22267397)
right, so making it implicit is bad design
Re:Python dicts are now ordered by mark-r on Friday February 07, 2020 @11:28AM (#22267590)
It's part of the zen of Python: Explicit is better than implicit.
Re:Python dicts are now ordered by skedaddle on Friday February 07, 2020 @01:32PM (#22269099)
Python is nothing like its guiding principles. That's why it's Zen -- the principles are a collection of contradictory statements, given what you will encounter in real world Python. You're meant to be confused and meditate on it.
Re:Python dicts are now ordered by takeda on Friday February 07, 2020 @01:42PM (#22269194)
Well... full support for 3.6 ended in December of 2018 (now it only has security fixes), the older versions are already unsupported.

Also, this change was implemented 3.6, but in 3.7 they officially documented it as a language feature (i.e. that all other Python implementations also need to preserve the order).

Re:Python dicts are now ordered by ehsankia on Friday February 07, 2020 @01:49PM (#22269278)
Furthermore, there's a lot more stuff that are not backward compatible after 3.6 or 3.7, and if you're writing a library that targets other versions, I would hope that you have tests for all said versions.
Re:Python dicts are now ordered by njharman on Saturday February 08, 2020 @03:25AM (#22274704)
> Code written for Python 3.7 might break on older versions of Python

That's a truism. For all versions of Python. If you use feature of python ver X, you should not be surprised that it doesn't run on versions less than X that lack that feature!!!

If you write a Python library and use feature of Python ver X and don't mark library as only >= Python ver X, you are doing it wrong and a horrible person.

Re:Python dicts are now ordered by andybak on Friday February 07, 2020 @11:41AM (#22267740)
What versions of Python didn't have this behaviour? It was there but just not guaranteed.

I don't see how anything could break (unless there are alternative implementations with different behaviour I'm not aware of?)

Re:Python dicts are now ordered by masklinn on Friday February 07, 2020 @11:49AM (#22267859)
> It was there but just not guaranteed.

Dicts have been effectively ordered since 3.6. Iteration order was literally randomised (at process start) before 3.6. I'm also not sure whether the behaviour under deletion was changed between 3.6 and 3.7 so it's possible that there are subtle differences there.

Re:Python dicts are now ordered by dbcurtis on Friday February 07, 2020 @11:07AM (#22267320)
CPython is mot the only Python. Portability is an issue also.
Re:Python dicts are now ordered by maxnoe on Friday February 07, 2020 @11:18AM (#22267458)
This ja why it is now a language feature. Every python implementation that claims python 3.7 compatability must implement this.

The other why around is also true, code that relies on it must specify that it requires python >= 3.7

Re:Python dicts are now ordered by setr on Friday February 07, 2020 @11:20AM (#22267483)
Portability isn't affected; if they claim compatibility with python3.7, then they claim their dicts have insertion-ordered keys.

If they claim compatibility with only up to python3.6, they can have whatever order they choose.

The only issue with portability is that I think the main reason it was made a gaurantee is that cpython found the new, presumably optimized, implementation came with insertion order for free, so they went ahead and gauranteed it. But that might not be an optimal strategy in other areas, but they're forced to follow along anyways.

But actually moving cpython code to say ironpython should not be impacted, unless ironpython lies about it's compatibility

Re:Python dicts are now ordered by masklinn on Friday February 07, 2020 @11:52AM (#22267901)
That also goes both way: Pypy defaulted to ordered dicts a few years before cpython did.
Re:Python dicts are now ordered by maxnoe on Friday February 07, 2020 @12:52PM (#22268668)
The insertion order dict implementation actually comes from pypy
Re:Python dicts are now ordered by masklinn on Friday February 07, 2020 @01:43PM (#22269196)
The insertion order dict implementation comes from Raymond Hettinger who is amongst other things a core CPython developer. pypy pulled the trigger on using it first (and probably has optimisations CPython doesn't). PHP also used it before CPython did, IIRC. And possibly Rust (as the third-party indexmap).
Re:Python dicts are now ordered by nicklarsennz on Monday February 10, 2020 @09:46PM (#22295546)
Do you mean to say the future should be constrained by the past?

I get the whole principal of least surprise, but not at the expense of progress.

Re:Python dicts are now ordered by klyrs on Friday February 07, 2020 @11:10AM (#22267340)
> Code that ordered the dictionary keys before iterating are now slightly innefficient due to extra work of sorting a sorted list.

Dicts are ordered, specifically insertion-ordered, not sorted.

Sometimes they'll be sorted:

  D = {i:i for i in range(10)}
... specifically, when you insert them in sorted order. But then you can break the sortedness on your next insert:

  D[-1] = -1
What it allows is parallel iteration:

  zip(D.keys(), D.values())
now being synonymous with

  D.items()
This enables, nay, encourages people to write code that is very subtly broken in 3.5 and below.
Re:Python dicts are now ordered by throwaway287391 on Friday February 07, 2020 @12:27PM (#22268376)
The property you mention at the end has been true of dicts since long before 3.5, at least since 2.7 if not forever. See https://docs.python.org/2/library/stdtypes.html#dict.items :

> If items(), keys(), values(), iteritems(), iterkeys(), and itervalues() are called with no intervening modifications to the dictionary, the lists will directly correspond. This allows the creation of (value, key) pairs using zip(): pairs = zip(d.values(), d.keys()).

Re:Python dicts are now ordered by klyrs on Friday February 07, 2020 @01:10PM (#22268866)
Sorry, yes, I was hasty. Ordered dicts supports such a thing with intervening modifications:

  oldkeys = list(D.keys())
  D[z] = foo(z)
now if you take

  zip(oldkeys, D.values())
then you're guaranteed to iterate over oldkeys, with the proper values associated with those keys -- if z was an oldkey, its value got updated; otherwise, it comes after oldkeys and gets dropped out of zip.

The subtlety of this is what I, and perhaps others, find the most jarring.

Re:Python dicts are now ordered by hayd on Friday February 07, 2020 @12:26PM (#22268364)
Dicts are ordered in certain cases in python 2, and it was relied upon by some users (I saw it in the wild).

Baking this as a language guarantee is the only protection against Hyrum's Law.

Re:Python dicts are now ordered by LeifCarrotson on Friday February 07, 2020 @11:22AM (#22267500)
This won't break existing code. It will break new, good code that gets back-ported from eg. a 3.7 tutorial to a 3.5 environment, without any syntax errors.

> Changed in version 3.7: LIFO order is now guaranteed. In prior versions, `popitem()` would return an arbitrary key/value pair. [1]

If they added a new `popordereditem()` method, good 3.7 code would use that, and an attempt to run that code on 3.5 would throw a reasonable, useful error message. If they wanted to play it safe like Rust or Go, they'd add the ordered method and make popitem() deprecated or make it artificially use random/arbitrary order so you can't accidentally depend on a new implementation detail and have a test case work.

Also, your case 4 does deserve some protection because while bad code it's hard to test for bad but working code. Implementation-specific or undefined behavior that works is the worst kind of problem, because it's hardest to test against. Compile-time syntax errors are the easiest, runtime errors are testable with a solid test harness, some possible can be identified as warnings with linters, but sloppy code requires manual inspection to detect.

Actually, no, I take that back: Implementation-specific or undefined behavior that works sometimes! is the worst kind of problem. That's what this code enables; if your test case is `dict({'one': True, 'two': True})` and you have a unit test where you popitem() to assert that you get 'two' and then 'one' it will pass the test harness on 3.7, it will pass on 3.6 because of implementation-specific behavior, and it will pass on 3.5 because the hash map arbitrarily puts those particular items in order. But it will silently get it wrong when you pass in user-supplied data. Shudder.

[1]: https://docs.python.org/3/library/stdtypes.html#dict.popitem

Re:Python dicts are now ordered by mark-r on Friday February 07, 2020 @11:31AM (#22267623)
> Code that ordered the dictionary keys before iterating are now slightly innefficient due to extra work of sorting a sorted list.

I think TimSort is extremely efficient for presorted lists, so even that isn't a major impediment.

Re:Python dicts are now ordered by mumblemumble on Friday February 07, 2020 @10:59AM (#22267231)
I'm of two minds. In principle, no, I don't love the idea of a change like this happening on a minor version.

But, from a pragmatic angle, it strikes me as a genius move. As the article said, this was a natural by-product of a performance enhancement that was made in 3.6. In principle, that was fine, because there was officially no predictable ordering, so a change to how it was being ordered in practice shouldn't materially affect anyone. And nobody really paid much notice to it then.

And that's where the danger lies - there's risk there, because, as you said, someone who's used to Python 3.6 might have problems switching to 3.5. And that's probably a greater risk if they left it out of the spec, because people would have continued to not pay it much notice. By making it official in 3.7, though, they've sent out a message that the Internet hate machine has ensured that everyone will hear. That probably, in practice, actually reduces the risk.

And, while many understandably see this as violating the spirit of semver, it unambiguously does not break the letter: Minor changes are only supposed to avoid breaking the software's compatibility with code written against an old version. There was never any rule saying that old versions have to be compatible with code written against the new version.

Re:Python dicts are now ordered by frosted-flakes on Friday February 07, 2020 @12:20PM (#22268289)
Python (the language) doesn't follow semver anyway.
Re:Python dicts are now ordered by kyrra on Friday February 07, 2020 @10:52AM (#22267126)
Go purposely "randomizes" order of a map when it's iterated over, which you can see running this demo:

https://play.golang.org/p/DISpyv0Zuq_j

HN discussed this a little 6 years ago: https://news.ycombinator.com/item?id=7655948

As crawshaw pointed in that discussion, it helps catch people inadvertently relying on map order in tests or other places in their code.

Re:Python dicts are now ordered by ipsin on Friday February 07, 2020 @11:04AM (#22267286)
More important (in my opinion), adding a random seed to your hash prevents collision attacks, where an attacker tries to ruin your performance by sending many values (e.g. HTTP params) that would hash to the same bucket.
Re:Python dicts are now ordered by tomp on Friday February 07, 2020 @11:55AM (#22267945)
Many (most?) programming language runtimes now do this, especially the web-focused ones. But it's completely orthogonal to insertion-ordered iteration (which is implemented by a list).
Re:Python dicts are now ordered by throwaway8291 on Friday February 07, 2020 @11:03AM (#22267265)
That surprised me, when I first saw it. If someone takes a minute to read the docs (e.g. Python), one would never build something knowing that order is not guaranteed (e.g. order in dictionaries). But seemingly people do.
Re:Python dicts are now ordered by UncleEntity on Friday February 07, 2020 @11:54AM (#22267926)
Had some code break while porting from 2 to 3 because it assumed dict order and it was part of the official Python build system, the old spark parser for the AST module.
Re:Python dicts are now ordered by Sean1708 on Friday February 07, 2020 @11:06AM (#22267300)
My main issue with it is that if someone figures out an even better way to do dictionaries but it doesn't preserve insertion order, then that technique can't be used. But I certainly wouldn't call it a stupid decision, the problem is that once a behaviour is observable then people absolutely will start relying on it.
Re:Python dicts are now ordered by mark-r on Friday February 07, 2020 @11:41AM (#22267736)
All they have to do is give it a different name, such as unordered_dict.
Re:Python dicts are now ordered by jmilloy on Friday February 07, 2020 @01:12PM (#22268891)
I might have preferred odict be added and dict left alone, so that you didn't have to import OrderedDict when really you just want the new dict. If dict and odict mapped to the same thing for a while, fine, but dict could diverge again if desired.
Re:Python dicts are now ordered by masklinn on Friday February 07, 2020 @02:12PM (#22269592)
The problem is that when you behave a certain predictable and deterministic way users will leverage that even if it's not specified.

That is actually why the Python maintainers decided to make this behaviour official: the ordering was the consequence of changes in implementation details, but over 3.6's lifecycle they feared it would cause compatibility issues as users would start relying on the ordering properties of CPython and that would be an issue for alternate implementations (though pypy had switched to the same implementation even earlier so was also insertion-ordered even when running in Python 2.7 mode).

Providing stronger guarantees was considered useful and unlikely to be severely detrimental in the long run, so the project decided to make it part of the language spec.

Re:Python dicts are now ordered by thedirt0115 on Friday February 07, 2020 @02:45PM (#22270036)
"users will leverage that even if it's not specified" -- reminds me of the classic xkcd, "Workflow": https://xkcd.com/1172
Re:Python dicts are now ordered by mark-r on Friday February 07, 2020 @02:58PM (#22270194)
An xkcd in the thousands is now considered "classic"? Man I'm getting old.
Re:Python dicts are now ordered by compiler-guy on Friday February 07, 2020 @12:36PM (#22268476)
Which means no one gets it for free when it is added to the language.
Re:Python dicts are now ordered by jmilloy on Friday February 07, 2020 @01:16PM (#22268938)
You could add an ordered dict by a different name and also have dict be the more efficient ordered version so that people get the efficiency gain for free but don't have to worry and forward compatibility.
Re:Python dicts are now ordered by harikb on Friday February 07, 2020 @11:24AM (#22267530)
I think this is a key point. Since they advertised this, it became a commitment for all future versions. Sure they can break again in 4.0
Re:Python dicts are now ordered by jrockway on Friday February 07, 2020 @06:54PM (#22272462)
Maintaining insertion order is strictly a product of adding an additional list to whatever more efficient map you implement. Add something to a dict, push it onto the end of the list. When iterating over the keys, use the list instead of the dict structure.

It does come at a cost, but I think Python aims for ease of use over runtime speed and memory efficiency, so it seems perfect for them.

Re:Python dicts are now ordered by _bxg1 on Friday February 07, 2020 @10:58AM (#22267215)
> I would consider changing how a builtin works to be a major breaking change.

This one is unusual because it won't break old code being brought forward, only the other way around, and theoretically there are lots of things going the other direction that would break (though most of them are explicit, not silent).

Re:Python dicts are now ordered by manaskarekar on Friday February 07, 2020 @11:16AM (#22267435)
In other words, it breaks backwards compatibility, but not forward compatibility.
Re:Python dicts are now ordered by elcomet on Friday February 07, 2020 @11:23AM (#22267522)
That's not what people call backward compatibility.

Backward compatibility is the ability to run old code with new interpreters. This is not broken here.

What's broken is the ability to run new code on old interpreters. But this is already broken at every python update (new operators, methods, syntactic sugar..). We could call it reverse backward compatibility.

Re:Python dicts are now ordered by manaskarekar on Friday February 07, 2020 @11:30AM (#22267616)
I suppose the meaning of the term depends on what we consider to be the subject of the compatibility.

- backwards compatible code: new code can run on an old interpreter

- backwards compatible interpreter: old code can run on a new interpreter

EDIT: After some thought, you're right. The second description is the reasonable interpretation.

"python 3.7 is backwards compatible with python 3.6"

Re:Python dicts are now ordered by rovolo on Friday February 07, 2020 @04:48PM (#22271347)
This confusion reminds me of a scene from the 2002 film of Dave Barry's "Big Trouble".

(Driving to an airport) "Okay, we gotta pick a road. Arrivals or departures? We're arriving, but then we're departing."

https://en.wikiquote.org/wiki/Big_Trouble

https://www.youtube.com/watch?v=EjHHzZAUxbM&t=300

Re:Python dicts are now ordered by gnulinux on Friday February 07, 2020 @12:11PM (#22268169)
No, this change is backward compatible but not forward compatible. Old code (written for old interpreter) works in new interpreter; but new code (written for new interpreter) is broken in old interpreter.
Re:Python dicts are now ordered by riazrizvi on Friday February 07, 2020 @11:22AM (#22267508)
That is an original line of thinking in the world of software, “Let’s not add a feature to a new version because it wouldn’t work if used in an older version”.
Re:Python dicts are now ordered by Biganon on Friday February 07, 2020 @11:44AM (#22267788)
It would silently introduce bugs, that's the whole issue.
Re:Python dicts are now ordered by nkozyra on Friday February 07, 2020 @12:07PM (#22268104)
Right. In fact, if it explicitly broke something there'd be less of an issue. Instead, it will appear to work/interpret but you'll get unreliable results. That makes the bug more nebulous.
Re:Python dicts are now ordered by ptero on Friday February 07, 2020 @12:05PM (#22268083)
I think you are giving it bigger weight than it deserves. Writing Python code I would not want to depend on internal order of dict elements without a very good reason. If I am writing some low level code that could benefit from it, maybe I would use this feature, but I would then encapsulate it and insert a version check to complain.

This is like many evaluation guarantees in latest C++-NN standards. Good to know, might be useful for performance tuning of automatic code generators, etc. , but irrelevant most of the time. My 2c.

Re:Python dicts are now ordered by Waterluvian on Friday February 07, 2020 @10:59AM (#22267224)
You can't walk Python code backwards anyway without already considering the minor version differences. eg. f'strings'.
Re:Python dicts are now ordered by jkbbwr on Friday February 07, 2020 @11:02AM (#22267259)
At least f"strings" are an explicit failure case and are obvious when you run unit tests / coverage
Re:Python dicts are now ordered by elcomet on Friday February 07, 2020 @11:24AM (#22267541)
Not only f strings, but any change really.. New operators, new methods on standard library objects... Python never guaranteed compatibility of new code with old interpreters.
Re:Python dicts are now ordered by toyg on Friday February 07, 2020 @12:22PM (#22268316)
If you rely on this feature, surely you know it’s new to 3.7 and document your project accordingly...? It’s not like code magically appears, somebody has to write it.
Re:Python dicts are now ordered by doubleunplussed on Friday February 07, 2020 @10:55AM (#22267177)
3.5 is EOL soon, and it's already uncommon to write code using a new interpreter that targets an older interpreter - there's more than just ordered dicts that you'll be missing if you do so.

People will just do what they've always done - they'll be aware of the differences, or they'll test.

There's nowhere I have seen that mentions dicts are ordered without mentioning in the same paragraph the version since which this has been the case, so anyone who knows they're ordered will be aware.

Tldr its fine

Re:Python dicts are now ordered by OJFord on Friday February 07, 2020 @11:57AM (#22267977)
It's not breaking, it was implementation defined, now it's guaranteed order.

If a new guarantee or behaviour were a breaking change, every non-patch release of a semversioned tool (which python isn't) would be major.

Re:Python dicts are now ordered by masklinn on Friday February 07, 2020 @02:15PM (#22269623)
> It's not breaking, it was implementation defined

And randomised at interpreter start, since Python 3.3.

Re:Python dicts are now ordered by nkozyra on Friday February 07, 2020 @12:07PM (#22268117)
> It's not breaking

And that's sort of the problem. If it was broken, you'd know it and you'd fix/rearchitect it. Instead, it will appear to work.

Re:Python dicts are now ordered by dagmx on Friday February 07, 2020 @12:16PM (#22268235)
Sort of. You'd only know based on the interpreter you were using. You wouldn't know unless you tested other Python interpreters.

For example, if you wrote something in pypy it would be ordered versus cpython.

Re:Python dicts are now ordered by boublepop on Friday February 07, 2020 @02:23PM (#22269718)
Code that assumes no order cannot be broken by a specific order unless it was setup to assume everything but that specific order in which case it was already broken, but only randomly showing it’s broken nature.
Re:Python dicts are now ordered by kayf on Friday February 07, 2020 @11:12AM (#22267369)
Actualy, dict are already ordered since a long time(since python 3 I think), but it wasn't certified. It was just the result of a new implementation of dict structure.

I can't imagine how it can break something. In which case can you have an advantage to have an unordered list? Biggest downside can be about perf, but I don't think it's the case here.

Re:Python dicts are now ordered by pantsforbirds on Friday February 07, 2020 @11:32AM (#22267643)
python 3.6 is when they reworked the dictionary and had the side effect of being ordered.
Re:Python dicts are now ordered by hinkley on Friday February 07, 2020 @05:56PM (#22272035)
For anyone who came to Unit Testing with the XP era and happened to use Java, Java 5 introduced changes to hash table ordering that somehow resulted in Junit 3.0 running some tests in a different order.

It's important to discover coupling between your tests, this just isn't the way most people want to do it.

Re:Python dicts are now ordered by jokoon on Friday February 07, 2020 @11:15AM (#22267418)
I don't see exactly how one would rely on dicts not being sorted, as it was already answered by another comments.

And beyond this, even if maintaining backward compatibility is important, I don't think it should prevent software from being improved, and dicts being ordered is pretty awesome. I'm pretty sure relying on unsorted dicts might involve pretty hacky code.

I recently stopped writing a z-order test application because I remembered that dicts are not sorted, so it made my goal a little pointless. Meanwhile C++'s std::map is sorted. I think there was already sorted dict in python, but I don't remember.

EDIT: I'm wrong, I'm mixing "ordered" and "sorted"

Re:Python dicts are now ordered by pmart123 on Friday February 07, 2020 @10:54AM (#22267162)
I agree, but more from the point of view on what if a new unordered implement if discovered 10 years from now that’s better? Would a new type have to be added?
Re:Python dicts are now ordered by wodenokoto on Saturday February 08, 2020 @05:59AM (#22275155)
I think you bring up a good point. If someone hands me a python script and told me it was 3.7 I would only hear 3 and expect it to run or fail, not to run with differing outputs!

Dot-upgrades do allow for breaking changes, but this one can break silently and I’m not sure where such breakages neither belongs in python nor where they should belong.

Personally I’m happy to get ordered ducts sooner rather than later.

Re:Python dicts are now ordered by jmilloy on Friday February 07, 2020 @12:58PM (#22268740)
I think if you are a library developer targeting different versions of Python, you generally know what features you can and can't use from new versions of Python (ie not many), and ideally you are also testing with each version in CI.
Re:Python dicts are now ordered by carapace on Friday February 07, 2020 @01:48PM (#22269260)
No, I agree, it's stupid. To me it feels like a kind of conceptual backwash from JS. The whole P3 fiasco looks really silly from far enough away.

It's like, you have a great marriage with everything working out and some fine children who are doing great too, but you get a divorce anyway to pursue your dreams of being a conceptual artist.

(BTW, in case anyone is keeping track, I was going to maintain P2 but got caught up in Prolog, of all things, and now Python looks just as crude as everything else and I don't have the requisite love anymore to shoulder the work. I might make a Python 2 interpreter in Prolog though! That would be fun.)

Re:Python dicts are now ordered by nwsm on Friday February 07, 2020 @12:44PM (#22268562)
By that logic, any change would be considered "breaking" because people will expect that the change also exists in older versions.
Re:Python dicts are now ordered by pcj-github on Friday February 07, 2020 @02:59PM (#22270211)
This was my initial thought as well. Seems like people are celebrating, but this is going to be a source of difficult to figure out bugs.
Re:Python dicts are now ordered by EGreg on Friday February 07, 2020 @11:10AM (#22267343)
PHP has had this undocumented feature since forever and so did all mainstream Javascript engines.

Big whoop

Re:Python dicts are now ordered by dehrmann on Friday February 07, 2020 @11:34AM (#22267664)
> Javascript

Javascript doesn't specify performance characteristics of objects and arrays, so even with implementations, one object could be a hashtable, another a balanced tree.

Re:Python dicts are now ordered by Arnavion on Friday February 07, 2020 @12:51PM (#22268646)
The implementation doesn't matter to EGreg's point, which is that ES standardized that iterating over object keys are generally required to return keys in insertion order.

In the past (from before this standardization) Chrome had in fact changed the object iteration order due to an optimization, and had to revert it after lots of complaining on their bug tracker.

(To be precise, the spec still requires array index properties to be returned ahead of other properties regardless of insertion order. The behavior that Chrome "reverted" to is this new one, so not exactly the same as the original behavior.)