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/

Reply via email to