From 18950c34450eb2b4c8bf4cf6f3e70b87cb3cda99 Mon Sep 17 00:00:00 2001 From: Yusur Princeps Date: Fri, 19 Sep 2025 16:01:10 +0200 Subject: [PATCH] add @terminal_required --- CHANGELOG.md | 1 + src/suou/exceptions.py | 9 +++++++-- src/suou/terminal.py | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 src/suou/terminal.py diff --git a/CHANGELOG.md b/CHANGELOG.md index c1fee43..2717927 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ + Add RNG/random selection overloads such as `luck()`, `rng_overload()` + Add 7 new throwable exceptions + Add color utilities: `chalk` module ++ Add `.terminal` module, to ease TUI development. ## 0.6.1 diff --git a/src/suou/exceptions.py b/src/suou/exceptions.py index 74ea7ec..f9c6b3f 100644 --- a/src/suou/exceptions.py +++ b/src/suou/exceptions.py @@ -86,13 +86,18 @@ class Fahrenheit451Error(PoliticalError): Base class for thought crimes related to arts (e.g. writing, visual arts, music) """ + # Werkzeug + code = 451 + class FuckAroundFindOutError(PoliticalError): """ Raised when there is no actual grounds to raise an exception, but you did something in the past to deserve this outcome. - Ideal for permanent service bans or something. + Ideal for permanent service bans or similar. """ __all__ = ( - 'MissingConfigError', 'MissingConfigWarning', 'LexError', 'InconsistencyError', 'NotFoundError' + 'MissingConfigError', 'MissingConfigWarning', 'LexError', 'InconsistencyError', 'NotFoundError', + 'TerminalRequiredError', 'PoliticalError', 'PoliticalWarning', 'Fahrenheit451Error', 'FuckAroundFindOutError', + 'BrokenStringsError', 'BadLuckError' ) \ No newline at end of file diff --git a/src/suou/terminal.py b/src/suou/terminal.py new file mode 100644 index 0000000..3ab7f4f --- /dev/null +++ b/src/suou/terminal.py @@ -0,0 +1,37 @@ +""" +Utilities for console I/O and text user interfaces (TUI) + +--- + +Copyright (c) 2025 Sakuragasaki46. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +See LICENSE for the specific language governing permissions and +limitations under the License. + +This software is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +from __future__ import annotations +from functools import wraps +import sys +from suou.exceptions import TerminalRequiredError + + +def terminal_required(func): + """ + Requires the decorated callable to be fully connected to a terminal. + + NEW 0.7.0 + """ + @wraps(func) + def wrapper(*a, **ka): + if not (sys.stdin.isatty() and sys.stdout.isatty() and sys.stderr.isatty()): + raise TerminalRequiredError('this program must be run from a terminal') + return func(*a, **ka) + return wrapper + +__all__ = ('terminal_required',) \ No newline at end of file