-
Notifications
You must be signed in to change notification settings - Fork 4
Description
I propose a style guide when we create a sentinel.
Common standard python sentinels like 'True', 'False', 'None' follow this style
-
Naming Conventions: The requirement for sentinel names to be in title case and have descriptive names is clear and aligns with Python's naming conventions. This ensures that sentinel names are meaningful and self-explanatory. Example:
Undefined,Missing. -
Avoiding Conflicts: The guideline to avoid overriding standard Python sentinels like None, True, and False is crucial to prevent confusion and unexpected behavior. It's important to emphasize that sentinels should not interfere with the behavior of built-in constants.
-
Usage of Sentinels: The suggestion to use sentinels only when None cannot be used as a sentinel value is reasonable. It encourages developers to leverage the existing
Nonesentinel when it fits the purpose as this is normal python standard. -
Complexity of Sentinels: The recommendation to keep sentinels simple and not create complex classes or subclasses aligns with the principle of keeping code straightforward and understandable.
-
Consistency: Sentinels created must be consistent throughout the entire project. The created Sentinels must have the same meaning wherever it is used. The guideline to maintain consistency in the meaning of sentinels throughout a project is essential for code clarity and predictability.
-
Sentinel Comparison Order: Sentinels cannot be compared with each other. Use
Enumsinstead. -
Explicit Boolean Evaluation: Provide Boolean evaluation explicitly rather than setting it to be
Trueby default as this avoids confusion.Example:
Undefined = Sentinel('<undefined>') # Let's say a function can return `Undefined ` value = foo() if value: print(f"Value received is {value}") else: raise ValueError("Value wan't available")
Here you can see that, it makes more sense that Undefined was
Falserather than it beingTrueby default. If a sentinel must beTrueorFalsedepends on the context of the sentinel.
Example:Undefinedshould be evaluated toFalseandSuccesscan be evaluated toTrue, whileEOFdoesn't necessarily meanTrueorFalseand thus can have an "Invalid State" or it is "ambiguous".
So, I propose that we should pass in explicitly if a Sentinel is truthy or not, using thetruthyargument. Thetruthyargument can beTrue,FalseorNone(default). IftruthyisNone, then we should raise aValueError. This makes sentinels more explicit and can force the users to give meaning to a sentinel and enforces them to useisoperator to evaluate.Example:
Undefined = Sentinel('<undefined>', truthy=False) Success= Sentinel('<successful>', truthy=True) EOF= Sentinel('<undefined>') value = Undefined if value: print("value is defined.") value = Success if value: print("Function ran successfully") value = EOF # This results in a ValueError # bool(value)
This makes the behavior of sentinels more explicit and avoids any ambiguity.
Can we discuss this and possibly add it into PEP 661 Proposal?