[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Mark Shannon

Hi Brandt,

On 30/03/2021 11:49 pm, Brandt Bucher wrote:

Hi Mark.

I've spoken with Guido, and we are willing to propose the following amendments 
to PEP 634:

- Require `__match_args__` to be a tuple.


I think we're all in agreement on this one.
Let's just do it.


- Add new `__match_seq__` and `__match_map__` special attributes, corresponding 
to new public `Py_TPFLAGS_MATCH_SEQ` and `Py_TPFLAGS_MATCH_MAP` flags for use 
in `tp_flags`. When Python classes are defined with one or both of these 
attributes set to a boolean value, `type.__new__` will update the flags on the 
type to reflect the change (using a similar mechanism as `__slots__` 
definitions). They will be inherited otherwise. For convenience, 
`collections.abc.Sequence` will define `__match_seq__ = True`, and 
`collections.abc.Mapping` will define `__match_map__ = True`.

Using this in Python would look like:

```
class MySeq:
 __match_seq__ = True
 ...

class MyMap:
 __match_map__ = True
 ...
```


I don't like the way this need special inheritance rules, where 
inheriting one attribute mutates the value of another.

It seems convoluted.

Consider:

class WhatIsIt(MySeq, MyMap):
pass

With __match_container__ it works as expected with no special 
inheritance rules.


This was why you convinced me to split __match_kind__; it works better 
with inheritance.


Anther reason for preferring __match_container__ is that it provides a 
better option for extensibility, IMO.
Suppose we wanted to add a "set" pattern in the future, with 
__match_container__ we just need to add a new constant.

With your proposed approach, we would need another special attribute.



Using this in C would look like:

```
PyTypeObject PyMySeq_Type = {
 ...
 .tp_flags = Py_TPFLAGS_MATCH_SEQ | ...,
 ...
}

PyTypeObject PyMyMap_Type = {
 ...
 .tp_flags = Py_TPFLAGS_MATCH_MAP | ...,
 ...
}
```


I'm wary of using up tp_flags, as they are a precious resource, but this 
does provide a more declarative way to specific the behavior than 
setting the attribute via the C-API.




We believe that these changes will result in the best possible outcome:
- The new mechanism should faster than either PEP.


The naive implementation of the boolean version might be a tiny bit 
faster (it would hard to measure a difference).
However, once specialized by type version (as we do for LOAD_ATTR) both 
forms become a no-op.



- The new mechanism should provide a better user experience than either PEP 
when defining types in either Python *or C*.


The inheritance rules make __match_container__ a better user experience 
in Python, IMO.
As for C, there no reason why the it would make any difference, 
__match_container__ could be

(tp_flags & (Py_TPFLAGS_MATCH_SEQ|Py_TPFLAGS_MATCH_MAP))
shifted to line up the bits.



If these amendments were made, would you be comfortable withdrawing PEP 653? We 
think that if we're in agreement here, a compromise incorporating these 
promising changes into the current design would be preferable to submitting yet 
another large pattern matching PEP for a very busy SC to review and pronounce 
before the feature freeze. I am also willing, able, and eager to implement 
these changes promptly (perhaps even before the next alpha) if so.


I think we are close to agreement on the mechanism for selecting which 
pattern to match, but I still want the better defined semantics of PEP 653.




Thanks for pushing us to make this better.


And thank you for the feedback.

Cheers,
Mark.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/VXSUTM6CNEMOBZUJZXVP42OYYZWCBE2C/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Weird io.OpenWrapper hack to use a function as method

2021-03-31 Thread Victor Stinner
Hi,

The io module provides an open() function. It also provides an
OpenWrapper which only exists to be able to store open as a method
(class or instance method). In the _pyio module, pure Python
implementation of the io module, OpenWrapper is implemented as:

class OpenWrapper:
"""Wrapper for builtins.open

Trick so that open won't become a bound method when stored
as a class variable (as dbm.dumb does).

See initstdio() in Python/pylifecycle.c.
"""
def __new__(cls, *args, **kwargs):
return open(*args, **kwargs)

I would like to remove this class which is causing troubles in the PEP
597 implementation, but I don't know how. Simplified problem:
---
def func():
print("my func")

class MyClass:
method = func

func() # A
MyClass.method() # B
obj = MyClass()
obj.method() # C
---

With this syntax, A and B work, but C fails with TypeError: func()
takes 0 positional arguments but 1 was given.

If I decorate func() with @staticmethod, B and C work, but A fails
with TypeError: 'staticmethod' object is not callable.

Is OpenWrapper the only way to have a callable object which works in
the 3 variants A, B and C?

A, B and C work if MyClass is modified to use staticmethod:

class MyClass:
method = staticmethod(func)

Victor
-- 
Night gathers, and now my watch begins. It shall not end until my death.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/QZ7SFW3IW3S2C5RMRJZOOUFSHHUINNME/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Weird io.OpenWrapper hack to use a function as method

2021-03-31 Thread Victor Stinner
tl; dr *Maybe* staticmethod could be modified to become callable?


io.open is a built-in function (type "builtin_function_or_method"). It
behaves differently than _pyio.open which is a Python function (type
"function").

The difference is in the LOAD_METHOD bytecode which uses __get__()
descriptor if available. Built-in function has no __get__() method and
so the function is used directly as a method. Python function has a
__get__() descriptor which returns the function unchanged when a class
method is requested, and create a bound method if an instance method
is requested:
---
def func():
...

FunctionType = type(func)

class MyClass:
method = func

class_method = MyClass.method
assert class_method is func
assert class_method is FunctionType.__get__(func, None, MyClass)

obj = MyClass()
instance_method = obj.method
assert instance_method.__self__ is obj
assert instance_method.__func__ is func
# each __get__() call creates a new bound method
assert instance_method == FunctionType.__get__(func, obj, type(obj))
---

@staticmethod decorator avoids the creation of the bound method:
---
def func(): ...

class MyClass:
method = staticmethod(func)

# method = MyClass.method
attr = MyClass.__dict__['method']
method = type(attr).__get__(attr, None, MyClass)
assert method is func
---

The drawback is that the object created by staticmethod cannot be
called :-( The following code raises a TypeError:
---
wrapped = staticmethod(func)
wrapped()
---

*Maybe* staticmethod could be modified to become callable?

Victor


On Wed, Mar 31, 2021 at 2:34 PM Victor Stinner  wrote:
>
> Hi,
>
> The io module provides an open() function. It also provides an
> OpenWrapper which only exists to be able to store open as a method
> (class or instance method). In the _pyio module, pure Python
> implementation of the io module, OpenWrapper is implemented as:
>
> class OpenWrapper:
> """Wrapper for builtins.open
>
> Trick so that open won't become a bound method when stored
> as a class variable (as dbm.dumb does).
>
> See initstdio() in Python/pylifecycle.c.
> """
> def __new__(cls, *args, **kwargs):
> return open(*args, **kwargs)
>
> I would like to remove this class which is causing troubles in the PEP
> 597 implementation, but I don't know how. Simplified problem:
> ---
> def func():
> print("my func")
>
> class MyClass:
> method = func
>
> func() # A
> MyClass.method() # B
> obj = MyClass()
> obj.method() # C
> ---
>
> With this syntax, A and B work, but C fails with TypeError: func()
> takes 0 positional arguments but 1 was given.
>
> If I decorate func() with @staticmethod, B and C work, but A fails
> with TypeError: 'staticmethod' object is not callable.
>
> Is OpenWrapper the only way to have a callable object which works in
> the 3 variants A, B and C?
>
> A, B and C work if MyClass is modified to use staticmethod:
>
> class MyClass:
> method = staticmethod(func)
>
> Victor
> --
> Night gathers, and now my watch begins. It shall not end until my death.



-- 
Night gathers, and now my watch begins. It shall not end until my death.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/KAZ5HR2ZLPBZ76FZZOZI5RU35FYDBDI7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Weird io.OpenWrapper hack to use a function as method

2021-03-31 Thread Victor Stinner
A friend, Antoine Rozo, wrote a variant of staticmethod which is
callable. With this decorator, it works in A, B and C cases:
---
class simplefunction:
def __init__(self, func):
self.func = func
def __get__(self, owner, instance):
return self.func
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)

@simplefunction
def func():
print("my func")

class MyClass:
method = func

func() # A
MyClass.method() # B
MyClass().method() # C
---

It works without the __get__() method, but in this case, we go through
the __call__() indirection for A, B and C cases, rather than only
going through __call__() indirection in A case.

Victor
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/OQUM4RZBIGHF6UJYQDFAMTHOZOU5DLKS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP-376 and PEP-427 interpretation

2021-03-31 Thread Daniel Holth
I meant to exclude md5 and sha1, e.g. hash functions with known problems.
SHA224 would be a weird choice but it wouldn't personally offend me
otherwise. It would be fun to see how many wheel handlers support
non-sha256 hash functions.

On Mon, Mar 29, 2021 at 9:56 PM Theallredman via Python-Dev <
python-dev@python.org> wrote:

> Thank you.  I can't think of a compelling reason someone would want to
> choose SHA224 over SHA256 in the context of wheel generation.  It just that
> the PEPs are usually pretty explicit and SHA224 seemed to be implicitly
> excluded from RECORD files.  And I'm considering the details of making a
> pretty pedantic wheel generation PEP517 backend.
>
> Eldon
>
> ‐‐‐ Original Message ‐‐‐
> On Monday, March 29, 2021 2:16 PM, Paul Moore  wrote:
>
> > On Mon, 29 Mar 2021 at 17:40, Theallredman via Python-Dev
> > python-dev@python.org wrote:
> >
> > > So going back to my actual question SHA224 is disallowed in record
> files because it's bit length is less then 256?
> >
> > It doesn't look like it's ever been excluded. The only explicit
> > exclusions are MD5 and SHA1 as you point out. Do you have a particular
> > reason to want to use SHA224? Pretty much everyone is using SHA256, as
> > far as I know.
> >
> > Paul
>
>
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@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/NB6MLDDDJHRTRMOEWDFG5IYGZCP65K6V/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/P4575PDTQCUYMYZVOSJPYGD3J5YKNCFY/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Weird io.OpenWrapper hack to use a function as method

2021-03-31 Thread Ethan Furman

On 3/31/21 6:49 AM, Victor Stinner wrote:


tl; dr *Maybe* staticmethod could be modified to become callable?


There have been other requests to make staticmethod callable, one of them being

  https://bugs.python.org/issue20309

+1 for having it done.

--
~Ethan~
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/KITFURNWOLEMETD2CLM6LKXCFUNZUNUP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Weird io.OpenWrapper hack to use a function as method

2021-03-31 Thread Victor Stinner
I created https://bugs.python.org/issue43682 "Make static methods
created by @staticmethod callable".

Oh, I didn't know this old bpo-20309 issue closed as "not a bug". But
it proposed to modify many other wrappers like @classmethod. I only
propose to make static methods created @staticmethod callable.

Victor

On Wed, Mar 31, 2021 at 4:19 PM Ethan Furman  wrote:
>
> On 3/31/21 6:49 AM, Victor Stinner wrote:
>
> > tl; dr *Maybe* staticmethod could be modified to become callable?
>
> There have been other requests to make staticmethod callable, one of them 
> being
>
>https://bugs.python.org/issue20309
>
> +1 for having it done.
>
> --
> ~Ethan~
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@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/KITFURNWOLEMETD2CLM6LKXCFUNZUNUP/
> Code of Conduct: http://python.org/psf/codeofconduct/



-- 
Night gathers, and now my watch begins. It shall not end until my death.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/D6CI33WWUMQTA4VKVKIPZGGJ4XCQTTI2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Weird io.OpenWrapper hack to use a function as method

2021-03-31 Thread Guido van Rossum
Honestly it has always bugged me that staticmethod only becomes callable
through __get__. So I think this would be fine. But I don't know if there
might be unintended consequences.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/43LSVSJU6QURCOWEEA2JKH3WWTJBWKCE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Weird io.OpenWrapper hack to use a function as method

2021-03-31 Thread Barry Scott


> On 31 Mar 2021, at 13:34, Victor Stinner  wrote:
> 
> def func():
>print("my func")


This would work for the example given of a func with no args.
But cannot check it called with the right number.

def func(*args):
   print("my func")

A signature like this would be a hard nut to crack.

def func(fixed, *args):
print("my func", fixed, args)

Barry

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/RKAIEYL36YR2JQLPIHLQYJENIWZPAVWE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: SC feedback: PEP 648 -- Extensible customizations of the interpreter at startup

2021-03-31 Thread Mario Corchero
Thanks all. I'll address this feedback next week.

Regards,
Mario

On Wed, 31 Mar 2021 at 03:01, Barry Warsaw  wrote:

> Kind of :)
>
> PEP 648 would definitely allow us to deprecate the executable part of pth
> files.  I let my own biases leak in to my response because I would like to
> find a way to replace the sys.path feature of pth with something much more
> auditable and discoverable.  To me that means deprecating pth files and
> finding something better, but maybe not.
>
> In any case, this is outside the scope of PEP 648 so just pretend that
> part wasn’t in my response.
>
> -Barry
>
> > On Mar 30, 2021, at 17:00, Pablo Galindo Salgado 
> wrote:
> >
> > Hi Nick,
> >
> > Please don't, since that would force everyone to start using PEP 648
> just to extend sys.path, which would be just as bad as the status quo.
> >
> > I think Barry is referring to deprecate the execution capabilities of
> pth files (https://bugs.python.org/issue33944), not the files themselves.
> >
> > Cheers,
> > Pablo Galindo Salgado
> >
> > On Wed, 31 Mar 2021 at 00:34, Nick Coghlan  wrote:
> >
> >
> > On Wed, 31 Mar 2021, 3:15 am Barry Warsaw,  wrote:
> > .  We would like to eventually go farther, including deprecation of pth
> files entirely, but that is outside the scope of this PEP.
> >
> > Please don't, since that would force everyone to start using PEP 648
> just to extend sys.path, which would be just as bad as the status quo.
> >
> > Cheers,
> > Nick.
> >
> >
> >
> > ___
> > Python-Dev mailing list -- python-dev@python.org
> > To unsubscribe send an email to python-dev-le...@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/MSOV7NKDCO7L3X46SDDLVTUEN7ER2EDB/
> > Code of Conduct: http://python.org/psf/codeofconduct/
>
>
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/S2RTLPBF5FYVTOBT6MKAXR5PDTBCS5PH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Adrian Freund
Hi Mark,

I also wanted to give some feedback on this. While most of the
discussion so far has been about the matching of the pattern itself I
think it should also be considered what happens in the block below.

Consider this code:

```
m = ...

match m:
    case [a, b, c] as l:
        # what can we safely do with l?

```

or in terms of the type system: What is the most specific type that we
can know l to be?

With PEP 634 you can be sure that l is a sequence and that it's length
is 3. With PEP 653 this is currently not explicitly defined. Judging
from the pseudo code we can only assume that l is an iterable (because
we use it in an unpacking assignment) and that it's length is 3, which
greatly reduces the operations that can be safely done on l.

For mapping matches with PEP 634 we can assume that l is a mapping. With
PEP 653 all we can assume is that it has a .get method that takes two
parameters, which is even more restrictive, as we can't even be sure if
we can use len(), .keys, ... or iterate over it.

This also makes it a lot harder for static type checkers to check match
statements, because instead of checking against an existing type they
now have to hard-code all the guarantees made my the match statement or
not narrow the type at all.

Additionally consider this typed example:

```
m: Mapping[str, int] = ...

match m:
    case {'version': v}:
    pass
```

With PEP 634 we can statically check that v is an int. With PEP 653
there is no such guarantee.


Therefore I would strongly be in favor of having sequence and mapping
patterns only match certain types instead of relying on dunder
attributes. If implementing all of sequence is really to much work just
to be matched by a sequence pattern, as PEP 653 claims, then maybe a
more general type could be chosen instead.

I don't have any objections against the other parts of the PEP.


Adrian Freund

On 3/27/21 2:37 PM, Mark Shannon wrote:
> Hi everyone,
>
> As the 3.10 beta is not so far away, I've cut down PEP 653 down to the
> minimum needed for 3.10. The extensions will have to wait for 3.11.
>
> The essence of the PEP is now that:
>
> 1. The semantics of pattern matching, although basically unchanged,
> are more precisely defined.
>
> 2. The __match_kind__ special attribute will be used to determine
> which patterns to match, rather than relying on the collections.abc
> module.
>
> Everything else has been removed or deferred.
>
> The PEP now has only the slightest changes to semantics, which should be
> undetectable in normal use. For those corner cases where there is a
> difference, it is to make pattern matching more robust.
> E.g. With PEP 653, pattern matching will work in the collections.abc
> module. With PEP 634 it does not.
>
>
> As always, all thoughts and comments are welcome.
>
> Cheers,
> Mark.
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@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/YYIT3QXMLPNLXQAQ5BCXE4LLJ57EE7JV/
> Code of Conduct: http://python.org/psf/codeofconduct/
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/OAVTGQCFXNX47JH52ZMOAHVISDZ2JNMO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Guido van Rossum
On Wed, Mar 31, 2021 at 2:30 AM Mark Shannon  wrote:

> > - Add new `__match_seq__` and `__match_map__` special attributes,
> corresponding to new public `Py_TPFLAGS_MATCH_SEQ` and
> `Py_TPFLAGS_MATCH_MAP` flags for use in `tp_flags`. When Python classes are
> defined with one or both of these attributes set to a boolean value,
> `type.__new__` will update the flags on the type to reflect the change
> (using a similar mechanism as `__slots__` definitions). They will be
> inherited otherwise. For convenience, `collections.abc.Sequence` will
> define `__match_seq__ = True`, and `collections.abc.Mapping` will define
> `__match_map__ = True`.
> >
> > Using this in Python would look like:
> >
> > ```
> > class MySeq:
> >  __match_seq__ = True
> >  ...
> >
> > class MyMap:
> >  __match_map__ = True
> >  ...
> > ```
>
> I don't like the way this need special inheritance rules, where
> inheriting one attribute mutates the value of another.
> It seems convoluted.
>
> Consider:
>
> class WhatIsIt(MySeq, MyMap):
>  pass
>
> With __match_container__ it works as expected with no special
> inheritance rules.
>

Wait a minute, do you expect WhatIsIt to be a sequence but not a map? *I*
would expect that it is both, and that's exactly what Brandt's proposal
does. So I see this as a plus.


> I think we are close to agreement on the mechanism for selecting which
> pattern to match, but I still want the better defined semantics of PEP 653.
>

I don't know that PEP 653's semantics are better. Have you analyzed any
*differences* besides the proposal above? I've personally found reading
your pseudo-code very difficult, so I simply don't know.

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/HZRGTO3UXRGXWXWXSX2H3WX6Y3Z37XOS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Mark Shannon

Hi Guido,

On 31/03/2021 6:21 pm, Guido van Rossum wrote:
On Wed, Mar 31, 2021 at 2:30 AM Mark Shannon > wrote:


 > - Add new `__match_seq__` and `__match_map__` special attributes,
corresponding to new public `Py_TPFLAGS_MATCH_SEQ` and
`Py_TPFLAGS_MATCH_MAP` flags for use in `tp_flags`. When Python
classes are defined with one or both of these attributes set to a
boolean value, `type.__new__` will update the flags on the type to
reflect the change (using a similar mechanism as `__slots__`
definitions). They will be inherited otherwise. For convenience,
`collections.abc.Sequence` will define `__match_seq__ = True`, and
`collections.abc.Mapping` will define `__match_map__ = True`.
 >
 > Using this in Python would look like:
 >
 > ```
 > class MySeq:
 >      __match_seq__ = True
 >      ...
 >
 > class MyMap:
 >      __match_map__ = True
 >      ...
 > ```

I don't like the way this need special inheritance rules, where
inheriting one attribute mutates the value of another.
It seems convoluted.

Consider:

class WhatIsIt(MySeq, MyMap):
      pass

With __match_container__ it works as expected with no special
inheritance rules.


Wait a minute, do you expect WhatIsIt to be a sequence but not a map? 
*I* would expect that it is both, and that's exactly what Brandt's 
proposal does. So I see this as a plus.



Earlier you said:

Classes that are both mappings and sequences are ill-conceived.
Let's not compromise semantics or optimizability to support these.
   (IOW I agree with Mark here.)

PEP 653 requires that:
(__match_container__ & (MATCH_SEQUENCE | MATCH_MAPPING)) != 
(MATCH_SEQUENCE | MATCH_MAPPING)


Would you require that (__match_seq__ and __match_map__) is always false?
If so, then what is the mechanism for handling the `WhatIsIt` class?
If not, then you loose the ability to make a single test to determine
which patterns can apply.



I think we are close to agreement on the mechanism for selecting which
pattern to match, but I still want the better defined semantics of
PEP 653.


I don't know that PEP 653's semantics are better. Have you analyzed any 
*differences* besides the proposal above? I've personally found reading 
your pseudo-code very difficult, so I simply don't know.


PEP 653 semantics are more precise. I think that is better :)

