
On Sun, Jan 10, 2016 at 7:37 PM, Andrew Barnert <abarnert@yahoo.com> wrote:
On Jan 10, 2016, at 10:35, Neil Girdhar <mistersheik@gmail.com> wrote:
On Sun, Jan 10, 2016 at 12:57 PM, Steven D'Aprano <steve@pearwood.info> wrote:
On Sun, Jan 10, 2016 at 11:48:35AM -0500, Neil Girdhar wrote:
[...]
v = mydict.__version__ maybe_modify(mydict) if v != mydict.__version__: print("dict has changed")
This is exactly what I want to avoid. If you want to do something like this, I think you should do it in regular Python by subclassing dict and overriding the mutating methods.
That doesn't help Victor, because exec need an actual dict, not subclasses. Victor's PEP says this is a blocker.
No, he can still do what he wants transparently in the interpreter. What I want to avoid is Python users using __version__ in their own code.
Well, he could change exec so it can use arbitrary mappings (or at least dict subclasses), but I assume that's much harder and more disruptive than his proposed change.
Anyway, if I understand your point, it's this: __version__ should either be a private implementation-specific property of dicts, or it should be a property of all mappings; anything in between gets all the disadvantages of both.
Right. I prefer the the former since making it a property of mappings bloats Mapping beyond a minimum interface.
If so, I agree with you. Encouraging people to use __version__ for other purposes besides namespace guards, but not doing anything to guarantee it actually exists anywhere besides namespaces, seems like a bad idea.
But there is still something in between public and totally internal to FAT Python. Making it a documented property of PyDict objects at the C API level is a different story--there are already plenty of ways that C code can use those objects that won't work with arbitrary mappings, so adding another doesn't seem like a problem.
Adding it to PyDict and exposing it in the C API is totally reasonable to me.
And even making it public but implementation-specific at the Python level may be useful for other CPython-specific optimizers (even if partially written in Python); if so, the best way to deal with the danger that someone could abuse it for code that should work with arbitrary mappings or with another Python implementation should be solved by clearly documenting it's non portability and discouraging its abuse in the docs, not by hiding it.
Here is where I have to disagree. I hate it when experts say "we'll just document it and then it's the user's fault for misusing it". Yeah, you're right, but as a user, it is very frustrating to have to read other people's documentation. You know that some elite Python programmer is going to optimize his code using this and someone years later is going to scratch his head wondering where __version__ is coming from. Is it the provided by the caller? Was it added to the object at some earlier point? Finally, he'll search the web, arrive at a stackoverflow question with 95 upvotes that finally clears things up. And for what? Some minor optimization. (Not Victor's optimization, but a Python user's optimization in Python code.) Python should make it easy to write clear code. It's my opinion that documentation is not a substitute for good language design, just as comments are not a substitute for good code design. Also, using this __version__ in source code is going to complicate switching from CPython to any of the other Python implementations, so those implementations will probably end up implementing it just to simplify "porting", which would otherwise be painless. Why don't we leave exposing __version__ in Python to another PEP? Once it's in the C API (as you proposed) you will be able to use it from Python by writing an extension and then someone can demonstrate the value of exposing it in Python by writing tests.