Changed code to support older Python versions
This commit is contained in:
parent
eb92d2d36f
commit
582458cdd0
5027 changed files with 794942 additions and 4 deletions
156
venv/lib/python3.11/site-packages/rich_toolkit/input.py
Normal file
156
venv/lib/python3.11/site-packages/rich_toolkit/input.py
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Optional, Protocol
|
||||
|
||||
from ._input_handler import TextInputHandler
|
||||
|
||||
from .element import CursorOffset, Element
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .styles.base import BaseStyle
|
||||
|
||||
|
||||
class Validator(Protocol):
|
||||
"""Protocol for validators that can validate input values.
|
||||
|
||||
Any object with a validate_python method can be used as a validator.
|
||||
This includes Pydantic's TypeAdapter or custom validators.
|
||||
|
||||
Example with Pydantic TypeAdapter:
|
||||
>>> from pydantic import TypeAdapter
|
||||
>>> validator = TypeAdapter(int)
|
||||
>>> input_field = Input(validator=validator)
|
||||
|
||||
Example with custom validator:
|
||||
>>> class MyValidator:
|
||||
... def validate_python(self, value):
|
||||
... if not value.startswith("x"):
|
||||
... raise ValueError("Must start with x")
|
||||
... return value
|
||||
>>> input_field = Input(validator=MyValidator())
|
||||
"""
|
||||
|
||||
def validate_python(self, value: Any) -> Any:
|
||||
"""Validate a Python value and return the validated result.
|
||||
|
||||
Args:
|
||||
value: The value to validate
|
||||
|
||||
Returns:
|
||||
The validated value
|
||||
|
||||
Raises:
|
||||
ValidationError: If validation fails
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class Input(TextInputHandler, Element):
|
||||
label: Optional[str] = None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
label: Optional[str] = None,
|
||||
placeholder: Optional[str] = None,
|
||||
default: Optional[str] = None,
|
||||
default_as_placeholder: bool = True,
|
||||
required: bool = False,
|
||||
required_message: Optional[str] = None,
|
||||
password: bool = False,
|
||||
inline: bool = False,
|
||||
name: Optional[str] = None,
|
||||
style: Optional[BaseStyle] = None,
|
||||
validator: Optional[Validator] = None,
|
||||
**metadata: Any,
|
||||
):
|
||||
self.name = name
|
||||
self.label = label
|
||||
self._placeholder = placeholder
|
||||
self.default = default
|
||||
self.default_as_placeholder = default_as_placeholder
|
||||
self.required = required
|
||||
self.password = password
|
||||
self.inline = inline
|
||||
|
||||
self.text = ""
|
||||
self.valid = None
|
||||
self.required_message = required_message
|
||||
self._validation_message: Optional[str] = None
|
||||
self._validator: Optional[Validator] = validator
|
||||
|
||||
Element.__init__(self, style=style, metadata=metadata)
|
||||
super().__init__()
|
||||
|
||||
@property
|
||||
def placeholder(self) -> str:
|
||||
if self.default_as_placeholder and self.default:
|
||||
return self.default
|
||||
|
||||
return self._placeholder or ""
|
||||
|
||||
@property
|
||||
def validation_message(self) -> Optional[str]:
|
||||
if self._validation_message:
|
||||
return self._validation_message
|
||||
|
||||
assert self.valid
|
||||
|
||||
return None
|
||||
|
||||
@property
|
||||
def cursor_offset(self) -> CursorOffset:
|
||||
top = 1 if self.inline else 2
|
||||
|
||||
left_offset = 0
|
||||
|
||||
if self.inline and self.label:
|
||||
left_offset = len(self.label) + 1
|
||||
|
||||
return CursorOffset(top=top, left=self.cursor_left + left_offset)
|
||||
|
||||
@property
|
||||
def should_show_cursor(self) -> bool:
|
||||
return True
|
||||
|
||||
def on_blur(self):
|
||||
self.on_validate()
|
||||
|
||||
def on_validate(self):
|
||||
value = self.value.strip()
|
||||
|
||||
if not value and self.required:
|
||||
self.valid = False
|
||||
self._validation_message = self.required_message or "This field is required"
|
||||
|
||||
return
|
||||
|
||||
if self._validator:
|
||||
from pydantic import ValidationError
|
||||
|
||||
try:
|
||||
self._validator.validate_python(value)
|
||||
except ValidationError as e:
|
||||
self.valid = False
|
||||
|
||||
# Extract error message from Pydantic ValidationError
|
||||
self._validation_message = e.errors()[0].get("msg", "Validation failed")
|
||||
|
||||
return
|
||||
|
||||
self._validation_message = None
|
||||
self.valid = True
|
||||
|
||||
@property
|
||||
def value(self) -> str:
|
||||
return self.text or self.default or ""
|
||||
|
||||
def ask(self) -> str:
|
||||
from .container import Container
|
||||
|
||||
container = Container(style=self.style)
|
||||
|
||||
container.elements = [self]
|
||||
|
||||
container.run()
|
||||
|
||||
return self.value
|
||||
Loading…
Add table
Add a link
Reference in a new issue