Apart from that, I think the semantics are so similar once you've added 
__match_seq__/__match_map__  to PEP 634 that is hard to

claim one is better than the other.
My (unfinished) implementation of PEP 653 makes almost no changes to the 
test suite.


The code in the examples is Python, not pseudo-code.
That might be easier to follow.

Cheers,
Mark.


--
--Guido van Rossum (python.org/~guido )
/Pronouns: he/him //(why is my pronoun here?)/ 


___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/TC46W5FKYMKDSWRT77ESVJCSWRHSLCNF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Guido van Rossum
On Wed, Mar 31, 2021 at 12:08 PM Mark Shannon  wrote:

> Hi Guido,
>
> On 31/03/2021 6:21 pm, Guido van Rossum wrote:
> > On Wed, Mar 31, 2021 at 2:30 AM Mark Shannon  > > wrote:
>


> [Brandt Bucher, earlier]
> >  > - Add new `__match_seq__` and `__match_map__` special attributes,
> > corresponding to new public `Py_TPFLAGS_MATCH_SEQ` and
> > `Py_TPFLAGS_MATCH_MAP` flags for use in `tp_flags`. When Python
> > classes are defined with one or both of these attributes set to a
> > boolean value, `type.__new__` will update the flags on the type to
> > reflect the change (using a similar mechanism as `__slots__`
> > definitions). They will be inherited otherwise. For convenience,
> > `collections.abc.Sequence` will define `__match_seq__ = True`, and
> > `collections.abc.Mapping` will define `__match_map__ = True`.
> >  >
> >  > Using this in Python would look like:
> >  >
> >  > ```
> >  > class MySeq:
> >  >  __match_seq__ = True
> >  >  ...
> >  >
> >  > class MyMap:
> >  >  __match_map__ = True
> >  >  ...
> >  > ```
>


