[Python-Dev] Re: The repr of a sentinel

2021-06-01 Thread Tal Einat
Following the continued discussion, I'm currently in favor of a simple
interface using a factory function, i.e. NotGiven = sentinel('NotGiven').

I've created a new GitHub repo with a reference implementation. It also
includes a second version of the draft PEP, addresses some of the
additional points brought up in the latest parts of this discussion.

https://github.com/taleinat/python-stdlib-sentinels

- Tal

On Mon, May 24, 2021 at 5:28 PM Tal Einat  wrote:

> On Mon, May 24, 2021 at 3:30 AM Luciano Ramalho 
> wrote:
> >
> > On Sun, May 23, 2021 at 3:37 AM Tal Einat  wrote:
> > > I put up an early draft of a PEP on a branch in the PEPs repo:
> > > https://github.com/python/peps/blob/sentinels/pep-.rst
> >
> > Thanks for that PEP, Tal. Good ideas and recap there.
> >
> > I think repr= should have a default: the name of the class within <>:
> > .
> >
> > Sentinels don't have state or any other data besides a name, so I
> > would prefer not to force users to create a class just so they can
> > instantiate it.
> >
> > Why not just this?
> >
> > NotGiven = sentinel('')
>
> I'm seriously considering that now. The issues I ran into with this
> approach are perhaps not actually problematic.
>
> > On the other hand, if the user must create a class, the class itself
> > should be the sentinel. Class objects are already singletons, so that
> > makes sense.
> >
> > Here is a possible class-based API:
> >
> > class NotGiven(Sentinel):
> > pass
> >
> > That's it. Now I can use NotGiven as the sentinel, and its default
> > repr is .
> >
> > Behind the scenes we can have a SentinelMeta metaclass with all the
> > magic that could be required--including the default __repr__ method.
> >
> > What do you think?
>
> One issue with that is that such sentinels don't have their own class,
> so you can't write a strict type signature, such as `Union[str,
> NotGivenType]`.
>
> Another issue is that having these objects be classes, rather than
> normal instances of classes, could be surprising and confusing.
>
> For those two reasons, for now, I think generating a unique object
> with its own unique class is preferable.
>
> > Sorry about my detour into the rejected idea of a factory function.
>
> Please don't apologize! I put those ideas in the "Rejected Ideas"
> section mostly to have them written down with a summary of the
> considerations related to them. They shouldn't be considered finally
> rejected unless and until the PEP is finished and accepted.
>
> - Tal
>
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/WVUIDCPLQULT4THEQ3CXNARZIUSF4C2U/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: The repr of a sentinel

2021-06-01 Thread Tal Einat
Thanks for this, Luciano!

My main issue with using class objects is that such use of them would be
unusual and potentially confusing. I think that is important in general,
and doubly so for something I suggest adding to the stdlib.

Additionally, I very much would like for each sentinel object to have its
own dedicated class, to allow writing strict function type signatures. Once
one adds that to a meta-class or class decorator, the complexity of the
implementation approaches what I currently have for a sentinel() function.
At that point, I can't see a clear advantage for such an approach.

- Tal

On Mon, May 24, 2021 at 7:31 PM Luciano Ramalho  wrote:

> On Mon, May 24, 2021 at 11:44 AM Tal Einat  wrote:
> > > But frankly Luciano's idea of a base class that can be subclassed
> seems the most startightford to me.
> >
> > Yes, and it's what I originally suggested near the beginning of this
> thread :)
>
> I am sorry to have missed your previous e-mail with a base class for
> sentinels, @Tal. I support that idea.
>
> In fact, if we have a SentinelMeta metaclass, and a Sentinel base
> class built from SentinelMeta, the Sentinel class can be used directly
> as a sentinel without the need for subclassing—if the application does
> not require a custom sentinel. If it does, then the user can subclass
> Sentinel.
>
> The SentinelMeta could be private, to discourage misuse.
>
> This is my implementation, after learning from @Tal's code:
>
>
> https://github.com/fluentpython/example-code-2e/blob/master/25-class-metaprog/sentinel/sentinel.py
>
> Since having a Sentinel base class is desirable for ease of use, I
> think it is simpler to code the __new__ method in it, instead of
> coding metaclass logic to inject __new__ in the class namespace.
>
> Best,
>
> Luciano
>
>
>
> --
> Luciano Ramalho
> |  Author of Fluent Python (O'Reilly, 2015)
> | http://shop.oreilly.com/product/0636920032519.do
> |  Technical Principal at ThoughtWorks
> |  Twitter: @ramalhoorg
>
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/HGG43Y5IM5HVCEERA3ZFM6II6W2G6Y5H/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: The repr of a sentinel

2021-06-01 Thread Tal Einat
On Tue, May 25, 2021 at 11:25 AM Pascal Chambon  wrote:
>
> Hello, and thanks for the PEP,
>
> I feel like the 3-lines declaration of a new sentinel would discourage a
> bit its adoption compared to just "sentinel = object()"

I now tend to agree. The new version of the draft PEP proposes a
simpler interface: NotGiven = sentinel('NotGiven')

> From what I understand from the PEP, if new classes are defined inside
> the closure of a factory function, some Python implementations would
> have trouble copying/pickling them?

The reference implementations I propose take care of this. I'll make
sure that everything works in popular alternate implementations such
as PyPy.

> Would it be doable to have a single Sentinel class, whose instances
> store their representation and some autogenerated UUID, and which
> automatically return internally stored singletons (depending on this
> UUID) when called multiple times or unpickled ?
> This would require some __new__() and unpickling magic, but nothing too
> CPython-specific (or am I missing something?).

That's certainly doable, and I believe that there are existing
implementations of sentinels that use this method. But since classes
are singletons, and it's simple to make a class that always returns
the same object, there's no need for setting a UUID and implementing
custom pickling logic as you suggest.

Another drawback of this approach is that each sentinel value wouldn't
have its own dedicated type.

- Tal
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/SPIN5YYO2R6SU4FTKW2IEQY23KBTGYHR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: The repr of a sentinel

2021-06-01 Thread Tal Einat
On Tue, May 25, 2021 at 10:09 PM Eric Nieuwland
 wrote:
>
>
> To add to the suggestions already given in this thread I dug into code I 
> wrote some time ago. Offered as an inspiration.
>
> === missing.py ===
>
> from typing import Any
>
> def MISSING(klass: Any) -> Any: """ create a sentinel to indicate a missing 
> instance of a class :param klass: the class of which an instance is missing 
> :return: missing class object """ g = globals() missing_klass_name = 
> f"_MISSING_{klass.__module__}_{klass.__name__}_MISSING_" if 
> missing_klass_name not in g: g[missing_klass_name] = type( 
> missing_klass_name, (klass,), { "__repr__": lambda x: 
> f"MISSING({klass.__name__})", } ) return g[missing_klass_name]()
>
> ===
>
> and as a demo:
>
> === demo_missing.py ===
>
> import pickle
>
> from missing import MISSING
>
> x = MISSING(str) y = "bar" print(f"{x!r} == {y!r}: {x == y}") print(f"{x!r} 
> is {y!r}: {x is y}") # MISSING(str) == 'bar': False # MISSING(str) is 'bar': 
> False
>
> with open("object.pickled", "wb") as f: pickle.dump(x, f) with 
> open("object.pickled", "rb") as f: y = pickle.load(f) print(f"{x!r} == {y!r}: 
> {x == y}") print(f"{x!r} is {y!r}: {x is y}") # MISSING(str) == MISSING(str): 
> True # MISSING(str) is MISSING(str): False
>
> def foo(a: int = MISSING(int), b: int = MISSING(int)): print(f"{a=} 
> {isinstance(a, int)}") print(f"{b=} {isinstance(b, int)}") print(f"{a!r} == 
> {b!r}: {a == b}") print(f"{a!r} is {b!r}: {a is b}")
>
> foo() # a=MISSING(int) True # b=MISSING(int) True # MISSING(int) == 
> MISSING(int): True # MISSING(int) is MISSING(int): False
>
> foo(1) # a=1 True # b=MISSING(int) True # 1 == MISSING(int): False # 1 is 
> MISSING(int): False
>
> class Test: ...
>
> t = MISSING(Test) print(f"{t=}") # t=MISSING(Test)
>
> ===

Wow, that's... terribly clever. Thanks for sharing this!

- Tal
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/AEUHYDXJF3PVGGZ5WET5AMLKNO3STQJP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] [RELEASE] Python 3.10.0b2 is available

2021-06-01 Thread Pablo Galindo Salgado
After fighting with some release blockers, implementing a bunch of GC
traversal functions, and fixing some pending reference leaks, we finally
have Python 3.10.0 beta 2 ready for you! Thanks to everyone that helped to
unblock the release!

https://www.python.org/downloads/release/python-3100b2/

# This is a beta preview of Python 3.10

Python 3.10 is still in development. 3.10.0b2 is the second of four planned
beta release previews. Beta release previews are intended to give the wider
community the opportunity to test new features and bug fixes and to prepare
their projects to support the new feature release.

We **strongly encourage** maintainers of third-party Python projects to
**test with 3.10** during the beta phase and report issues found to [the
Python bug tracker](https://bugs.python.org/) as soon as possible. While
the release is planned to be feature complete entering the beta phase, it
is possible that features may be modified or, in rare cases, deleted up
until the start of the release candidate phase (Monday, 2021-08-02). Our
goal is to have no ABI changes after beta 4 and as few code changes as
possible after 3.10.0rc1, the first release candidate. To achieve that, it
will be **extremely important** to get as much exposure for 3.10 as
possible during the beta phase.

Please keep in mind that this is a preview release and its use is **not**
recommended for production environments.

The next pre-release of Python 3.10 will be 3.10.0b3, currently scheduled
for Thursday, 2021-06-17.

# And now for something completely different

The Ehrenfest paradox concerns the rotation of a "rigid" disc in the theory
of relativity. In its original 1909 formulation as presented by Paul
Ehrenfest in relation to the concept of Born rigidity within special
relativity, it discusses an ideally rigid cylinder that is made to rotate
about its axis of symmetry. The radius R as seen in the laboratory frame is
always perpendicular to its motion and should therefore be equal to its
value R0 when stationary. However, the circumference (2πR) should appear
Lorentz-contracted to a smaller value than at rest. This leads to the
apparent contradiction that R = R0 and R < R0.

# We hope you enjoy those new releases!

Thanks to all of the many volunteers who help make Python Development and
these releases possible! Please consider supporting our efforts by
volunteering yourself or through organization contributions to the Python
Software Foundation.

Regards from very sunny London,

Your friendly release team,
Pablo Galindo @pablogsal
Ned Deily @nad
Steve Dower @steve.dower
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/K24LNBMWJH6E6YKZK5PMAVEAQFPAPTYN/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Need help to debug a ssl crash on Windows which prevents merging PRs

2021-06-01 Thread Victor Stinner
On Fri, May 28, 2021 at 6:40 PM Victor Stinner  wrote:
> In the 3.10 branch, it became really hard to merge PRs because the
> following ssl crashs on Windows:
> https://bugs.python.org/issue44252

Update on this bug which blocked the Python 3.10 beta 2 release. It's
now fully fixed!

It was a simple bug in the _ssl.SSLError exception. The problem was
that the crash only occurred on Windows and only if tests were run in
a very specific way. On CIs, the crash was deterministic. When I
debugged the issue manually, I failed to reproduce it. I tried many
different ways to run the tests, none worked.

I recall an old hack: run "import gc; gc.set_threshold(5)" at startup.
It makes crashes related to GC way more likely (the default threshold
of GC generation 0 is 700). I used this hack 3 years ago to debug
another GC bug really hard to reproduce:
https://mail.python.org/pipermail/python-dev/2018-June/153857.html
https://docs.python.org/dev/library/gc.html#gc.set_threshold

Not only the _ssl.SSLError bug is fixed, but Pablo also fixed the
documentation to explain clearly that a traverse function must be
implemented if Py_TPFLAGS_HAVE_GC is set:
https://github.com/python/cpython/commit/8b55bc3f93a655bc803bff79725d5fe3f124e2f0

Moreover, for people who don't read the documentation ;-), I also made
sure that it's no longer possible to create a type with
Py_TPFLAGS_HAVE_GC but with no traverse function:
https://github.com/python/cpython/commit/ee7637596d8de25f54261bbeabc602d31e74f482

By the way, I had to fix two stdlib types (_testcapi and _decimal
modules) which didn't respect that!

Victor
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/7FHMUDJIZSO4EPREJ5XX6WTYLR3SQTAI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Need help to debug a ssl crash on Windows which prevents merging PRs

2021-06-01 Thread Rob Cliffe via Python-Dev

Well done Victor!
This stuff is way over my head, but rest assured that humble Python 
programmers like me appreciate all the effort put in from guys like you 
into improving Python.

Rob Cliffe

On 01/06/2021 23:14, Victor Stinner wrote:

On Fri, May 28, 2021 at 6:40 PM Victor Stinner  wrote:

In the 3.10 branch, it became really hard to merge PRs because the
following ssl crashs on Windows:
https://bugs.python.org/issue44252

Update on this bug which blocked the Python 3.10 beta 2 release. It's
now fully fixed!

It was a simple bug in the _ssl.SSLError exception.

[snip]
___
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/TDBYDARGKANV2ZIS27UTZW4NOKQKE6WE/
Code of Conduct: http://python.org/psf/codeofconduct/