Hello,
On Wed, 2 Dec 2020 21:15:22 +1100
Steven D'Aprano
On Wed, Dec 02, 2020 at 10:52:30AM +0300, Paul Sokolovsky wrote:
[Paul]
# Leads to a warning: replacing (monkey-patching) a constant slot (function) with a variable. mod.func1 = 1
[...]
That example explores the meaning of:
def func1(): pass
func1 = 1
Those two code snippets demonstrate different things. Your original example demonstrates assigning to an module attribute from outside of the module. Your new example demonstrates assigning to a global variable from inside the same module. These call different byte-codes in CPython (STORE_ATTR and STORE_NAME).
Nice language-lawyering pick! Behold my counter: Generally, the background idea of this proposal is to treat Python as "a generic programming language", and not to go to deep into (CPython) jargon and implementation details. From that point of view, those two things demonstrate very similar things: in 1st case, "func1" is assigned in another module's namespace, in 2nd case, "func1" is assigned in the current module's namespace. Implementation details you raise are insightful, but aren't needed for audience to understand those snippets. Generally, Steven, I know that you're among the people who could find *real* issues with my proposal. So, I look forward to, if you would so like, us to finish with this language-lawyering preamble, and get to the substance of the proposal.
There is, as far as I know, no way to hook into and prevent STORE_NAME as yet.
And yet I'm doing just that. You just didn't reach yet in your reading the section of https://github.com/pycopy/PycoEPs/blob/master/StrictMode.md#implementation . You'd immediately remember that we've got STORE_NAME covered. STORE_GLOBAL is a culprit however. []
class DemoModule(type(glob)): ... def __setattr__(self, name, value): ... print("You tried to change an module attribute, you naughty person!") ... glob.__class__ = DemoModule
glob.spam = 1 You tried to change an module attribute, you naughty person! glob.spam Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: module 'glob' has no attribute 'spam'
> And from a PoV of a human programmer, it's like written in the > comment > - first, the symbol (name) "func1" is defined as a function, and > then it's redefined as a variable. It sounds like you are describing a programmer who doesn't understand Python's execution model.
No, I'm describing a programmer who understands Python's execution model well enough, and "fed up" with some parts of it, and looking forward to some adjusted execution models to expand their horizons. The whole point of the proposal is to introduce a new execution model, I hope the beginning of the proposal, "This proposal seeks to introduce opt-in "strict execution mode"" rings enough of a bell. I'm sorry if it didn't.
Do you understand that "func1" is already a variable?
Not only I understand that, that's exactly what I seek to mend. Generally, Steven, let me draw a picture. For a moment, imagine that we both know Python execution model. Then: You: Look at it and... like what you see. I: Look at it and... spotting problematic things to adjust.
In the sense that "variables" are name bindings, which is the only sense that applies to Python. Just because it is bound to a function object doesn't make it something different -- "func1" is still a name bound to a value, which is the Python concept of a variable.
Paul, I would have more confidence in your proposal if you described your proposal in terms of Python's existing execution model. Because so far, the language you use to describe your proposal sounds like the language used by somebody who doesn't understand Python's execution model.
That could be a fair point. But let me ask a fair question: what percentage of the full proposal have you read? Because if it's sufficiently less than "entire", than your premonitions could be premature. If anything, I'm glad I've posted the "TL;DR" version, because the real proposal has got exactly 0 responses so far, while so many people were already kind to kick at the direction of the "TL;DR". (And given that I explicitly said I'm going to post this proposal "for beating", kicks are exactly the expected outcome.)
That does not give me confidence in your understanding of the consequences of these changes, or that you are coming to this proposal as somebody who loves Python.
Love can be hard, too.
If you want to program in another language with radically different semantics, there are hundreds of languages that aren't Python.
But that's a part of meta-motivation of the most things I do to Python, sorry for not keeping you in loop! So, as someone who was long time with Python and knows it pretty well, I also know many of its issues. And I was looking for alternatives. And I found out that almost any other reasonable choice would give me more static/strict language nature. E.g., among the common crowd of Ruby/JavaScript/Lua, Python is the strongest-typed alternative (while being dynamically typed). And heck, I have to admit, I like that, so I don't downgrade to them. And the rest of crowd, are rather too static to be practical for human-scale computing (not touching on problems of syntax ugliness, bloat, and concerns of being advertisement product of a media company). So, I decided to make a contrarian move: sit on the things I like in Python, and work on changing things I don't like.
You don't have to turn Python into one of them.
Believe it or not, but the proposal is so cute, that "addresses" even that point. It's at the very end, titled "Trivia". I'll let you scroll to it at your pace. But just in case, it's along the lines of: "Python was kidnapped by the secret Smalltalk cult! Freedom to Python!" ;-) [the rest later] -- Best regards, Paul mailto:pmiscml@gmail.com