> [Mark, in response]
> > I don't like the way this need special inheritance rules, where
> > inheriting one attribute mutates the value of another.
> > It seems convoluted.
> >
> > Consider:
> >
> > class WhatIsIt(MySeq, MyMap):
> >   pass
> >
> > With __match_container__ it works as expected with no special
> > inheritance rules.
>

[me, responding to Mark]

> > Wait a minute, do you expect WhatIsIt to be a sequence but not a map?
> > *I* would expect that it is both, and that's exactly what Brandt's
> > proposal does. So I see this as a plus.
>

[Now back to Mark]

> Earlier you said:
>
>  Classes that are both mappings and sequences are ill-conceived.
>  Let's not compromise semantics or optimizability to support these.
> (IOW I agree with Mark here.)
>

Ah, you caught me there. I do think that classes that combine both
characteristics are in troublesome water. I think we can get optimizability
either way, so I'll focus on semantics.

Brandt has demonstrated that it's ugly to write the code for a class that
in match statements behaves as either a sequence or a mapping (but not
both) while at the same time keeping the code compatible with Python 3.9 or
before. I also think that using flag attributes that are set to True or
False (instead of using a bitmap of flags, which is obscure to many Python
users) solves this problem nicely.

Using separate flag attributes happens to lead to different semantics than
the flags-bitmap approach in the case of multiple inheritance. Given that
one *can* inherit from both Sequence and Mapping, having separate flags
seems slightly better than the flags-bitmap approach. It wasn't enough to
convince me earlier, but the other advantage does convince me: separate
flag attributes are better than using a flags-bitmap.

