Hello, On Wed, 2 Dec 2020 10:42:25 +1100 Steven D'Aprano <st...@pearwood.info> wrote:
> Paul wrote: > > > > Below is an example of strict mode program with comments explaining > > various features: > > > > ``` > > import mod > > > > # Leads to a warning: replacing (monkey-patching) a constant slot > > (function) with a variable. > > mod.func1 = 1 > > (Aside: the literal `1` is not a variable, and variables aren't > first-class citizens in Python. We can't bind "a variable" to a name, > only the variable's value.) Nobody calls literal "1" a variable. That example explores the meaning of: def func1(): pass func1 = 1 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. > Is monkey-patching disallowed because `mod.func1` is defined as a > constant? What "disallowed" do you mean? The example above clearly says "Leads to a warning". At "run-time" (i.e. eventually, after you've done the monkey-patching), it's disallowed, yes. > Or are all functions automatically considered to be > constants? That's the case, right. > > If the later, then decorators won't work in strict mode: > > @decorate > def func(): > ... > > is defined as: > > # define-decorate-replace > def func(): > ... > > func = decorate(func) That's "conceptual model". How it's actually implemented is, "bu abuse of notation" is: def decorate(func): ... Works without hitch with the strict mode. > > so if functions are automatically const, decorators won't work. > > Occasionally I find that decorator syntax is not sufficient, and I've > used the explicit "define-decorate-replace" form. That won't work > either. You'll get a warning, and if you're smarter than the strict mode in that case, you can disable it (in the same sense that you can disable any warning in Python). > Is it only *monkey-patching* from outside of the module that is > disallowed, or any rebindings to functions, including within the > owning module itself? In the *run-time* (aka "eventually") any "assign" operation on a const name is disallowed, and additionally adding any new names is disallowed, ditto for deletions. At the *import-time*, everything is allowed. > > If the later, that's also going to break the common idiom: > > def func(): > # Slow Python version. > > # maybe replace with fast C version > from c_accelerators import * > > under strict mode. Will lead to a warning. Got bitten by that myself, yeah. (I llllove "from foo import *"). Had to finally implement __all__ in Pycopy due to those strict mode problems, can you believe? Anyway, re: example above would either need to mend your your ways (e.g. run "import *" first then conditionally define missing funcs), or disable the warning. [Have to stop here, will look at the rest later, thanks for comments.] [] -- Best regards, Paul mailto:pmis...@gmail.com _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/GBXENRGLJIR3UNL7UEZJSLAMW7R5NN6U/ Code of Conduct: http://python.org/psf/codeofconduct/