Maybe a good start, but we currently document some things that are supposed to be “internal” – though perhaps those should just be promoted to public?
Or the documentation clarified.
This was my point about the amount of effort required to actually review the existing docs and fix it, rather than trying to invent a new mechanism that would also require reviewing everything but wouldn’t necessarily fix the docs.
Possibly relevant to this discussion; PyREPL’s tab completion currently does not respect the __all__ attributes. Should it?
Python is built around freedom. If I want to access or modify shutil._HAS_FCOPYFILE, I should have the full right to do so. Slapping my fingers with ExportError when I try to access a private attribute is plain unacceptable and against the spirit of Python. We’re all consenting adults here and we deeply care about core principles. Also that single leading underscore clearly and immediately communicates that I am doing something wrong and that I should be prepared to bear the consequences.
Consent does not mean I’ll “be prepared to bear the consequences”, it means abiding by what the other party has said they are OK with. The motivation in this thread is to provide a mechanism where library authors are able to prevent violations of their consent. It is intended to improve the “consenting adults” ethos by preventing non-consensual uses.
We clearly need a new term besides “consenting adults”, since culturally that phrase has come to mean something far more specific, and not what it was always meant to mean in the context it was written for Python.
How about “adults who don’t blame other people for problems we can solve ourselves”? (There may be a shorter version, but the risk of misinterpretation suggests we should be more wordy for the sake of making sure everyone understands what we currently, and have always, meant.)
Good point about the pitfalls associated with “consenting adults”. At the risk of bikeshedding, instead of what you suggest, I would prefer something like “programmers who share code freely”.
It should be possible to put this much more simply: “Do whatever you want.”
At the end of the day, there’s always going to be a tension between creating guardrails (safety) and not wanting to be constrained by them (freedom). That’s true of public, final, type annotations, and so on. There isn’t some universal principle that tells you where the line should be drawn.
In this case, some people want the ability to create guardrails that prevent access to private names, while others don’t want to give up the freedom to access them.
I think the Zen of Python suggests that Python has historically leaned toward freedom over safety. Quoting the Zen is useful when it helps express that idea, but I don’t think it was ever meant to function as a universal rule.
Except you immediately run into the “What if everyone did this” problem, which you even went ahead and demonstrated.
This is why Python has historically fallen on the side of the final developer getting to choose what they access, rather than the earlier stage developers deciding what the final developer will get to access. It’s the approach that provides the most freedom for the person carrying the most risk, and it doesn’t hit the “what if everyone” problem because there is nobody else after that final developer.
Ultimately, when you’re deciding the rules, either you are the only one who gets freedom or you can allow everyone to have freedom - you can’t choose to let some people have the freedom and others not.
This is true, and easily demonstrated by almost every second statement in the Zen contradicting the one that came right before it.
But pointing this out doesn’t invalidate the principle. It’s much easier to point to the complete lack of a concept of private members for the entire lifespan of Python so far and say “Python avoids letting type developers control whether their users can access the fields” - nobody has to appeal to the Zen when we have such a long, obvious history of preferring it.
Sure, this is the freedom argument. But the safety argument wants to limit that. That’s what hiding or deleting things from the interface does, or annotating variables as final, etc.
I agree that Python has historically been much more free than it is “safe”. I’m not sure that history is any more compelling than the Zen when it comes to making language decisions.
That’s not what I meant the spirit of the language to be at all! I don’t know where you got that idea.
Any conclusions drawn from that misunderstanding are not sensible arguments against such a proposal.
And the “consenting adults” metaphor (always an expression used in jest) also implies that if I prefix a name with an underscore, you will refrain from using it.
To me, “trust the user” captures this - trust the user to respect your declared intentions (or at a minimum not to complain to you if they don’t).
Enforcement is a way of expressing your intent, but it implies less trust than just stating your intent. As such, it may be necessary sometimes, but IMO it shouldn’t be the default or preferred option.
Agreed with “trust the user”. I think this is why the options I’ve felt “best” about are ones that lean toward clarifying intent and if they came with enforcement, the enforcement is “trivial to opt out of, with knowledge”
My main point is that I don’t trust users claiming their “freedom” should override everything else.
My ideal outcome here is enforcement when the author wants it, with an easy way to opt out for specific cases. (Which is what the hub model already has, but other approaches lack.)
While it isn’t particularly pithy, I’ve long thought of our “hazardous material warning” style approach to this kind of thing as “we’re not going to stop you, but when it inevitably breaks, you get to keep all the shiny pieces”.