Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a PEP661-compatible sentinels module #37

Closed
wants to merge 8 commits into from

Conversation

llucax
Copy link
Contributor

@llucax llucax commented Nov 8, 2024

Introduce a new module for creating unique sentinel objects according to PEP661.

This is based in the reference implementation in https://github.com/taleinat/python-stdlib-sentinels (commit 410273e40bdbd1b58a63cebefdf8abcce6c620e3), and adapted to match this repository documentation standards and linting tools.

To add support for PEP661 we copy the reference implementation at
https://github.com/taleinat/python-stdlib-sentinels. The code is copied
verbatim from commit 9fdf9628d7bf010f0a66c72b717802c715c7d564, only
adding the copyright notice, license and where we got the code from.

Signed-off-by: Leandro Lucarella <[email protected]>
Also update the header to clarify now this is not a verbatim copy
anymore and add another copyright line.

Signed-off-by: Leandro Lucarella <[email protected]>
Signed-off-by: Leandro Lucarella <[email protected]>
We don't want to check implementation details that deal with multiple
python implementations. We don't really want to *maintain* this code,
we added it with the hope that it gets added to the Python standard
library eventually.

Signed-off-by: Leandro Lucarella <[email protected]>
@github-actions github-actions bot added the part:tests Affects the unit, integration and performance (benchmarks) tests label Nov 8, 2024
Signed-off-by: Leandro Lucarella <[email protected]>
Signed-off-by: Leandro Lucarella <[email protected]>
@llucax llucax added the cmd:skip-release-notes It is not necessary to update release notes for this PR label Nov 8, 2024
@llucax
Copy link
Contributor Author

llucax commented Nov 8, 2024

Skipping release notes check as there is no release yet, we'll write the notes when the first release is out.

@llucax llucax added this to the v1.0.0 milestone Nov 8, 2024
Add missing docstrings and improve documentation to be compatible with
mkdocstrings and Google style.

Signed-off-by: Leandro Lucarella <[email protected]>
The PEP was updated in commit 410273e40bdbd1b58a63cebefdf8abcce6c620e3
but the reference implementation was not updated accordingly, so we
apply the proposed change here and add a test for it too.

Signed-off-by: Leandro Lucarella <[email protected]>
Marenz
Marenz previously approved these changes Nov 12, 2024
@Marenz Marenz added this pull request to the merge queue Nov 14, 2024
@Marenz Marenz removed this pull request from the merge queue due to a manual request Nov 14, 2024
if value is MISSING:
assert_type(value, MISSING)
else:
assert_type(value, int)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

python3 example.py
Traceback (most recent call last):
File "/home/marenz/frequenz/frequenz-client-dispatch-python/example.py", line 8, in
def func(value: int | MISSING) -> None:
~~~~^~~~~~~~~
TypeError: unsupported operand type(s) for |: 'type' and 'Sentinel'

Copy link
Contributor Author

@llucax llucax Nov 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dammit. Reading the spec again, this might need some language support:

More formally, type checkers should recognize sentinel creations of the form NAME = Sentinel('NAME') as creating a new sentinel object. If the name passed to the Sentinel constructor does not match the name the object is assigned to, type checkers should emit an error.

Sentinels defined using this syntax may be used in type expressions. They represent a fully static type that has a single member, the sentinel object itself.

Type checkers should support narrowing union types involving sentinels using the is and is not operators:

@Marenz Marenz dismissed their stale review November 14, 2024 14:42

Example is not working

@llucax
Copy link
Contributor Author

llucax commented Nov 15, 2024

I tried several alternatives and couldn't make it work with a reasonable syntax, so I guess we need to wait for the official support.

I tried other more old school implementations and they all suck, I guess the best approach for now is still to just do class Sentinel: pass; SENTINEL = Sentinel(), at least until this gets implemented, then at least we can use Literal with SENTINEL: Final = object() and accept Literal[SENTINEL] as argument, which seems still reasonable:

I think I will close for now.

@llucax llucax closed this Nov 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cmd:skip-release-notes It is not necessary to update release notes for this PR part:tests Affects the unit, integration and performance (benchmarks) tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants