Mailing List Archive

Making staticmethod callable, any oposite?
Hi, all.

I am implementing PEP 597. During review, Victor suggested to
deprecate `OpenWrapper`. `OpenWrapper` is defined only for
compatibility between C function and Python function:

```
from _pyio import open as py_open
from _io import open as c_open

class C:
py_open = py_open
c_open = c_open

C().c_open("README.rst") # works
C().py_open("README.rst") # TypeError: expected str, bytes or
os.PathLike object, not C
```

So builtin open is not io.open, but io.OpenWrapper in Python 3.9.
Making staticfunction callable fixes this issue.

```
@staticfunction
def open(...): ...
```

Now open defined in Python behaves like C function. We don't need
OpenWrapper anymore.
This has already been committed by Guido's approval. staticmethod is
callable, and OpenWrapper is just an alias of open and deprecated in
master branch.

But Mark Shannon said we shouldn't make such a change without
discussing at python-dev.
I don't know we *should*, but I agree that it is *ideal*.

Then, does anyone oppose this change?

Histrically, this idea had been rejected once. bpo-20309 proposed
making classmethod and staticmethod callable.
https://bugs.python.org/issue20309

It had been rejected by:

"I don't agree that this is a bug that should be fixed. It adds code
that will likely never get called or needed (i.e. there has never been
a request for this in the decade long history of desciptors and it
seems like a made up requirement to me. "
https://bugs.python.org/issue20309#msg240843

"actually supporting this would mean adding code that would need to be
maintained indefinitely without providing a compensating practical
benefit,"
https://bugs.python.org/issue20309#msg240898

But status is changed now. We already have OpenWrapper. It proves
callable classmethod is "called and needed".
Although there is only one use case, we can remove more code than adding.

staticmethod.__call__() is simple C function.
https://github.com/python/cpython/pull/25117/files#diff-57bc77178b3d6f1010dd924722c87522f224d93bc341f0e46c0945094124d8f2

Victor removed OpenWrapper class already, and we can remove `DocDescripter` too.
https://github.com/python/cpython/pull/25354/files#diff-bcdfa9cbb0764d7959cda48f9084d79785f87c5ad7460f27ba2678b0bda76e38R314-L327

I think maintenance burden of staticmethod.__call__() is not higher
than OpenWrapper and DocDescripter.
Additionally, if we have same issue in other module, we can just use
staticmethod, instead of copy&paste OpenWrapper and DocDescripter.

So it provides "compensating practical benefit".


Regards,

--
Inada Naoki <songofacandy@gmail.com>
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/MGQMXSMQIPI5ZKS2T5YHNM47PPWSSRD5/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: Making staticmethod callable, any oposite? [ In reply to ]
On 4/13/2021 9:20 PM, Inada Naoki wrote:

> But Mark Shannon said we shouldn't make such a change without
> discussing at python-dev.
> I don't know we *should*, but I agree that it is *ideal*.

I consider this case borderline. A lot of changes get made, and must
be, without pydev discussion.
>
> Then, does anyone oppose this change?
>
> Histrically, this idea had been rejected once. bpo-20309 proposed
> making classmethod and staticmethod callable.
> https://bugs.python.org/issue20309
>
> It had been rejected by:
>
> "I don't agree that this is a bug that should be fixed. It adds code
> that will likely never get called or needed (i.e. there has never been
> a request for this in the decade long history of desciptors and it
> seems like a made up requirement to me. "
> https://bugs.python.org/issue20309#msg240843

Written by Raymond Hettinger, who continued "If someone object to
recommendation to close and really wants to push for this, I recommend
making a business case for acceptance and then assigning this issue to
Guido for a decision. This is his code and AFAICT he intentionally
didn't go down a number of possible paths for descriptors simply because
there weren't motivating use cases."

You made the case on the issue, and have here, and Guido decided.

> "actually supporting this would mean adding code that would need to be
> maintained indefinitely without providing a compensating practical
> benefit,"
> https://bugs.python.org/issue20309#msg240898

Nick Coughlin, following Raymond, who continued
"Thanks Christian for nudging us to make a decision one way or the other."
and
"If another implementation requests clarification, we might want to
document that "directly callable-or-not" for these descriptors is
formally an interpreter implementation detail"

So both describe rejection as a close call that could go have gone and
might in the future go the other way.

> But status is changed now. We already have OpenWrapper. It proves
> callable classmethod is "called and needed".
> Although there is only one use case, we can remove more code than adding.
>
> staticmethod.__call__() is simple C function.
> https://github.com/python/cpython/pull/25117/files#diff-57bc77178b3d6f1010dd924722c87522f224d93bc341f0e46c0945094124d8f2
>
> Victor removed OpenWrapper class already, and we can remove `DocDescripter` too.
> https://github.com/python/cpython/pull/25354/files#diff-bcdfa9cbb0764d7959cda48f9084d79785f87c5ad7460f27ba2678b0bda76e38R314-L327
>
> I think maintenance burden of staticmethod.__call__() is not higher
> than OpenWrapper and DocDescripter.
> Additionally, if we have same issue in other module, we can just use
> staticmethod, instead of copy&paste OpenWrapper and DocDescripter.
>
> So it provides "compensating practical benefit".


--
Terry Jan Reedy

_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/UAN25M6F45XWNSDRUR4WGT2U5REQMUU4/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: Making staticmethod callable, any oposite? [ In reply to ]
On 4/13/21 6:20 PM, Inada Naoki wrote:

> Then, does anyone oppose this change?

Having staticmethod, etc., be callable would make my code much easier in at least two different projects.

Please make this change.

--
~Ethan~
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/U6PSB4NEI4UI3PSOE63CQHBFIP5X555L/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: Making staticmethod callable, any oposite? [ In reply to ]
On 14/04/2021 2:20 am, Inada Naoki wrote:
> Hi, all.
>
> I am implementing PEP 597. During review, Victor suggested to
> deprecate `OpenWrapper`. `OpenWrapper` is defined only for
> compatibility between C function and Python function:
>
> ```
> from _pyio import open as py_open
> from _io import open as c_open
>
> class C:
> py_open = py_open
> c_open = c_open
>
> C().c_open("README.rst") # works
> C().py_open("README.rst") # TypeError: expected str, bytes or
> os.PathLike object, not C
> ```
>
> So builtin open is not io.open, but io.OpenWrapper in Python 3.9.
> Making staticfunction callable fixes this issue.
>
> ```
> @staticfunction
> def open(...): ...
> ```
>
> Now open defined in Python behaves like C function. We don't need
> OpenWrapper anymore.
> This has already been committed by Guido's approval. staticmethod is
> callable, and OpenWrapper is just an alias of open and deprecated in
> master branch.
>
> But Mark Shannon said we shouldn't make such a change without
> discussing at python-dev.
> I don't know we *should*, but I agree that it is *ideal*.
>
> Then, does anyone oppose this change?

I do (although not strongly).

I think we are changing the wrong thing.

Sometimes code gets moved from C to Python and vice-versa.
The differences in descriptor behavior between builtin function and
Python functions trips people up. We agree on that.

However I don't think changing the behavior of static methods is the way
to fix that.

A staticmethod is not a function, builtin or otherwise. It is a method
that, when called, ignores the object it is attached to.

If we want Python functions to behave like a builtin function, then
marking them `@staticmethod` is misleading, IMO.

I'm also worried about corner cases where this change in behavior will
break code.

I'm all in favor of replacing C code with Python and don't want to make
it difficult.
So, why not add a new descriptor, that clearly describes the intent:

`@non_method` or just `@function`?

The decorator would make a new object that behaves like a
builtin-function, even though it is implemented in Python.

Cheers,
Mark.

_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/WRHFP4FKWCCJWOU2JTRVFXB6LSFRATKG/
Code of Conduct: http://python.org/psf/codeofconduct/