python-stdlib-sentinels icon indicating copy to clipboard operation
python-stdlib-sentinels copied to clipboard

Specific type signatures for each sentinel value

Open not-my-profile opened this issue 2 years ago • 2 comments

I really like the proposed Sentinel class because when using an Enum for a singleton type it always annoyingly shows up in type signatures and autogenerated documentation.

However I think not supporting Literal as mentioned in Specific type signatures for each sentinel value is a big mistake, since it would mean Sentinel could not actually replace Enum if you require the ability to use the type in Literal ... which I think is a very common requirement.

Python notably does not support algebraic data types. For example in Rust you could just define:

enum Submodule {
    Specific(String),
    All,
    AllRecursively,
}

the closest you can do in Python is to use the Union type, for example Union[str, Literal[DirectSubmodules, AllSubmodules]], now instead of having to abuse Enum for this as follows:

class _ModuleSpec(Enum):
    DirectSubmodules = 'DirectSubmodules'
    AllSubmodules = 'AllSubmodules'

DirectSubmodules = _ModuleSpec.DirectSubmodules
AllSubmodules = _ModuleSpec.AllSubmodules

(which would result in _ModuleSpec showing up in IDE tooltips and autogenerated API documentation and thus potentially confuse users), it would be great if you could instead just do:

DirectSubmodules = Sentinel('DirectSubmodules')
AllSubmodules = Sentinel('AllSubmodules')

and still be able to use Literal[DirectSubmodules, AllSubmodules].

The PEP mentions that Literal support has been dropped from the PEP due to concerns voiced on the mailing list. While I cannot really comment on the challenges of special casing Literal, I think this additional complexity would definitely be worth it to make Sentinel as useful as Enum and allow it to replace it for cases where you do not actually want to introduce an enum type.

not-my-profile avatar Dec 26 '22 09:12 not-my-profile

You don't say what concrete problems this would solve. I think both the PEP and the linked typing-sig discussion got a bit stuck in disagreement over how sentinels should be defined, but my preference (second message in the thread), which I still stand by, is to make sentinels directly usable as types. In your case, if you want to accept either str or your two sentinels, you would write str | DirectSubmodules | AllSubmodules.

JelleZijlstra avatar Dec 26 '22 14:12 JelleZijlstra

Oh that would actually work great for me ... I created this issue because I understood the Specific type signatures for each sentinel value section of the PEP to say that value-specific types wouldn't be supported at all. Am I misunderstanding the PEP? Reading the section again it still seems to imply that str | DirectSubmodules | AllSubmodules wouldn't be supported.

not-my-profile avatar Dec 26 '22 14:12 not-my-profile