valid8r.prompt.io_provider

IO provider interface for pluggable input/output in prompt functions.

This module defines the IOProvider protocol and standard implementations for handling user interaction in prompt functions. By using a pluggable provider, prompts can be tested without monkeypatching builtins, and alternative UIs (TUI, GUI) can be easily integrated.

Classes

IOProvider

Protocol for pluggable input/output in prompt functions.

BuiltinIOProvider

Default IO provider using Python builtins (input/print).

TestIOProvider

IO provider for testing that captures I/O without builtins.

Module Contents

class valid8r.prompt.io_provider.IOProvider[source]

Bases: Protocol

Protocol for pluggable input/output in prompt functions.

Implementations of this protocol can provide custom behavior for displaying prompts, collecting input, and showing error messages. This enables testing without mocking builtins and supports alternative UIs beyond command-line interfaces.

Examples

Use default builtin provider:

from valid8r.prompt.io_provider import BuiltinIOProvider
from valid8r.prompt.basic import ask
from valid8r.core.parsers import parse_int

provider = BuiltinIOProvider()
result = ask("Age: ", parser=parse_int, io_provider=provider)

Use test provider for non-interactive testing:

from valid8r.prompt.io_provider import TestIOProvider

test_provider = TestIOProvider(inputs=["25"])
result = ask("Age: ", parser=parse_int, io_provider=test_provider)
# result.value_or(0) == 25
# test_provider.outputs == []
# test_provider.errors == []
input(prompt)[source]

Display prompt and get user input.

Parameters:

prompt (str) – The prompt message to display to the user

Returns:

The user’s input as a string

Return type:

str

output(message)[source]

Display an output message to the user.

Parameters:

message (str) – The message to display

Return type:

None

error(message)[source]

Display an error message to the user.

Parameters:

message (str) – The error message to display

Return type:

None

class valid8r.prompt.io_provider.BuiltinIOProvider[source]

Default IO provider using Python builtins (input/print).

This provider delegates to Python’s built-in input() and print() functions, providing standard command-line interaction behavior.

Examples:

from valid8r.prompt.io_provider import BuiltinIOProvider
provider = BuiltinIOProvider()

# Input from user
user_input = provider.input("Name: ")  # Uses input()

# Output to console
provider.output("Hello!")  # Uses print()

# Error to console
provider.error("Invalid input")  # Uses print()
input(prompt)[source]

Display prompt using builtins.input.

Parameters:

prompt (str) – The prompt message to display

Returns:

The user’s input string

Return type:

str

output(message)[source]

Display output using builtins.print.

Parameters:

message (str) – The message to display

Return type:

None

error(message)[source]

Display error using builtins.print.

Parameters:

message (str) – The error message to display

Return type:

None

class valid8r.prompt.io_provider.TestIOProvider(inputs)[source]

IO provider for testing that captures I/O without builtins.

This provider allows testing prompt functions without monkeypatching builtins.input and builtins.print. It provides pre-configured inputs and captures all outputs and errors for inspection.

Parameters:

inputs (list[str])

inputs[source]

List of input strings to return (consumed in order)

outputs[source]

List of captured output messages

errors[source]

List of captured error messages

Examples

>>> from valid8r.prompt.io_provider import TestIOProvider
>>> from valid8r.prompt.basic import ask
>>> from valid8r.core.parsers import parse_int
>>>
>>> # Set up test provider with simulated inputs
>>> provider = TestIOProvider(inputs=["42", "invalid", "25"])
>>>
>>> # First call returns "42"
>>> result1 = ask("Age: ", parser=parse_int, io_provider=provider)
>>> # result1.value_or(0) == 42
>>>
>>> # Second call with retry consumes "invalid" then "25"
>>> result2 = ask("Age: ", parser=parse_int, retry=1, io_provider=provider)
>>> # result2.value_or(0) == 25
>>>
>>> # Inspect captured output
>>> len(provider.errors)  # 1 error for "invalid"
1
>>> len(provider.outputs)  # No outputs
0
inputs[source]
outputs: list[str] = [][source]
errors: list[str] = [][source]
input(prompt)[source]

Return next simulated input.

Parameters:

prompt (str) – The prompt message (ignored but required by protocol)

Returns:

Next input from the inputs list

Return type:

str

Raises:

RuntimeError – If all inputs have been consumed

output(message)[source]

Capture output message.

Parameters:

message (str) – The output message to capture

Return type:

None

error(message)[source]

Capture error message.

Parameters:

message (str) – The error message to capture

Return type:

None