Now, if it weren't for other issues, having no flags at all here but just
signalling the applicable pattern kinds through inheritance from
collections.abc.{Sequence,Mapping} would be even cleaner. But we do have
other issues: (a) the exceptions for str, bytes, bytearray, and (b) the
clumsiness of importing collections.abc (which is Python code) deep in the
ceval main loop. So some explicit form of signalling this is fine -- and
for classes that explicitly inherit from Sequence or Mapping will get it
for free that way.

>
> PEP 653 requires that:
> (__match_container__ & (MATCH_SEQUENCE | MATCH_MAPPING)) !=
> (MATCH_SEQUENCE | MATCH_MAPPING)
>
> Would you require that (__match_seq__ and __match_map__) is always false?
>

Nope.

If so, then what is the mechanism for handling the `WhatIsIt` class?
> If not, then you loose the ability to make a single test to determine
> which patterns can apply.
>

Translating the flag attributes to bits in tp_flags (or in a new flags
variable elsewhere in the type object) would still allow a pretty fast
test. And needing to support overlapping subsets of the cases is not unique
to this situation, after all a class may well be a sequence *and* have
attributes named x, y and z.


> > I think we are close to agreement on the mechanism for selecting
> which
> > pattern to match, but I still want the better defined semantics of
> > PEP 653.
> >
> >
> > I don't know that PEP 653's semantics are better. Have you analyzed any
> > *differences* besides the proposal above? I've personally found reading
> > your pseudo-code very difficult, so I simply don't know.
>
> PEP 653 semantics are more precise. I think that is better :)
>

