Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Builtins Integration

## Purpose
The builtins integration capability allows optional installation of the absence sentinel and predicate into the Python builtins module. This enables usage without explicit imports in every file, similar to `None` or `True`.

## Requirements

### Requirement: Install Function
The package MUST provide an `install()` function to inject symbols into builtins.

Priority: Medium

#### Scenario: Default Installation
- **WHEN** `install()` is called without arguments
- **THEN** `Absent` is added to builtins (referencing `absent`)
- **AND** `isabsent` is added to builtins (referencing `is_absent`)

#### Scenario: Custom Names
- **WHEN** `install()` is called with `sentinel_name='MyAbsent'` and `predicate_name='is_missing'`
- **THEN** `MyAbsent` and `is_missing` are added to builtins with correct references

#### Scenario: Partial Installation
- **WHEN** `install()` is called with `sentinel_name=None`
- **THEN** the sentinel is not added to builtins
- **AND** the predicate is added (unless also None)

#### Scenario: Non-Conflict
- **WHEN** `install()` is called multiple times with different names
- **THEN** all installed names remain available
30 changes: 30 additions & 0 deletions documentation/architecture/openspec/specs/custom-sentinels/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Custom Sentinels

## Purpose
The custom sentinels capability allows developers to create distinct absence sentinels for specific packages or contexts. This prevents conflicts when multiple libraries use sentinels and allows for custom string representations.

## Requirements

### Requirement: Absence Factory
The package MUST provide an `AbsenceFactory` class to create custom absence sentinels.

Priority: High

#### Scenario: Sentinel Creation
- **WHEN** `AbsenceFactory()` is instantiated
- **THEN** it returns a new sentinel object
- **AND** the new sentinel is distinct from the global `absent` sentinel

#### Scenario: Falsey Behavior
- **WHEN** a custom sentinel is evaluated in a boolean context
- **THEN** it evaluates to `False`

#### Scenario: Custom String Representation
- **WHEN** `AbsenceFactory` is instantiated with `repr_function` and `str_function`
- **THEN** `repr(sentinel)` calls the provided `repr_function`
- **AND** `str(sentinel)` calls the provided `str_function`

#### Scenario: Predicate Behavior
- **WHEN** `is_absence(custom_sentinel)` is called
- **THEN** it returns `True`
- **AND** `is_absent(custom_sentinel)` returns `False`
35 changes: 35 additions & 0 deletions documentation/architecture/openspec/specs/global-sentinel/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Global Absence Sentinel

## Purpose
The global `absent` sentinel provides a standardized, process-unique object to represent missing values. This addresses the ambiguity of using `None` in scenarios where `None` is a valid value, enabling developers to distinguish between "not provided" and "provided as None".

## Requirements

### Requirement: Singleton Instance
The package MUST provide a globally unique `absent` sentinel available as a module-level singleton.

Priority: Critical

#### Scenario: Identity Check
- **WHEN** the `absent` object is compared with itself using the `is` operator
- **THEN** the result is `True`
- **AND** comparing `absent` with any newly created object returns `False`

#### Scenario: Boolean Evaluation
- **WHEN** the `absent` object is evaluated in a boolean context
- **THEN** it evaluates to `False`

#### Scenario: String Representation
- **WHEN** the `absent` object is converted to a string using `str()`
- **THEN** it returns `'absent'`
- **AND** `repr(absent)` returns `'absence.absent'`

### Requirement: Non-Picklable
The `absent` sentinel MUST NOT be picklable to guarantee singleton semantics and prevent bugs from unpickling multiple instances.

Priority: Critical

#### Scenario: Pickling Attempt
- **WHEN** `pickle.dumps()` is called with the `absent` object
- **THEN** it raises an `OperationValidityError`
- **AND** the error message indicates that pickling is not supported
39 changes: 39 additions & 0 deletions documentation/architecture/openspec/specs/type-safety/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Type Safety

## Purpose
The type safety capability provides tools for static type checkers and runtime verification to ensure correct usage of absence sentinels. This includes type predicates for narrowing types and a type alias for expressing optional parameters.

## Requirements

### Requirement: Type Predicates
The package MUST provide type-safe predicate functions for checking absence.

Priority: Critical

#### Scenario: Global Sentinel Check
- **WHEN** `is_absent(value)` is called with the global `absent` sentinel
- **THEN** it returns `True`
- **AND** it returns `False` for any other value (including `None` or custom sentinels)

#### Scenario: General Absence Check
- **WHEN** `is_absence(value)` is called with any absence sentinel (global or custom)
- **THEN** it returns `True`
- **AND** it returns `False` for other objects (including `None`)

#### Scenario: Type Guarding
- **WHEN** `is_absent(value)` is used in a conditional
- **THEN** type checkers narrow the type of `value` to `AbsentSingleton` in the true branch

### Requirement: Absential Type Alias
The package MUST provide an `Absential[T]` type alias to represent a value that can be of type `T` or `absent`.

Priority: Critical

#### Scenario: Type Definition
- **WHEN** `Absential[int]` is used as a type annotation
- **THEN** it accepts integers and the `absent` sentinel
- **AND** it rejects other types (e.g., strings)

#### Scenario: Generic Support
- **WHEN** `Absential[T]` is used with a complex type `T` (e.g., `dict[str, Any]`)
- **THEN** it correctly represents the union of `T` and the sentinel type
Loading