Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
61e6a64
Unify all error messages & add a new option to allow the space separa…
xulbux May 7, 2026
881ae5b
Add better typing for the arg values `.get()` method
xulbux May 7, 2026
015ceb6
Follow no-single-letter-names everywhere, remove redundant format cod…
xulbux May 10, 2026
24a8621
Performance improvements for `Console.log()`, `Data.remove_duplicates…
xulbux May 12, 2026
0c5aa16
Improve the `ProgressBar` style
xulbux May 13, 2026
4e5144e
Performance improvements for `FormatCodes` class
xulbux May 13, 2026
a242f2b
Restructure `FormatCodes.to_ansi()` as it was getting too complex
xulbux May 13, 2026
e12c62d
Add a new `skip` param to `Console.get_args()` and new props to the `…
xulbux May 13, 2026
2de8e09
Added new `unknown_flags` attr to `ParsedArgs` and changed the type o…
xulbux May 14, 2026
2fc32b3
Exclude `./build` folder from linting
xulbux May 14, 2026
04b236b
No longer force the `Console.log()` title to be all uppercase
xulbux May 15, 2026
5819bb1
Use the rendered title length for tab size calculation in `Console.lo…
xulbux May 15, 2026
cc01edf
Improve inline `is not None` if-statements and start fixing `E501 lin…
xulbux May 15, 2026
ba1a724
Continue fixing `E501 line too long`
xulbux May 15, 2026
75b3802
wip: Completely rework the formatting API and mark the old one as dep…
xulbux May 15, 2026
9901b24
wip: Completely rework the formatting API and mark the old one as dep…
xulbux May 15, 2026
6508f2a
Remove `xulbux-lib fc` CLI command, use the new `FC` API inside the l…
xulbux May 16, 2026
9b650ad
`F.link(…)` bugfix
xulbux May 16, 2026
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
4 changes: 2 additions & 2 deletions .github/workflows/test-and-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ jobs:

- name: Lint with flake8
run: |
python -m flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
python -m flake8 . --exit-zero --max-complexity=12 --statistics
python -m flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=build
python -m flake8 . --exit-zero --max-complexity=12 --statistics --exclude=build

- name: Type check with pyright
run: |
Expand Down
24 changes: 12 additions & 12 deletions .style.yapf
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
[style]
ALLOW_SPLIT_BEFORE_DICT_VALUE = true
BASED_ON_STYLE = pep8
BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF = 1
BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES = 2
COALESCE_BRACKETS = true
COLUMN_LIMIT = 127
ALLOW_SPLIT_BEFORE_DICT_VALUE = true
SPLIT_BEFORE_FIRST_ARGUMENT = true
SPLIT_BEFORE_LOGICAL_OPERATOR = true
SPLIT_BEFORE_BITWISE_OPERATOR = true
SPLIT_BEFORE_ARITHMETIC_OPERATOR = true
SPLIT_BEFORE_DOT = true
SPLIT_COMPLEX_COMPREHENSION = false
DEDENT_CLOSING_BRACKETS = true
INDENT_CLOSING_BRACKETS = false
COALESCE_BRACKETS = true
EACH_DICT_ENTRY_ON_SEPARATE_LINE = false
BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES = 2
DISABLE_SPLIT_LIST_WITH_COMMENT = true
EACH_DICT_ENTRY_ON_SEPARATE_LINE = false
INDENT_CLOSING_BRACKETS = false
SPACES_AROUND_SUBSCRIPT_COLON = false
SPACES_BEFORE_COMMENT = 2
BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF = 1
SPLIT_BEFORE_ARITHMETIC_OPERATOR = true
SPLIT_BEFORE_BITWISE_OPERATOR = true
SPLIT_BEFORE_DOT = true
SPLIT_BEFORE_FIRST_ARGUMENT = true
SPLIT_BEFORE_LOGICAL_OPERATOR = true
SPLIT_COMPLEX_COMPREHENSION = false
1,143 changes: 609 additions & 534 deletions CHANGELOG.md

Large diffs are not rendered by default.

