Live data from Hacker News

Python dicts are now ordered

softwaremaniacs.org

61–70 of 457 posts

Re: Python dicts are now ordered

#61

Earlier quoted context omitted.

It doesn’t break existing code. Code written for Python 3.7 might break on older versions of Python

If you know you're supporting old code, use OrderedDict. you arguably ought to anyway, for explicitness.

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

#62

Earlier quoted context omitted.

It doesn’t break existing code. Code written for Python 3.7 might break on older versions of Python

CPython is mot the only Python. Portability is an issue also.

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

#63
post #36

Earlier quoted context omitted.

It doesn’t break existing code. Code written for Python 3.7 might break on older versions of Python

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?

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

#64

Earlier quoted context omitted.

It doesn’t break existing code. Code written for Python 3.7 might break on older versions of Python

CPython is mot the only Python. Portability is an issue also.

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

#66
post #42

I still see dict ordering as an implementation detail; not a technical one but a descriptive one. If you want to rely on insertion order, use collections.OrderedDict. It communicates your intention far better, and there should be no overhead.

OrderedDict is less efficient. It's best to replace usage with basic dict where possible to improve efficiency. There is one obscure feature of OrderedDict that isn't in the basic, so it can't always be swapped.

Re: Python dicts are now ordered

#67
post #20
post #15

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.

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…

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

#68
post #15

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.

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

#69
post #28

Earlier quoted context omitted.

> 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).

In other words, it breaks backwards compatibility, but not forward compatibility.

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

#70
post #66
post #42

I still see dict ordering as an implementation detail; not a technical one but a descriptive one. If you want to rely on insertion order, use collections.OrderedDict. It communicates your intention far better, and there should be no overhead.

OrderedDict is less efficient. It's best to replace usage with basic dict where possible to improve efficiency. There is one obscure feature of OrderedDict that isn't in the basic, so it can't always be swapped.

Really? I would have figured they'd just do something like:

    class OrderedDict(dict):
        pass
(Plus a little bit of API shimming.)
Post reply on HN