Next-generation terminal text & UI formatting engine
Project description
Textforge
Textforge is a comprehensive terminal text and UI formatting engine designed for building console applications, GUI applications, TTY applications, and exporting to various formats (HTML, PDF, SVG). Built with Python 3.14, it provides a modular architecture with a powerful component subsystem that enables declarative UI construction with consistent styling, GPU acceleration, and cross-platform rendering.
Features
Textforge offers a complete ecosystem for terminal and GUI application development:
- Component Subsystem: 30+ reusable UI components organized into categories (containers, typography, interactive, data visualization, status indicators, navigation, visual elements, feedback, decorative) with extensible base classes for custom component development
- Styling System: TFS (Textforge Style) declarative styling with CSS-like syntax, theme support, and state-based styling
- Layout Engine: Advanced layout algorithms including flexbox, grid, and absolute positioning with coordinate system conversion
- Multi-Renderer Support: Native rendering for CLI, TTY, GUI backends (Win32, Cocoa, GTK), and export formats (HTML, SVG, PDF, Plain text)
- Event System: Cross-subsystem event handling with propagation, filtering, and async processing
- Animation & Effects: Timeline-based animations, particle systems, and GPU acceleration
- GPU Acceleration Subsystem: Hardware-accelerated rendering with DirectX (Windows), Metal (macOS), Vulkan/OpenGL (Linux) backends and automatic CPU fallback
- Internationalization: Full Unicode support with i18n framework and RTL layout
- Accessibility: Screen reader support, keyboard navigation, and contrast checking
- Performance: Optimized with Cython compilation, memory pooling, GPU acceleration, and thread-safe operations for Python 3.14 free threading
Optimization Highlights
- Layout cache reuse: Cached flex/grid results now hydrate node layouts directly, eliminating unnecessary re-traversals during repeated measurements.
- Lean VDOM diffing: Thread-local reconcilers and prefix/suffix pruning cut allocations and comparisons during tree reconciliation.
- Markup parsing acceleration: Guarded escape handling and cached tag lookups reduce per-render allocations in the text pipeline.
- Color acceleration: Gradient results and ANSI lookups are cached, dramatically lowering the cost of repeated color operations.
- GPU manager reuse: A shared GPU manager caches shader programs and backend detection while falling back to CPU rendering when hardware acceleration is unavailable.
GUI Backend Notes
- The GUI runtime is optimised for Windows first; create a GUI console with
Console.for_backend("gui")to spawn the native window immediately. - The pipeline now schedules the very first
WM_PAINTas soon as the Win32 window becomes ready, so the demo content appears without manually resizing the window. - The render path emits
DEBUG:traces (backend selection, runtime stream activity, Win32 paint scheduling) to help diagnose lifecycle issues while developing widgets. - Mouse clicks are translated to component callbacks, so interactive components (e.g.
Button) now invoke their registered handlers inside the desktop window. - Pointer interaction currently supports basic click dispatch; gesture handling and hover/drag feedback are planned follow-ups.
Quick Start
from textforge import TextForgeAPI
api = TextForgeAPI()
# Build a component tree declaratively
headline = api.create_component("title", text="System Status", level=2)
details = api.create_component("paragraph", text="All systems are nominal.")
action = api.create_component("button", label="Restart")
layout = api.create_component(
"box",
children=[headline, details, action],
)
# Render to the terminal
print(api.render(layout))
# Export directly to HTML
html_markup = api.render(layout, target="html")
CLI Utilities
Textforge ships with a small CLI toolkit for scaffolding demos and previewing effects. Install Textforge on your PATH and use:
textforge new demo_app --dir ./samplesto create a ready-to-run scaffold containing amain.pythat renders basic components.textforge typewriter "Hello, Textforge!" --delay 0.02 --color primaryto preview the typewriter animation effect directly in your terminal with configurable pacing and optional theme-aware colouring.
Component Architecture
Textforge's component subsystem provides a hierarchical, composable architecture for building complex UIs:
Component Categories
- Containers:
Box,Panel,Card,Dialog- Layout and grouping components - Typography:
Text,Title,Paragraph,List- Text formatting and structure - Interactive:
Button,Checkbox,Slider,Form- User input components - Data:
Table,Chart,Progress- Data visualization components - Status:
Spinner,ProgressBar,Gauge,Meter- Status and progress indicators - Navigation:
Menu,Tabs,Breadcrumbs- Navigation components - Visual:
Canvas,Graph,Image- Visual rendering components - Feedback:
Alert,Toast,Snackbar- User feedback components - Decorative:
Banner,Divider,AsciiArt- Visual enhancement components - Layout:
Columns,Grid,Flex- Layout management components
Component Usage
from textforge import components as C
# Create a dashboard layout
dashboard = C.box(
title="System Monitor",
children=[
C.columns([
C.panel("CPU Usage", children=[
C.progress_bar(current=65, maximum=100, label="CPU", color="red")
]),
C.panel("Memory", children=[
C.gauge(value=0.8, label="RAM", color="blue")
])
]),
C.divider(),
C.table(
headers=["Process", "CPU%", "Memory"],
rows=[
["python.exe", "15.2%", "245MB"],
["chrome.exe", "8.7%", "180MB"],
["vscode.exe", "12.1%", "320MB"]
]
)
]
)
tfprint(dashboard)
Component Foundation
The component subsystem foundation delivers thread-safe primitives that every custom component can rely on:
Component: abstract logical component with DEBUG-level creation logging, validation helpers, and RLock-protected state updates.RenderableComponent: dataclass that caches resolved TFS styles, wraps rendering and measurement calls with TRACE-level logging, and exposes ato_node()helper for GUI conversions.- GUI conversion now propagates container children and component metadata into
GuiNodeinstances, so the GUI renderer can draw boxes, panels, text, buttons, and progress indicators without manual wiring. ContainerBaseandContainerRenderable: utilities for building compositional components while automatically converting logical children to renderables under a shared styling context.- Helper functions like
box()andpanel()provide immediate access to pre-built container renderables without exposing legacy constructors. - Protocols in
textforge.components.typesdescribe the component and renderable interfaces, simplifying integration and static analysis.
from textforge.components import Component, ContainerBase, RenderableComponent, box
from textforge.core.console import Measure, Console
from textforge.style.subsystem import StylingContext
class Badge(Component):
"""Simple text badge that demonstrates style caching."""
def __init__(self, label: str) -> None:
self._label = label
@property
def component_name(self) -> str:
return "badge"
def to_renderable(self, styling_context: StylingContext | None = None) -> RenderableComponent:
context = styling_context or StylingContext(component_name=self.component_name)
class _BadgeRenderable(RenderableComponent):
def __init__(self, label: str, **kwargs: object) -> None:
super().__init__(**kwargs)
self._label = label
def render(self, console: Console) -> str:
self.get_resolved_style() # style cached behind the scenes
return self._label
def measure(self, console: Console) -> Measure:
return Measure.from_text(self._label)
return _BadgeRenderable(
label=self._label,
component_name=self.component_name,
styling_context=context,
)
# Compose helpers and custom components
header = box("System Status")
badge_component = Badge("Healthy")
container = ContainerBase(children=(badge_component,))
renderable_container = container.to_renderable()
Styling System
Textforge uses TFS (Textforge Style), a declarative styling language similar to CSS:
Built-in themes ship alongside the engine (defaults.tfs, dark.tfs, and light.tfs).
Place additional .tfs files in textforge/style/assets/custom/ and load them with
StyleEngine.load_stylesheet() to extend styling.
/* Component selectors with state pseudo-classes */
Button {
padding: 1 3;
border: 1px solid primary;
border-radius: 4px;
background: surface;
color: text;
}
Button:hover {
background: primary-dark;
transform: scale(1.05);
}
Button:focus {
outline: 2px solid accent;
box-shadow: 0px 0px 8px primary;
}
/* Responsive layouts */
@media (max-width: 80) {
.responsive-grid {
display: flex;
flex-direction: column;
}
}
Event Subsystem
Textforge's event subsystem delivers a unified, thread-safe pipeline for reacting to user input, component lifecycle changes, and cross-subsystem notifications. The subsystem provides:
- A global event bus that coordinates messages between subsystems.
- Dedicated subsystem buses for isolating component, layout, and renderer concerns.
- Filter and handler managers for transforming or short-circuiting events before propagation.
- An asynchronous processor that safely dispatches events across Python 3.14's free-threaded runtime.
- Recording and replay utilities for diagnostics and regression analysis.
- Platform handlers (Windows, macOS, Linux, CLI) that normalize keyboard and terminal resize signals without external dependencies.
from textforge.events import Event, EventSubsystem, EventType, SubsystemEventBus
subsystem = EventSubsystem()
# Register a subsystem bus
render_bus = SubsystemEventBus("rendering")
render_bus.subscribe(EventType.RENDER_FRAME.value, lambda event: print("frame rendered"))
subsystem.register_subsystem("rendering", render_bus)
# Add a global handler that validates events before propagation
def audit_event(event: Event) -> bool:
if event.type is EventType.STYLE_INVALIDATED:
return True # stop propagation when a conflicting style change is detected
return False
subsystem.register_handler(EventType.RENDER_FRAME, audit_event)
# Dispatch events synchronously or asynchronously
subsystem.dispatch_event(Event(type=EventType.RENDER_FRAME, data=None))
subsystem.dispatch_event_async(Event(type=EventType.TICK, data=None))
# Capture platform events from the CLI handler
subsystem.start_platform_event_loop()
subsystem.pump_platform_events()
Styling Subsystem Runtime API
The styling subsystem is exposed through textforge.style and provides a
thread-safe cache around the TFS engine. Components can resolve styles at
runtime without touching global state directly:
from textforge.style import resolve_component_style
# Resolve the default Button style
style = resolve_component_style("Button", state={"default": True})
print(style.background) # surface
# Apply theme overrides at call time
override_style = resolve_component_style(
"Button",
state={"default": True},
theme_overrides={"surface": "#222244"},
)
Built-in themes (defaults, dark, light) are located in
textforge/style/themes. The subsystem supports live theme switching and
runtime stylesheet loading for application specific branding:
from textforge.style import get_styling_subsystem
styling = get_styling_subsystem()
styling.set_theme("dark")
styling.load_stylesheet_text(
"product-branding",
"""
Banner {
[default] { background: #112233; color: #f0f6ff; }
}
""",
)
All styling goes through the TFS pipeline—there is no fallback styling path.
API Reference
Core API
from textforge import (
TextForgeAPI,
create_component,
export_html,
export_pdf,
export_svg,
render,
)
api = TextForgeAPI()
# Create components via the API instance or the module-level helper
title = api.create_component("title", text="Operations Dashboard")
summary = create_component("paragraph", text="Live view of infrastructure state.")
view = api.create_component("panel", children=[title, summary])
# Render to the terminal (string output)
cli_output = render(view)
# Export with built-in helpers
html_output = export_html(view)
pdf_bytes = export_pdf(view)
svg_output = export_svg(view, font_family="Fira Code", font_size=16)
Component Factory Functions
All components are available through the components module:
import textforge.components as C
# Typography
title = C.title("Main Title", level=1)
paragraph = C.paragraph("Content text")
list_items = C.list(["Item 1", "Item 2", "Item 3"])
# Containers
box = C.box("Content")
panel = C.panel("Multi-section content")
card = C.card("Structured information")
dialog = C.dialog("Modal message")
# Interactive
button = C.button("Action", on_click=callback)
checkbox = C.checkbox("Option", checked=True)
slider = C.slider(min=0, max=100, value=50)
form = C.form(fields=[...])
# Data Visualization
table = C.table(headers=["A", "B"], rows=[["1", "2"]])
chart = C.chart.bar_chart(data={"Jan": 10, "Feb": 15})
progress = C.progress_bar(current=75, maximum=100)
# Status Indicators
spinner = C.spinner("Loading...")
gauge = C.gauge(value=0.8, label="Usage")
meter = C.meter(value=65, label="Score")
# Navigation
menu = C.menu(options=["Option 1", "Option 2"])
tabs = C.tabs(tabs=["Tab 1", "Tab 2"], active=0)
breadcrumbs = C.breadcrumbs(path=["Home", "Section", "Page"])
# Visual Elements
canvas = C.canvas(width=80, height=24)
graph = C.graph(data_points=[1, 3, 2, 5, 4])
image = C.image(path="image.pgm")
# Feedback
alert = C.alert("Warning message", type="warning")
toast = C.toast("Notification")
snackbar = C.snackbar("Action completed")
# Decorative
banner = C.banner("TEXTFORGE", font="block")
divider = C.divider(char="─", length=40)
ascii_art = C.ascii_art("Custom text", font="small")
# Layout
columns = C.columns([comp1, comp2, comp3])
grid = C.grid(items=[[comp1, comp2], [comp3, comp4]])
flex = C.flex(children=[comp1, comp2], direction="row")
GPU Acceleration API
Textforge provides hardware-accelerated rendering through its GPU subsystem:
from textforge.gpu import GPUManager, Shader
# Initialize GPU manager (automatic backend detection)
gpu_manager = GPUManager()
if gpu_manager.is_available():
# Create and compile shaders
vertex_shader = gpu_manager.load_shader("vertex", "vertex_shader.glsl")
fragment_shader = gpu_manager.load_shader("fragment", "fragment_shader.glsl")
# Create shader program
shader = gpu_manager.create_shader("component_shader", vertex_shader, fragment_shader)
# Render component with GPU acceleration
geometry = component_to_gpu_geometry(component)
gpu_manager.render_geometry(geometry, shader)
print("Rendered with GPU acceleration")
else:
print("GPU acceleration not available, falling back to CPU rendering")
GPU Backend Support
Textforge automatically detects and uses the best available GPU backend:
- Windows: DirectX 11/12 (primary), Vulkan/OpenGL (fallback)
- macOS: Metal (primary), Vulkan/OpenGL (fallback)
- Linux: Vulkan (primary), OpenGL (fallback)
Shader Language Support
// Example vertex shader (GLSL)
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main() {
gl_Position = projection * view * model * vec4(aPos, 1.0);
TexCoord = aTexCoord;
}
GPU-Accelerated Rendering
from textforge.renderers import render_with_gpu_acceleration
# Render component with automatic GPU detection and fallback
output = render_with_gpu_acceleration(component, renderer_type="gui")
Component Base Classes
For advanced usage, Textforge provides base classes for creating custom components:
from textforge.components import Component, ContainerBase, TypographyBase, InteractiveBase
# Base classes for different component types:
# - Component: Abstract base for all components
# - ContainerBase: For components that can contain other components
# - TypographyBase: For text formatting components
# - InteractiveBase: For user interaction components
# - LayoutBase: For layout management components
# - DataBase: For data display components
# - StatusBase: For status indicator components
# - NavigationBase: For navigation components
# - VisualBase: For visual rendering components
# - FeedbackBase: For user feedback components
# - DecorativeBase: For decorative components
# Example: Creating a custom interactive component
class CustomButton(InteractiveBase):
@property
def component_name(self) -> str:
return "CustomButton"
def __init__(self, text: str, on_click=None):
self.text = text
self.on_click = on_click
def to_renderable(self, styling_context=None):
# Implementation for converting to renderable
pass
Supported Platforms
Textforge is designed for cross-platform compatibility with optimized support for:
-
Windows (Primary development platform)
- Win32 GUI backend with DirectX GPU acceleration
- Windows Terminal and legacy console support
- Windows Subsystem for Linux (WSL) compatibility
- DirectX 11/12 shader support with automatic Vulkan/OpenGL fallback
-
macOS
- Cocoa GUI backend with Metal GPU acceleration
- Native macOS terminal support
- Full Unicode and emoji rendering
- Metal shader support with automatic Vulkan/OpenGL fallback
-
Linux
- GTK GUI backend with Vulkan/OpenGL GPU acceleration
- Linux terminal and TTY support
- Systemd integration capabilities
- Vulkan shader support with OpenGL fallback
GPU Acceleration Backends
Textforge includes a comprehensive GPU acceleration subsystem with automatic backend detection:
- DirectX (Windows): DirectX 11/12 with HLSL shader support
- Metal (macOS): Metal API with MSL shader support
- Vulkan (Cross-platform): Vulkan 1.1+ with SPIR-V shader support
- OpenGL (Fallback): OpenGL 3.3+ with GLSL shader support
- CPU Fallback: Software rasterization when GPU acceleration unavailable
All GPU backends support vertex and fragment shaders, uniform buffers, and hardware-accelerated rendering with automatic CPU fallback for compatibility.
Requirements
- Python: 3.14 or higher (required for free threading support)
- Dependencies:
mypy>=1.18.2- Type checkingruff>=0.14.2- Linting and formatting
- Optional Dependencies:
colorama>=0.4.6- Legacy Windows console supportipython>=8- Jupyter notebook integration
Installation
pip install textforge-tf
For development with optional dependencies:
pip install textforge-tf[legacy_windows,jupyter]
CLI Usage
Textforge includes a comprehensive CLI for development and testing:
# Component gallery and demos
textforge demo --preset dashboard
textforge demo --preset all
# Theme management
textforge theme list
textforge theme preview dark
# Export functionality
textforge export -f html component.tf > output.html
textforge export -f svg component.tf > output.svg
# Development tools
textforge preview README.md
textforge new my-project
textforge bench --component box
Examples
Dashboard Application
from textforge import components as C, Console
def create_dashboard():
return C.box(
title="System Dashboard",
children=[
C.columns([
C.card(
title="CPU Usage",
content=C.progress_bar(65, 100, "CPU", "red")
),
C.card(
title="Memory",
content=C.gauge(0.8, "RAM", "blue")
),
C.card(
title="Disk I/O",
content=C.chart.bar_chart({"Read": 45, "Write": 23})
)
]),
C.divider(),
C.table(
headers=["Service", "Status", "Uptime"],
rows=[
["Web Server", "🟢 Running", "15d 8h"],
["Database", "🟢 Running", "30d 12h"],
["Cache", "🟡 Warning", "2d 6h"]
]
)
]
)
console = Console()
dashboard = create_dashboard()
console.print(dashboard)
Interactive Form
from textforge import components as C
def create_login_form():
return C.dialog(
title="Login",
content=C.form([
{"name": "username", "label": "Username", "type": "text"},
{"name": "password", "label": "Password", "type": "password"},
{"name": "remember", "label": "Remember me", "type": "checkbox"}
]),
buttons=[
C.button("Cancel", variant="secondary"),
C.button("Login", variant="primary", on_click=handle_login)
]
)
Architecture Overview
Textforge follows a strict subsystem architecture with unidirectional data flow:
Component → Styling → Layout → Rendering → Event
Subsystems
- Component Subsystem: Declarative component definitions, composition, and extensible base classes for custom component development
- Styling Subsystem: TFS parsing, cascading, and theme resolution
- Layout Subsystem: Flexbox, grid, and absolute positioning algorithms
- Rendering Subsystem: Multi-backend rendering (CLI, GUI, export formats)
- Event Subsystem: Cross-subsystem event handling and propagation
- Animation Subsystem: Timeline-based animations and effects
- Particle Subsystem: Particle effects and GPU acceleration
- Optimization Subsystem: Cython compilation and memory management
Performance
Textforge is optimized for high-performance rendering with a comprehensive optimization subsystem that provides multiple layers of performance enhancement:
Optimization Subsystem
The optimization subsystem provides advanced performance tools for production deployments:
Core Optimizations
- Function Optimization: Automatic Cython compilation with graceful fallback for performance-critical functions
- Memory Management: Object pooling and reuse for frequently allocated objects (events, patches, layouts)
- LRU Caching: Configurable caches with thread-safe eviction policies for style resolution, layout calculations, and render outputs
- Profiling Tools: Built-in profilers for function-level performance analysis with memory usage tracking
- Benchmarking Suite: Automated benchmarking with statistical analysis and performance regression detection
- Performance Monitoring: Real-time metrics collection with configurable thresholds and alerting
Advanced Features
- Reactive Computations: Event-driven reactivity system that minimizes recomputation by tracking dependencies and only updating when necessary
- Hardware Acceleration: Cross-platform SIMD operations and GPU acceleration with automatic backend detection
- Zero-Copy Operations: Memory-mapped buffers and copy-on-write data structures for efficient large data handling
- Thread-Safe Architecture: Full Python 3.14 free threading support with RLock synchronization throughout
Cython Optimizations
Textforge includes optimized Cython modules for performance-critical operations:
- Text Processing: High-performance text width calculation, truncation, and line splitting with ANSI escape sequence handling
- Layout Calculations: Optimized flexbox, grid, and bounding box computations using native math libraries
- Color Operations: SIMD-accelerated color blending, brightness adjustments, and palette operations
Usage Example
from textforge.optimization import OptimizationManager
# Initialize optimization manager
optimizer = OptimizationManager()
# Optimize a performance-critical function
@optimizer.optimize_function
def process_text_data(text: str) -> str:
return text.upper()
# Profile function performance
result = optimizer.profile_function(process_text_data, "hello world")
print(f"Execution time: {result.execution_time:.6f}s")
# Use reactive computations
reactive_value = optimizer.create_reactive_value("counter", 0)
# Changes to reactive_value automatically trigger dependent updates
# Hardware acceleration
accelerated_result = optimizer.accelerate_operation(
"vector_multiply",
[1.0, 2.0, 3.0],
other=[4.0, 5.0, 6.0]
)
Performance Characteristics
- Zero-copy operations where possible to eliminate unnecessary data copying
- Compiled optimizations via Cython for 3-10x speedup on compute-intensive tasks
- Memory pooling for frequent allocations, reducing GC pressure by 40-60%
- Thread-safe operations for Python 3.14 free threading with minimal contention
- GPU acceleration with automatic CPU fallback providing 2-5x rendering speedup
- Hardware shader support with DirectX/Metal/Vulkan/OpenGL backends
- Efficient algorithms for diffing and layout calculation using O(n) complexity
- Automatic backend detection and graceful degradation for maximum compatibility
Recent micro-optimizations (0.5.x)
- Markup engine: precompiled regexes, small per-instance output cache, and fast-path for plain text.
- Color subsystem: bounded LRU-like caches for ANSI and RGB resolution; faster inline markup application.
- VDOM reconciliation: eliminated O(n^2) child position lookups; trace logging guarded to avoid f-string overhead.
- Gradient rendering: branchless interpolation with hoisted constants for per-character coloring.
- Event dispatch (async): avoids deepcopy when
event.dataisNoneto reduce overhead. - Layout benchmarking: benchmark now exercises layout computation safely for real throughput metrics.
Contributing
Textforge follows strict coding standards and architectural principles. See AGENTS.md for detailed contribution guidelines.
License
MIT License - see pyproject.toml for license metadata.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file textforge_tf-0.7.0.tar.gz.
File metadata
- Download URL: textforge_tf-0.7.0.tar.gz
- Upload date:
- Size: 486.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e7b9d4462384a284e62b14ffcc9b6fd0b58090913dfe32d9b590d762903f36ec
|
|
| MD5 |
14bd6c392daf96e21adc13d65750d109
|
|
| BLAKE2b-256 |
ef1eac707c85a8394a27c682ce7a592d704521ec94688c887fbb1e73b941ceac
|
File details
Details for the file textforge_tf-0.7.0-cp314-cp314t-win_amd64.whl.
File metadata
- Download URL: textforge_tf-0.7.0-cp314-cp314t-win_amd64.whl
- Upload date:
- Size: 871.1 kB
- Tags: CPython 3.14t, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
79195897559686e5801adcc23f2c1fb5ece08025c7f7d4f57f55de41c99e5cc3
|
|
| MD5 |
1cdff7f7fde443647d90d975b64c7ddb
|
|
| BLAKE2b-256 |
946b2be251bb5d017c122e64306f3f5e479076e3da06514ced38bd3e2ad64d88
|
File details
Details for the file textforge_tf-0.7.0-cp314-cp314-win_amd64.whl.
File metadata
- Download URL: textforge_tf-0.7.0-cp314-cp314-win_amd64.whl
- Upload date:
- Size: 834.3 kB
- Tags: CPython 3.14, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f734f5992d65a8bfb383b40bd07ec607fd707897cbb830161d6bcb98c2ad79ee
|
|
| MD5 |
ff32169ae2c823b314b105ca175fe7c0
|
|
| BLAKE2b-256 |
e235e912a809b7a10d19db6bbd554e06bbd9e950ff5d3585b3b6191c3c6f2548
|