31 changes: 18 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![](https://img.shields.io/pypi/v/xulbux?style=flat&labelColor=404560&color=7075FF)](https://pypi.org/project/xulbux) [![](https://img.shields.io/pepy/dt/xulbux?style=flat&labelColor=404560&color=7075FF)](https://clickpy.clickhouse.com/dashboard/xulbux) [![](https://img.shields.io/github/license/xulbux/python-lib-xulbux?style=flat&labelColor=405555&color=70FFEE)](https://github.com/xulbux/python-lib-xulbux/blob/main/LICENSE) [![](https://img.shields.io/github/last-commit/xulbux/python-lib-xulbux?style=flat&labelColor=554045&color=FF6065)](https://github.com/xulbux/python-lib-xulbux/commits) [![](https://img.shields.io/github/issues/xulbux/python-lib-xulbux?style=flat&labelColor=554045&color=FF6065)](https://github.com/xulbux/python-lib-xulbux/issues) [![](https://img.shields.io/github/stars/xulbux/python-lib-xulbux?label=★&style=flat&labelColor=604A40&color=FF9673)](https://github.com/xulbux/python-lib-xulbux/stargazers)

**`xulbux`** is a library that contains many useful classes, types, and functions,
ranging from console logging and working with colors to file management and system operations.
ranging from terminal logging and working with colors to file management and system operations.
The library is designed to simplify common programming tasks and improve code readability through its collection of tools.

For precise information about the library, see the library's [**documentation**](https://github.com/xulbux/python-lib-xulbux/wiki).<br>
Expand All @@ -17,39 +17,42 @@ For the libraries latest changes and updates, see the [**change log**](https://g

## Installation

Run the following commands in a console with administrator privileges, so the actions take effect for all users.
Run the following commands in a terminal with administrator privileges, so the actions take effect for all users.

Install the library and all its dependencies with the command:
```console

```shell
pip install xulbux
```

Upgrade the library and all its dependencies to their latest available version with the command:
```console

```shell
pip install --upgrade xulbux
```

<br>

## CLI Commands

When the library is installed, the following commands are available in the console:
When the library is installed, the following commands are available in the terminal:

| Command | Description |
| :---------------- | :--------------------------------------------------------------- |
| `xulbux-lib` | Show some information about the library. |
| `xulbux-lib fc` | Parse and render a string's format codes as ANSI console output. |
| Command | Description |
| :----------- | :--------------------------------------- |
| `xulbux-lib` | Show some information about the library. |

<br>

## Usage

Import the full library under the alias `xx`, so its modules and main classes are accessible with `xx.module.Class`, `xx.MainClass.method()`:

```python
import xulbux as xx
```

So you don't have to import the full library under an alias, you can also import only certain parts of the library's contents:

```python
# LIBRARY SUB MODULES
from xulbux.base.consts import COLOR, CHARS, ANSI
Expand Down Expand Up @@ -104,12 +107,12 @@ from xulbux.color import rgba, hsla, hexa
</tr>
<tr>
<td><a href="https://github.com/xulbux/python-lib-xulbux/wiki/color"><img src="https://img.shields.io/badge/color-B272FC?style=for-the-badge" alt="color"></a></td>
<td><code>rgba</code><code>hsla</code><code>hexa</code><code>Color</code> classes, which include methods to work with<br>
<td><code>rgba</code> <code>hsla</code> <code>hexa</code> <code>Color</code> classes, which include methods to work with<br>
colors in various formats.</td>
</tr>
<tr>
<td><a href="https://github.com/xulbux/python-lib-xulbux/wiki/console"><img src="https://img.shields.io/badge/console-B272FC?style=for-the-badge" alt="console"></a></td>
<td><code>Console</code><code>ProgressBar</code> classes, which include methods for logging<br>
<td><code>Console</code> <code>ProgressBar</code> classes, which include methods for logging<br>
and other actions within the console.</td>
</tr>
<tr>
Expand All @@ -130,8 +133,9 @@ from xulbux.color import rgba, hsla, hexa
</tr>
<tr>
<td><a href="https://github.com/xulbux/python-lib-xulbux/wiki/format_codes"><img src="https://img.shields.io/badge/format__codes-B272FC?style=for-the-badge" alt="format_codes"></a></td>
<td><code>FormatCodes</code> class, which includes methods to print and work with strings that contain<br>
special formatting codes, which are then converted to ANSI codes for pretty console output.</td>
<td><code>Format</code> (<i>alias</i> <code>F</code>) <code>FormatCodes</code> (<i>alias</i> <code>FC</code>) <code>Term</code> classes for building richly formatted<br>
terminal output via a typed, operator-based syntax and for emitting common cursor- and<br>
screen-control sequences.</td>
</tr>
<tr>
<td><a href="https://github.com/xulbux/python-lib-xulbux/wiki/json"><img src="https://img.shields.io/badge/json-B272FC?style=for-the-badge" alt="json"></a></td>
Expand Down Expand Up @@ -159,6 +163,7 @@ from xulbux.color import rgba, hsla, hexa
## Example Usage

This is what it could look like using this library for a simple but ultra good-looking color converter:

```python
from xulbux.base.consts import COLOR, CHARS
from xulbux.color import hexa
Expand Down
27 changes: 9 additions & 18 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ requires = [
"mypy>=1.19.0",
"mypy-extensions>=1.1.0",
# TYPES FOR MyPy
"types-setuptools",
"types-regex",
"types-toml",
"prompt_toolkit>=3.0.41",
]
build-backend = "setuptools.build_meta"

[project]
name = "xulbux"
version = "1.9.7"
version = "1.9.8"
description = "A Python library to simplify common programming tasks."
readme = "README.md"
authors = [{ name = "XulbuX", email = "xulbux.real@gmail.com" }]
Expand Down Expand Up @@ -117,7 +119,11 @@ max-complexity = 12
max-line-length = 127
select = ["E", "F", "W", "C90"]
extend-ignore = ["E124", "E203", "E266", "E502", "W503"]
per-file-ignores = ["__init__.py:F403,F405", "types.py:E302,E305"]
per-file-ignores = [
"__init__.py:F403,F405",
"src/xulbux/base/types.py:E302,E305",
"src/xulbux/cli/help.py:E501",
]

[tool.setuptools]
package-dir = { "" = "src" }
Expand All @@ -132,22 +138,7 @@ xulbux = ["py.typed", "*.pyi", "**/*.pyi"]
minversion = "7.0"
addopts = "-ra -q"
pythonpath = ["src"]
testpaths = [
"tests/test_code.py",
"tests/test_color_types.py",
"tests/test_color.py",
"tests/test_console.py",
"tests/test_data.py",
"tests/test_env_path.py",
"tests/test_file_sys.py",
"tests/test_file.py",
"tests/test_format_codes.py",
"tests/test_json.py",
"tests/test_metadata_consistency.py",
"tests/test_regex.py",
"tests/test_string.py",
"tests/test_system.py",
]
testpaths = ["tests/test_*.py"]

[tool.pyright]
include = ["src", "tests"]
Expand Down
14 changes: 10 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ def generate_stubs_for_package():

print(f"\nStub generation complete. ({generated_count} generated, {skipped_count} copied)\n")

except Exception as e:
fmt_error = "\n ".join(str(e).splitlines())
except Exception as exc:
fmt_error = "\n ".join(str(exc).splitlines())
print(f"[WARNING] Could not generate stubs:\n {fmt_error}\n")


Expand All @@ -73,8 +73,13 @@ def delete_project_stub_files():

ext_modules = []

# ONLY COMPILE AND GENERATE STUBS WHEN ACTUALLY BUILDING, NOT DURING METADATA-ONLY
# PHASES (egg_info, dist_info) THAT PIP INVOKES AS PART OF PEP 517 PREPARATION.
_BUILD_COMMANDS = {"bdist_wheel", "build_ext", "build", "develop", "editable_wheel", "install"}
_is_building = bool(set(sys.argv[1:]) & _BUILD_COMMANDS)

# OPTIONALLY USE MYPYC COMPILATION
if os.environ.get("XULBUX_USE_MYPYC", "1") == "1":
if os.environ.get("XULBUX_USE_MYPYC", "1") == "1" and _is_building:
try:
from mypyc.build import mypycify

Expand All @@ -97,4 +102,5 @@ def delete_project_stub_files():
ext_modules=ext_modules,
)

delete_project_stub_files()
if _is_building:
delete_project_stub_files()
4 changes: 3 additions & 1 deletion src/xulbux/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__package_name__ = "xulbux"
__version__ = "1.9.7"
__version__ = "1.9.8"
__description__ = "A Python library to simplify common programming tasks."
__status__ = "Production/Stable"

Expand All @@ -25,6 +25,7 @@
"File",
"FileSys",
"FormatCodes",
"deprFormatCodes",
"Json",
"Regex",
"String",
Expand All @@ -39,6 +40,7 @@
from .file import File
from .file_sys import FileSys
from .format_codes import FormatCodes
from .depr_format_codes import deprFormatCodes
from .json import Json
from .regex import Regex
from .string import String
Expand Down
43 changes: 22 additions & 21 deletions src/xulbux/base/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,26 +80,32 @@ class ANSI:
"""Printable ANSI escape character."""
CHAR: Final = "\x1b"
"""ANSI escape character."""

START: Final = "["
"""Start of an ANSI escape sequence."""
"""**DEPRECATED** – only used by `depr_format_codes`. Will be removed together with that module.\n
Start of an ANSI escape sequence."""
SEP: Final = ";"
"""Separator between ANSI escape sequence parts."""
"""**DEPRECATED** – only used by `depr_format_codes`. Will be removed together with that module.\n
Separator between ANSI escape sequence parts."""
END: Final = "m"
"""End of an ANSI escape sequence."""
"""**DEPRECATED** – only used by `depr_format_codes`. Will be removed together with that module.\n
End of an ANSI escape sequence."""

@classmethod
def seq(cls, placeholders: int = 1, /) -> FormattableString:
"""Generates an ANSI escape sequence with the specified number of placeholders."""
"""**DEPRECATED** – only used by `depr_format_codes`. Will be removed together with that module.\n
Generates an ANSI escape sequence with the specified number of placeholders."""

return cls.CHAR + cls.START + cls.SEP.join(["{}" for _ in range(placeholders)]) + cls.END

SEQ_COLOR: Final[FormattableString] = CHAR + START + "38" + SEP + "2" + SEP + "{}" + SEP + "{}" + SEP + "{}" + END
"""ANSI escape sequence with three placeholders for setting the RGB text color."""
SEQ_BG_COLOR: Final[FormattableString] = CHAR + START + "48" + SEP + "2" + SEP + "{}" + SEP + "{}" + SEP + "{}" + END
"""ANSI escape sequence with three placeholders for setting the RGB background color."""
SEQ_FG_COLOR: Final[FormattableString] = f"{CHAR}[38;2;{{}};{{}};{{}}m"
"""RGB foreground color sequence with placeholders for red, green, and blue values."""
SEQ_BG_COLOR: Final[FormattableString] = f"{CHAR}[48;2;{{}};{{}};{{}}m"
"""RGB background color sequence with placeholders for red, green, and blue values."""

SEQ_LINK_OPEN: Final[FormattableString] = CHAR + "]8;;{}" + CHAR + "\\"
SEQ_LINK_OPEN: Final[FormattableString] = f"{CHAR}]8;;{{}}{CHAR}\\"
"""OSC 8 hyperlink opening sequence with a placeholder for the URL."""
SEQ_LINK_CLOSE: Final[str] = CHAR + "]8;;" + CHAR + "\\"
SEQ_LINK_CLOSE: Final[str] = f"{CHAR}]8;;{CHAR}\\"
"""OSC 8 hyperlink closing sequence."""

COLOR_MAP: Final[set[str]] = {
Expand All @@ -112,7 +118,8 @@ def seq(cls, placeholders: int = 1, /) -> FormattableString:
"cyan",
"white",
}
"""The standard terminal color names."""
"""**DEPRECATED** – only used by `depr_format_codes`. Will be removed together with that module.\n
The standard terminal color names."""

COLOR_VARIANTS_MAP: Final[set[str]] = COLOR_MAP | {
"br:black",
Expand All @@ -123,16 +130,9 @@ def seq(cls, placeholders: int = 1, /) -> FormattableString:
"br:magenta",
"br:cyan",
"br:white",
"bright:black",
"bright:red",
"bright:green",
"bright:yellow",
"bright:blue",
"bright:magenta",
"bright:cyan",
"bright:white",
}
"""All color variants that can be used in formatting."""
"""**DEPRECATED** – only used by `depr_format_codes`. Will be removed together with that module.\n
All color variants that can be used in formatting."""

CODES_MAP: Final[dict[str | tuple[str, ...], int]] = {
################# SPECIFIC RESETS ##################
Expand Down Expand Up @@ -193,4 +193,5 @@ def seq(cls, placeholders: int = 1, /) -> FormattableString:
"bg:br:cyan": 106,
"bg:br:white": 107,
}
"""Dictionary mapping format keys to their corresponding ANSI code numbers."""
"""**DEPRECATED** – only used by `depr_format_codes`. Will be removed together with that module.\n
Dictionary mapping format keys to their corresponding ANSI code numbers."""
5 changes: 3 additions & 2 deletions src/xulbux/base/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ def mypyc_attr(**kwargs: Any) -> Callable[[T], T]:
or acts as a no-op decorator when `mypy_extensions` is not installed.\n
This allows the use of `mypyc` compilation hints for compiling without making
`mypy_extensions` a required dependency.\n
-----------------------------------------------------------------------------------------
- `**kwargs` -⠀keyword arguments to pass to `mypy_extensions.mypyc_attr` if available"""
-------------------------------------------------------------------------------------------
* `**kwargs` – keyword arguments to pass to `mypy_extensions.mypyc_attr` if available"""

try:
from mypy_extensions import mypyc_attr as _mypyc_attr
return _mypyc_attr(**kwargs)
Expand Down
Loading
Loading