I wish I knew of a single instance where PEP 634 and PEP 653 actually
differ.


> Apart from that, I think the semantics are so similar once you've added
> __match_seq__/__match_map__  to PEP 634 that is hard to
> claim one is better than the other.
> My (unfinished) implementation of PEP 653 makes almost no changes to 

[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Brandt Bucher
>> - Add new `__match_seq__` and `__match_map__` special attributes, 
>> corresponding to new public `Py_TPFLAGS_MATCH_SEQ` and 
>> `Py_TPFLAGS_MATCH_MAP` flags for use in `tp_flags`. When Python classes are 
>> defined with one or both of these attributes set to a boolean value, 
>> `type.__new__` will update the flags on the type to reflect the change 
>> (using a similar mechanism as `__slots__` definitions). They will be 
>> inherited otherwise. For convenience, `collections.abc.Sequence` will define 
>> `__match_seq__ = True`, and `collections.abc.Mapping` will define 
>> `__match_map__ = True`.
>> 
>> Using this in Python would look like:
>> 
>> ```
>> class MySeq:
>>  __match_seq__ = True
>>  ...
>> 
>> class MyMap:
>>  __match_map__ = True
>>  ...
>> ```
> 
> I don't like the way this need special inheritance rules, where inheriting 
> one attribute mutates the value of another. It seems convoluted.

Let me clarify: these two attributes do not interact with one another; each 
attribute only interacts with its own flag on the type. It is perfectly 
possible to do:

```
class WhatIsIt:
__match_map__ = True
__match_seq__ = True
```

This will set both flags, and this `WhatIsIt` will match as a mapping *and* a 
sequence. This is allowed and works in PEP 634, but like Guido I'm not entirely 
opposed to making the matching behavior of such a class undefined against 
sequence or mapping patterns. 

> Consider:
> 
> class WhatIsIt(MySeq, MyMap):
 pass
> 
> With __match_container__ it works as expected with no special inheritance 
> rules.

What *is* the expected behavior of this? Based on the current behavior of PEP 
634, I would expect the `__match_container__` of each base to be or'ed, and 
something like this to match as both a mapping and a sequence (which PEP 653 
says leads to undefined behavior). The actual behavior seems more like it will 
just be a sequence and not a mapping, since `__match_container__` would be 
inherited from `MySeq` and `MyMap` would be ignored.

In the interest of precision, here is an implementation of *exactly* what I am 
thinking:

`typeobject.c`: 
https://github.com/python/cpython/compare/master...brandtbucher:patma-flags#diff-1decebeef15f4e0b0ce106c665751ec55068d4d1d1825847925ad4f528b5b872

`ceval.c`: 
https://github.com/python/cpython/compare/master...brandtbucher:patma-flags#diff-c22186367cbe20233e843261998dc027ae5f1f8c0d2e778abfa454ae74cc59de

(One change from my last email: it doesn't allow `__match_map__` / 
`__match_seq__` to be set to `False`... only `True`. This prevents some 
otherwise tricky multiple-inheritance edge-cases present in both of our 
flagging systems that I discovered during testing. I don't think there are 
actual use-cases for unsetting the flags in subclasses, but we can revisit that 
later if needed.)
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/S4KLVTEA4HYDCAER25DZMOUB6LN6K63P/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Guido van Rossum
On Wed, Mar 31, 2021 at 2:14 PM Brandt Bucher 
wrote:

> (One change from my last email: it doesn't allow `__match_map__` /
> `__match_seq__` to be set to `False`... only `True`. This prevents some
> otherwise tricky multiple-inheritance edge-cases present in both of our
> flagging systems that I discovered during testing. I don't think there are
> actual use-cases for unsetting the flags in subclasses, but we can revisit
> that later if needed.)
>

That's surprising to me. Just like we can have a class that inherits from
int but isn't hashable, and make that explicit by setting `__hash__ =
None`, why couldn't I have a class that inherits from something else that
happens to inherit from Sequence, and say "but I don't want it to match
like a sequence" by adding `__match_sequence__ = False`? AFAIK all Mark's
versions would support this by setting `__match_kind__ = 0`.

Maybe you can show an example edge case where this would be undesirable?

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/EMNJQVXAJMTZHFQKCK6SQ5MMSGTFVXYG/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Brandt Bucher
Guido van Rossum wrote:
> On Wed, Mar 31, 2021 at 2:14 PM Brandt Bucher brandtbuc...@gmail.com
> wrote:
> > (One change from my last email: it doesn't allow `__match_map__` /
> > `__match_seq__` to be set to `False`... only `True`. This prevents some
> > otherwise tricky multiple-inheritance edge-cases present in both of our
> > flagging systems that I discovered during testing. I don't think there are
> > actual use-cases for unsetting the flags in subclasses, but we can revisit
> > that later if needed.)
> That's surprising to me. Just like we can have a class that inherits from
> int but isn't hashable, and make that explicit by setting `__hash__ =
> None`, why couldn't I have a class that inherits from something else that
> happens to inherit from Sequence, and say "but I don't want it to match
> like a sequence" by adding `__match_sequence__ = False`? AFAIK all Mark's
> versions would support this by setting `__match_kind__ = 0`.

The issue isn't when *I* set `__match_seq__ = False` or `__match_container__ = 
0`. It's when *one of my parents* does it that things become difficult.

> Maybe you can show an example edge case where this would be undesirable?

Good idea. I've probably been staring at this stuff for too long to figure it 
out myself. :)

As far as I can tell, these surprising cases arise because a bit flag can only 
be either 0 or 1. For us, "not specified" is equivalent to 0, which can lead to 
ambiguity.

Consider this case:

```
class Seq:
__match_seq__ = True
# or __match_container__ = MATCH_SEQUENCE

class Parent:
pass

class Child(Parent, Seq):
pass
```

Okay, cool. `Child` will match as a sequence, which seems correct. But what 
about this similar case?

```
class Seq:
__match_seq__ = True
# or __match_container__ = MATCH_SEQUENCE

class Parent:
__match_seq__ = False
# or __match_container__ = 0

class Child(Parent, Seq):
pass
```

Here, `Child` will *not* match as a sequence, even though it probably should. 
The only workarounds I've found (like allowing `None` to mean "this is unset, 
don't inherit me if another parent sets this flag", ditching tp_flags entirely, 
or not inheriting these attributes) feel a bit extreme just to allow some users 
to do the moral equivalent of un-subclassing `collections.abc.Sequence`.

So, my current solution (seen on the branch linked in my earlier email) is:

- Set the flag if the corresponding magic attribute is set to True in the class 
definition
- Raise at class definition time if it's set to anything other than True
- Otherwise, set the flag if any of the parents set have the flag set

As far as I can tell, this leads to the expected (and current, as of 3.10.0a6) 
behavior in all cases. Plus, it doesn't break my mental model of how 
inheritance works.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/R3BGDN6NINJMLUWBVMVYIGORSLPJOMJP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Caleb Donovick
> Here, `Child` will *not* match as a sequence, even though it probably
should,

Strong disagree,  if I explicitly set `__match_seq__` to `False` in
`Parent` I probably have a good reason for it and would absolutely expect
`Child` to not match as a sequence.

> - Raise at class definition time if it's set to anything other than True

I feel like this is a consenting adults thing.  Yeah you probably won't
need to set a flag to `False` but I don't see why it should be forbidden.

On Wed, Mar 31, 2021 at 3:35 PM Brandt Bucher 
wrote:

> Guido van Rossum wrote:
> > On Wed, Mar 31, 2021 at 2:14 PM Brandt Bucher brandtbuc...@gmail.com
> > wrote:
> > > (One change from my last email: it doesn't allow `__match_map__` /
> > > `__match_seq__` to be set to `False`... only `True`. This prevents some
> > > otherwise tricky multiple-inheritance edge-cases present in both of our
> > > flagging systems that I discovered during testing. I don't think there
> are
> > > actual use-cases for unsetting the flags in subclasses, but we can
> revisit
> > > that later if needed.)
> > That's surprising to me. Just like we can have a class that inherits from
> > int but isn't hashable, and make that explicit by setting `__hash__ =
> > None`, why couldn't I have a class that inherits from something else that
> > happens to inherit from Sequence, and say "but I don't want it to match
> > like a sequence" by adding `__match_sequence__ = False`? AFAIK all Mark's
> > versions would support this by setting `__match_kind__ = 0`.
>
> The issue isn't when *I* set `__match_seq__ = False` or
> `__match_container__ = 0`. It's when *one of my parents* does it that
> things become difficult.
>
> > Maybe you can show an example edge case where this would be undesirable?
>
> Good idea. I've probably been staring at this stuff for too long to figure
> it out myself. :)
>
> As far as I can tell, these surprising cases arise because a bit flag can
> only be either 0 or 1. For us, "not specified" is equivalent to 0, which
> can lead to ambiguity.
>
> Consider this case:
>
> ```
> class Seq:
> __match_seq__ = True
> # or __match_container__ = MATCH_SEQUENCE
>
> class Parent:
> pass
>
> class Child(Parent, Seq):
> pass
> ```
>
> Okay, cool. `Child` will match as a sequence, which seems correct. But
> what about this similar case?
>
> ```
> class Seq:
> __match_seq__ = True
> # or __match_container__ = MATCH_SEQUENCE
>
> class Parent:
> __match_seq__ = False
> # or __match_container__ = 0
>
> class Child(Parent, Seq):
> pass
> ```
>
> Here, `Child` will *not* match as a sequence, even though it probably
> should. The only workarounds I've found (like allowing `None` to mean "this
> is unset, don't inherit me if another parent sets this flag", ditching
> tp_flags entirely, or not inheriting these attributes) feel a bit extreme
> just to allow some users to do the moral equivalent of un-subclassing
> `collections.abc.Sequence`.
>
> So, my current solution (seen on the branch linked in my earlier email) is:
>
> - Set the flag if the corresponding magic attribute is set to True in the
> class definition
> - Raise at class definition time if it's set to anything other than True
> - Otherwise, set the flag if any of the parents set have the flag set
>
> As far as I can tell, this leads to the expected (and current, as of
> 3.10.0a6) behavior in all cases. Plus, it doesn't break my mental model of
> how inheritance works.
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@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/R3BGDN6NINJMLUWBVMVYIGORSLPJOMJP/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/PRCDAGDDSJGLEVXFEPX26VB7JENYEDAF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Chris Angelico
On Thu, Apr 1, 2021 at 11:54 AM Caleb Donovick  wrote:
>
> > Here, `Child` will *not* match as a sequence, even though it probably 
> > should,
>
> Strong disagree,  if I explicitly set `__match_seq__` to `False` in `Parent` 
> I probably have a good reason for it and would absolutely expect `Child` to 
> not match as a sequence.
>

How much difference is there between:

class Grandparent:
"""Not a sequence"""
class Parent(Grandparent):
"""Also not a sequence"""
class Child(Parent):
"""No sequences here"""

and this:

class Grandparent(list):
"""Is a sequence"""
class Parent(Grandparent):
"""Explicitly not a sequence"""
__match_seq__ = False
class Child(Parent):
"""Shouldn't be a sequence"""


? Either way, Parent should function as a non-sequence. But if Child
inherits from both Parent and tuple, it is most definitely a tuple,
and therefore should be a sequence.

With your proposed semantics, setting __match_seq__ to False is not
simply saying "this isn't a sequence", but it's saying "prevent this
from being a sequence". It's a stronger statement than simply undoing
the declaration that it's a sequence. There would be no way to reset
to the default state.

Brandt's proposed semantics sound complicated, but as far as I can
tell, they give sane results in all cases.

ChrisA
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/GKOUSL2CPMO7NPPTK2E7XE7LXTPDVRDJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Weird io.OpenWrapper hack to use a function as method

2021-03-31 Thread Inada Naoki
Do we need _pyio at all?
Does PyPy or any other Python implementation use it?

On Wed, Mar 31, 2021 at 9:36 PM Victor Stinner  wrote:
>
> Hi,
>
> The io module provides an open() function. It also provides an
> OpenWrapper which only exists to be able to store open as a method
> (class or instance method). In the _pyio module, pure Python
> implementation of the io module, OpenWrapper is implemented as:
>
> class OpenWrapper:
> """Wrapper for builtins.open
>
> Trick so that open won't become a bound method when stored
> as a class variable (as dbm.dumb does).
>
> See initstdio() in Python/pylifecycle.c.
> """
> def __new__(cls, *args, **kwargs):
> return open(*args, **kwargs)
>
> I would like to remove this class which is causing troubles in the PEP
> 597 implementation, but I don't know how. Simplified problem:
> ---
> def func():
> print("my func")
>
> class MyClass:
> method = func
>
> func() # A
> MyClass.method() # B
> obj = MyClass()
> obj.method() # C
> ---
>
> With this syntax, A and B work, but C fails with TypeError: func()
> takes 0 positional arguments but 1 was given.
>
> If I decorate func() with @staticmethod, B and C work, but A fails
> with TypeError: 'staticmethod' object is not callable.
>
> Is OpenWrapper the only way to have a callable object which works in
> the 3 variants A, B and C?
>
> A, B and C work if MyClass is modified to use staticmethod:
>
> class MyClass:
> method = staticmethod(func)
>
> Victor
> --
> Night gathers, and now my watch begins. It shall not end until my death.
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@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/QZ7SFW3IW3S2C5RMRJZOOUFSHHUINNME/
> Code of Conduct: http://python.org/psf/codeofconduct/



-- 
Inada Naoki  
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/BOSZENKZRZCTIYWDRBRLWT4GKHWGDLWP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Caleb Donovick
> It's a stronger statement than simply undoing
> the declaration that it's a sequence. There would be no way to reset
> to the default state.

How is this different from anything else that is inherited?

The setting of a flag to `False` is not some irreversible process which
permanently blocks child classes from setting that flag to `True`.
If I want to give priority to `Seq` over `Parent` in Brandt's original
example I need only switch the order of inheritance so that `Seq` is
earlier in `Child` MRO or explicitly set the flag to `True` (or
`Seq.__match_seq__`).  In contrast Brandt's scheme does irreversibly
set flags, there is no way to undo the setting of `__match_seq__` in a
parent class.

This really doesn't seem like an issue to me.  I can't personally think of
a use case for explicitly setting a flag to `False`
 but I also don't see why it should be forbidden. We get "- Otherwise, set
the flag if any of the parents set have the flag set"
for free through normal MRO rules except in the case where there is an
explicit `False` (which I assume will be exceedingly rare
and if it isn't there is clearly some use case).  Why make it more
complicated?

On Wed, Mar 31, 2021 at 6:05 PM Chris Angelico  wrote:

> On Thu, Apr 1, 2021 at 11:54 AM Caleb Donovick 
> wrote:
> >
> > > Here, `Child` will *not* match as a sequence, even though it probably
> should,
> >
> > Strong disagree,  if I explicitly set `__match_seq__` to `False` in
> `Parent` I probably have a good reason for it and would absolutely expect
> `Child` to not match as a sequence.
> >
>
> How much difference is there between:
>
> class Grandparent:
> """Not a sequence"""
> class Parent(Grandparent):
> """Also not a sequence"""
> class Child(Parent):
> """No sequences here"""
>
> and this:
>
> class Grandparent(list):
> """Is a sequence"""
> class Parent(Grandparent):
> """Explicitly not a sequence"""
> __match_seq__ = False
> class Child(Parent):
> """Shouldn't be a sequence"""
>
>
> ? Either way, Parent should function as a non-sequence. But if Child
> inherits from both Parent and tuple, it is most definitely a tuple,
> and therefore should be a sequence.
>
> With your proposed semantics, setting __match_seq__ to False is not
> simply saying "this isn't a sequence", but it's saying "prevent this
> from being a sequence". It's a stronger statement than simply undoing
> the declaration that it's a sequence. There would be no way to reset
> to the default state.
>
> Brandt's proposed semantics sound complicated, but as far as I can
> tell, they give sane results in all cases.
>
> ChrisA
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@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/GKOUSL2CPMO7NPPTK2E7XE7LXTPDVRDJ/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/UWSPAA27Q2ZE44YHK7ZKQCO5YZ2HG32F/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Guido van Rossum
+1. I also don’t see what’s the big deal.

On Wed, Mar 31, 2021 at 19:27 Caleb Donovick 
wrote:

> > It's a stronger statement than simply undoing
> > the declaration that it's a sequence. There would be no way to reset
> > to the default state.
>
> How is this different from anything else that is inherited?
>
> The setting of a flag to `False` is not some irreversible process which
> permanently blocks child classes from setting that flag to `True`.
> If I want to give priority to `Seq` over `Parent` in Brandt's original
> example I need only switch the order of inheritance so that `Seq` is
> earlier in `Child` MRO or explicitly set the flag to `True` (or
> `Seq.__match_seq__`).  In contrast Brandt's scheme does irreversibly
> set flags, there is no way to undo the setting of `__match_seq__` in a
> parent class.
>
> This really doesn't seem like an issue to me.  I can't personally think of
> a use case for explicitly setting a flag to `False`
>  but I also don't see why it should be forbidden. We get "- Otherwise, set
> the flag if any of the parents set have the flag set"
> for free through normal MRO rules except in the case where there is an
> explicit `False` (which I assume will be exceedingly rare
> and if it isn't there is clearly some use case).  Why make it more
> complicated?
>
> On Wed, Mar 31, 2021 at 6:05 PM Chris Angelico  wrote:
>
>> On Thu, Apr 1, 2021 at 11:54 AM Caleb Donovick 
>> wrote:
>> >
>> > > Here, `Child` will *not* match as a sequence, even though it probably
>> should,
>> >
>> > Strong disagree,  if I explicitly set `__match_seq__` to `False` in
>> `Parent` I probably have a good reason for it and would absolutely expect
>> `Child` to not match as a sequence.
>> >
>>
>> How much difference is there between:
>>
>> class Grandparent:
>> """Not a sequence"""
>> class Parent(Grandparent):
>> """Also not a sequence"""
>> class Child(Parent):
>> """No sequences here"""
>>
>> and this:
>>
>> class Grandparent(list):
>> """Is a sequence"""
>> class Parent(Grandparent):
>> """Explicitly not a sequence"""
>> __match_seq__ = False
>> class Child(Parent):
>> """Shouldn't be a sequence"""
>>
>>
>> ? Either way, Parent should function as a non-sequence. But if Child
>> inherits from both Parent and tuple, it is most definitely a tuple,
>> and therefore should be a sequence.
>>
>> With your proposed semantics, setting __match_seq__ to False is not
>> simply saying "this isn't a sequence", but it's saying "prevent this
>> from being a sequence". It's a stronger statement than simply undoing
>> the declaration that it's a sequence. There would be no way to reset
>> to the default state.
>>
>> Brandt's proposed semantics sound complicated, but as far as I can
>> tell, they give sane results in all cases.
>>
>> ChrisA
>> ___
>> Python-Dev mailing list -- python-dev@python.org
>> To unsubscribe send an email to python-dev-le...@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/GKOUSL2CPMO7NPPTK2E7XE7LXTPDVRDJ/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@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/UWSPAA27Q2ZE44YHK7ZKQCO5YZ2HG32F/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-- 
--Guido (mobile)
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/LVVS7YUUC37OZQLHDQZXKSEZ2GNQCSXB/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Weird io.OpenWrapper hack to use a function as method

2021-03-31 Thread Brett Cannon
On Wed., Mar. 31, 2021, 18:56 Inada Naoki,  wrote:

> Do we need _pyio at all?
> Does PyPy or any other Python implementation use it?
>

https://www.python.org/dev/peps/pep-0399/ would suggest rolling back Python
support is something to avoid.


> On Wed, Mar 31, 2021 at 9:36 PM Victor Stinner 
> wrote:
> >
> > Hi,
> >
> > The io module provides an open() function. It also provides an
> > OpenWrapper which only exists to be able to store open as a method
> > (class or instance method). In the _pyio module, pure Python
> > implementation of the io module, OpenWrapper is implemented as:
> >
> > class OpenWrapper:
> > """Wrapper for builtins.open
> >
> > Trick so that open won't become a bound method when stored
> > as a class variable (as dbm.dumb does).


>
> > See initstdio() in Python/pylifecycle.c.
> > """
> > def __new__(cls, *args, **kwargs):
> > return open(*args, **kwargs)
> >
> > I would like to remove this class which is causing troubles in the PEP
> > 597 implementation, but I don't know how. Simplified problem:
> > ---
> > def func():
> > print("my func")
> >
> > class MyClass:
> > method = func
> >
> > func() # A
> > MyClass.method() # B
> > obj = MyClass()
> > obj.method() # C
> > ---
> >
> > With this syntax, A and B work, but C fails with TypeError: func()
> > takes 0 positional arguments but 1 was given.
> >
> > If I decorate func() with @staticmethod, B and C work, but A fails
> > with TypeError: 'staticmethod' object is not callable.
> >
> > Is OpenWrapper the only way to have a callable object which works in
> > the 3 variants A, B and C?
> >
> > A, B and C work if MyClass is modified to use staticmethod:
> >
> > class MyClass:
> > method = staticmethod(func)
> >
> > Victor
> > --
> > Night gathers, and now my watch begins. It shall not end until my death.
> > ___
> > Python-Dev mailing list -- python-dev@python.org
> > To unsubscribe send an email to python-dev-le...@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/QZ7SFW3IW3S2C5RMRJZOOUFSHHUINNME/
> > Code of Conduct: http://python.org/psf/codeofconduct/
>
>
>
> --
> Inada Naoki  
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@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/BOSZENKZRZCTIYWDRBRLWT4GKHWGDLWP/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/6WKW5LJKEFSRTZFXXCIS3UWI3YOSKP7L/
Code of Conduct: http://python.org/psf/codeofconduct/