Skip to main content

GTCaca Python bindings

pybind11 bindings for GTCaca, a libcaca-based terminal UI toolkit: windows, widgets, charts, an editor, and a raw canvas escape hatch — all drawn as text cells.

The bindings compile the GTCaca C sources directly into the extension module, so the only external runtime dependency is libcaca itself. Every widget the toolkit ships is exposed.

pip install gtcaca

Contents


Requirements

  • A C/C++ toolchain and CMake ≥ 3.20
  • libcaca with development headers, discoverable via pkg-config (pkg-config --exists caca should succeed)
  • Python ≥ 3.9

On macOS: brew install libcaca, and if pkg-config cannot find it, export PKG_CONFIG_PATH="$(brew --prefix libcaca)/lib/pkgconfig". On Debian/Ubuntu: apt install libcaca-dev.

Install

pip install gtcaca                 # from PyPI
pip install .                      # from a checkout of src/bindings/python

Building in-tree without installing:

cmake -S . -B build -Dpybind11_DIR="$(python -m pybind11 --cmakedir)"
cmake --build build -j

Quick start

import gtcaca as gt

gt.init()
gt.application_new("Hello")
win = gt.window_new(None, "Demo", 0, 1, 40, 10)
gt.label_new(win, "Press Enter on the button", 2, 2)

btn = gt.button_new(win, "  OK  ", 2, 4)

def on_key(key):
    if key == gt.KEY_RETURN:
        gt.main_quit()
    return 0            # 0 = not consumed; let others see the key

btn.on_key(on_key)
win.set_focus()
gt.main()               # blocking event loop
gt.present_shutdown()

See example.py for a fuller program.


Core concepts

Lifecycle

Call Purpose
gt.init() open the display; must precede any widget creation
gt.main() run the blocking event loop
gt.main_quit() ask the loop to exit (call from a callback)
gt.redraw() repaint now — call after changing state from a callback
gt.present_shutdown() tear the display down
gt.canvas_width(), gt.canvas_height() canvas size in character cells

The display driver is chosen by libcaca; CACA_DRIVER=null runs headless, which is what makes the widgets testable without a terminal.

Widgets and parents

Every widget comes from a *_new() factory whose first argument is the parent — another widget, or None for a top-level/canvas-anchored widget:

win  = gt.window_new(None, "Title", 0, 0, 40, 12)
name = gt.entry_new(win, 2, 3, 20)          # lives inside the window

Widgets are owned by the C library and live for the process; they are never freed by Python. Each exposes the shared preamble x, y, width, height, has_focus, is_visible, id, plus show(), hide() and as_widget().

Focus

Keys go to focused widgets. widget.set_focus() (windows/custom) or assigning widget.has_focus = True moves it; window.focus_next_child() cycles.

Callbacks

  • Key callbackswidget.on_key(cb), cb(key: int) -> int. Return non-zero to consume the key; returning None means not consumed.
  • Value callbackson_toggle(cb) / on_change(cb) on Switch, Expander, Scale, SpinButton. Receive the new value.
  • Menu actions take no arguments.
  • MouseCustom.on_mouse(cb), cb(event, x, y, button).

Exceptions inside a callback are reported through sys.unraisablehook and never abort the event loop.

Colours

ANSI colour constants are module attributes: gt.BLACK, gt.RED, gt.GREEN, gt.BROWN, gt.BLUE, gt.MAGENTA, gt.CYAN, gt.LIGHTGRAY, gt.DARKGRAY, gt.LIGHTRED, gt.LIGHTGREEN, gt.YELLOW, gt.LIGHTBLUE, gt.LIGHTMAGENTA, gt.LIGHTCYAN, gt.WHITE. gt.color_name(idx) gives the display name.

Drawing primitives: gt.set_color(fg, bg), gt.set_color_rgb(fg12, bg12) (12-bit 0xRGB), gt.put_str(x, y, s), gt.put_char(x, y, codepoint), gt.fill_box(x, y, w, h, ch), gt.draw_box(...), gt.draw_thin_box(...).


Windows and layout

app = gt.application_new("My app")
win = gt.window_new(None, "Settings", 0, 1, 50, 16)
win2 = gt.window_new_centered(None, "Centered", 30, 8)

gt.frame_new(win, "Network", 2, 2, 44, 6)      # labelled box
gt.separator_new(win, 2, 9, 44)                # horizontal rule

Box layouts

A Box positions widgets; it draws nothing itself.

box = gt.vbox_new()                 # or gt.hbox_new() / gt.box_new(gt.BOX_HORIZONTAL)
box.set_spacing(1)
box.set_margin(1)
box.set_align(gt.ALIGN_CENTER)      # ALIGN_START / ALIGN_CENTER / ALIGN_END

box.add(gt.label_new(None, "Name", 0, 0))
box.add_expand(gt.entry_new(None, 0, 0, 20))   # takes leftover space
box.add_spacing(2)
box.add_stretch()

box.apply(0, 0, 40, 12)             # lay out into this rectangle
box.apply_window(win)               # ...or into a window's content area
print(box.preferred_width(), box.preferred_height())

Tabs and expanders

tabs = gt.tabs_new(win, 1, 1, 40, 12)
tabs.set_titles(["General", "Advanced"])
tabs.set_selected(1)
print(tabs.selected())              # 1
tabs.key(gt.KEY_RIGHT)              # feed it keys yourself

exp = gt.expander_new(win, "Details", 2, 14, 30)
exp.add_managed(some_widget)        # shown/hidden with the expander
exp.set_expanded(True)
exp.on_toggle(lambda expanded: print("open" if expanded else "closed"))

Buttons and input

btn = gt.button_new(win, "  Apply  ", 2, 2)
btn.on_key(lambda k: gt.main_quit() if k == gt.KEY_RETURN else 0)

chk = gt.checkbox_new(win, "Enable", 2, 4)
chk.set_checked(True); chk.get_checked()

r1 = gt.radiobutton_new(win, "Fast", 1, 2, 6)   # group id 1
r2 = gt.radiobutton_new(win, "Small", 1, 2, 7)
r1.set_active()                  # takes no argument: selects r1, clears the group
r2.get_active()                  # -> False

cb = gt.combobox_new(win, 2, 9, 20)
cb.append("gzip"); cb.append("zstd")
cb.get_selected(); cb.get_selected_index()

sw = gt.switch_new(win, 2, 11)
sw.set_active(True); sw.get_active()
sw.on_toggle(lambda active: print("switch:", active))

sb = gt.spinbutton_new(win, 2, 13, 0, 100, 5)   # min, max, step
sb.set_value(20); sb.get_value()
sb.on_change(lambda v: print("spin:", v))
sb.handle_key(gt.KEY_UP)

sc = gt.scale_new(win, 2, 15, 30, 0.0, 1.0, 0.05)   # a slider
sc.set_value(0.4); sc.get_value()
sc.on_change(lambda v: print("scale:", v))

Text

Label, Entry, TextView

gt.label_new(win, "Read only text", 2, 2)

e = gt.entry_new(win, 2, 4, 24)
e.set_text("hello"); e.get_text()
e.set_secret(True)                 # password field

tv = gt.textview_new(win, 2, 6, 40, 8)
tv.append("a log line")
tv.clear()

TextList — a scrollable, searchable list

tl = gt.textlist_new(win, 2, 2)
tl.set_view_size(10)
for name in ("alpha", "beta", "gamma"):
    tl.append(name)
tl.set_search_enabled(True)
tl.selection_down()
print(tl.selected_text(), tl.is_searching())
tl.on_key(lambda k: 0)

Editor — a multi-line text editor

A Scintilla-shaped API: positions are byte offsets, lines are 0-based.

ed = gt.editor_new(win, 0, 1, 80, 20)
ed.set_text("def f():\n    return 1\n")
ed.set_line_numbers(True)
ed.set_tab_width(4)
ed.set_caret_line_visible(True)

# navigation and selection
ed.goto_line(1); ed.line_end_extend()
print(ed.selected_text(), ed.current_line(), ed.line_count())

# editing with grouped undo
ed.begin_undo_action()
ed.insert_text(0, "# header\n")
ed.end_undo_action()
ed.undo(); ed.redo()
print(ed.can_undo(), ed.get_modify())

# search
hit = ed.find_text(0, "return", 0, len(ed))     # -> (start, end) or None
ed.set_target_range(0, len(ed))
if ed.search_in_target("return") >= 0:
    ed.replace_target("yield")

# syntax configuration
cfg = gt.editor_langcfg_new()
cfg.set_line_comment("#")
cfg.set_block_comment('"""', '"""')
cfg.add_bracket("(", ")")
cfg.set_keywords(["def", "class", "return"])
ed.set_langcfg(cfg)
ed.colourize()

# folding and annotations
ed.fold_by_indentation()
ed.toggle_fold(0)
ed.annotation_set_text(1, "returns an int")

Also available: rectangular selection (set_rectangular_selection, rect_copy, rect_yank, …), word motion (word_left, del_word_right, …), styling (style_set_fore, style_set_bold, set_bg_rgb12, …), set_read_only, set_overtype, set_wrap, set_view_whitespace, brace_match, and JSON mode (set_json_mode, fold_json).


Data views

Table — a lazy model/view

Rows live behind a model: any object with these methods. Only visible rows are queried, so the row count may be huge.

class FileModel:
    def __init__(self, rows): self.rows = rows
    def row_count(self):      return len(self.rows)
    def col_count(self):      return 2
    def header(self, col):    return ("Name", "Size")[col]
    def cell(self, row, col): return str(self.rows[row][col])
    # optional — Wireshark-style row colouring; None = theme default
    def row_color(self, row):
        return (gt.BLACK, gt.YELLOW) if self.rows[row][1] > 1_000_000 else None

t = gt.table_new(win, 0, 1, 60, 20)
t.set_model(FileModel([("a.txt", 12), ("big.iso", 4_000_000)]))
t.set_column_widths([30, 12])
t.set_title("Files")
t.key(gt.KEY_DOWN)
print(t.current_row(), t.current_col(), t.selected_row())

Tree — a lazy hierarchical view

Nodes are integers you choose; the invisible super-root is None.

NODES = {1: ("root", [2, 3]), 2: ("child A", []), 3: ("child B", [4]), 4: ("leaf", [])}

class TreeModel:
    def child_count(self, node):  return len(NODES[node][1]) if node else 1
    def child(self, node, i):     return NODES[node][1][i] if node else 1
    def label(self, node):        return NODES[node][0]
    def has_children(self, node): return bool(NODES[node][1]) if node else True
    # optional: paint the row yourself instead of using label()
    # def draw_row(self, node, x, y, width, selected): ...

tr = gt.tree_new(win, 0, 1, 40, 20)
tr.set_model(TreeModel())
tr.select(3)
print(tr.selected_node(), tr.visible_count())

HexView — byte viewer and editor

As a viewer:

hv = gt.hexview_new(win, 0, 1, 78, 20)
data = open("file.bin", "rb").read()
hv.set_data(data)            # keep `data` alive: the widget does not copy it
hv.set_highlight(16, 8)      # one reverse-video range
hv.set_title("file.bin")
hv.key(gt.KEY_DOWN)          # arrows/page/home/end move, TAB swaps panes
print(hv.cursor(), len(hv))

Layout — every dimension is adjustable:

hv.set_bytes_per_row(0)      # 0 = fit as many as the width allows
hv.bytes_per_row()           # the effective value
hv.set_group_size(4)         # blank column every 4 bytes (0 = no grouping)
hv.set_addr_digits(8)        # 0 = derive from the data length
hv.set_base_addr(0x400000)   # show file offsets as load addresses
hv.set_show_ascii(False)     # hex only
hv.set_box(False)            # borderless, for a full-width pane

Colouring — one hook, called for every painted byte (twice: hex cell and ASCII cell). Returning None falls through to the widget's own colouring, which is cursor → selection → tags → highlight range.

def cell(off, is_ascii):
    if off in bookmarks:
        return (0x000, 0xF66)          # 12-bit 0xRGB
    return None

hv.on_cell(cell)
hv.on_cell(None)                       # remove

Named coloured regions, for bookmarks or parsed fields — later tags paint over earlier ones:

hv.add_tag(0, 8, 0xFFF, 0x006, "header")
hv.add_tag(4, 2, 0x000, 0x0F0, "length")
print(hv.tag_at(4))                    # "length"
hv.clear_tags()

Cursor and selection:

hv.set_cursor(0x100); hv.cursor()
hv.set_pane(True); hv.pane()           # True = ASCII pane
hv.set_nibble(True); hv.nibble()       # which half-byte is being typed
hv.set_selection(10, 40); hv.selection()   # -> (10, 40) inclusive
hv.clear_selection()

Editing. The widget never mutates the bytes. It reports the intended change and your code applies it — which is what lets an application keep its own undo history, layers, or a memory-mapped file behind the view:

buf = bytearray(open("file.bin", "rb").read())

def on_edit(off, value):        # a byte was typed over
    buf[off] = value
    return True                 # False rejects it; the cursor does not advance

def on_splice(off, is_insert):  # one byte inserted or deleted
    buf.insert(off, 0) if is_insert else buf.pop(off)
    hv.set_data(buf)            # re-point: the buffer may have moved
    return True

hv.set_editable(True)
hv.on_edit(on_edit)
hv.on_splice(on_splice)
hv.set_insert_mode(True)        # INSERT toggles it too

Once editable, key() also handles hex digits (two nibbles per byte), printable ASCII in the ASCII pane, DELETE, BACKSPACE and INSERT.

Large data. Instead of a flat buffer, serve bytes on demand — for files bigger than memory, a remote target, or a stream decompressed as you scroll:

fh = open("huge.iso", "rb")
def read(off, n):
    fh.seek(off)
    return fh.read(n)

hv.on_read(read, os.path.getsize("huge.iso"))    # replaces set_data()

Search:

hv.find(b"\x89PNG")                       # -> offset, or -1
hv.find(b"PNG", from_offset=100)
hv.find(b"PNG", from_offset=len(hv), backwards=True)

Indicators

pb = gt.progressbar_new(win, 2, 2, 30); pb.set_value(0.5)

g = gt.gauge_new(win, 2, 4, 30)
g.set_percent(80)                        # or set_value(0.8)
g.set_label("CPU")                       # None shows the percentage
g.set_colors(gt.GREEN, gt.DARKGRAY)

sp = gt.spinner_new(win, 2, 6)
sp.set_spinning(True); sp.step()         # advance one frame

sd = gt.segdisplay_new(win, 2, 8, 30, 6) # seven-segment display
sd.set_text("42.7"); sd.set_colour(gt.LIGHTRED); sd.set_box(True)

sl = gt.sparkline_new(win, 2, 15, 30, 4)
sl.set_data([1.0, 4.0, 2.0, 8.0])
sl.push(5.0)                             # rolling append
sl.set_style(gt.SPARKLINE_AREA)          # or SPARKLINE_BLOCKS / set_style_auto()

bar = gt.statusbar_new(" ready ")
bar.set_text(" saved ")

Charts and maps

bc = gt.barchart_new(win, 0, 1, 40, 12)
bc.set_data([3.0, 7.0, 5.0], ["red", "green", "blue"])
bc.set_show_values(True); bc.set_bar_width(3, 1); bc.set_max(0)   # 0 = auto

pc = gt.piechart_new(win, 0, 1, 40, 14)
pc.set_data([30.0, 50.0, 20.0], ["a", "b", "c"])
pc.set_colors([gt.RED, gt.GREEN, gt.BLUE])
pc.set_donut(True); pc.set_show_legend(True)
gt.piechart_palette(0)                      # default palette entry

lc = gt.linechart_new(win, 0, 1, 60, 16)
lc.add_series([1.0, 3.0, 2.0, 5.0], gt.LIGHTGREEN)
lc.set_range(0, 6); lc.set_xspan(10, "s"); lc.set_log_y(False)

sp = gt.scatter_new(win, 0, 1, 60, 16)
sp.add_point(1.0, 2.0, gt.CYAN)
sp.set_data([1.0, 2.0, 3.0], [2.0, 4.0, 8.0], gt.YELLOW)
sp.set_autoscale(True)                      # or set_bounds(xmin, xmax, ymin, ymax)

Map

m = gt.map_new(win, 0, 1, 80, 24)
m.add_world(gt.BLUE)
m.set_graticule(True)
m.add_city("Paris", colour=gt.LIGHTRED)     # built-in city table
m.add_point(35.68, 139.69, label="Tokyo", colour=gt.YELLOW)
m.add_polyline([2.35, 48.85, 139.69, 35.68], gt.GREEN)   # flat lon,lat,lon,lat
print(m.project(2.35, 48.85))               # -> (x, y) or None if off-map
print(gt.map_find_city("Tokyo"))            # ('Tokyo', 35.68, 139.69)
print(len(gt.map_cities()))

MindMap

mm = gt.mindmap_new(win, 0, 1, 60, 20)
mm.clear("Project")
root = mm.root()
a = mm.add_child(root, "design")
mm.add_sibling(a, "build")
a.set_text("design docs")
a.toggle_fold()
mm.select(a)
print(mm.selected())

Menus

The library binds F10 to toggle menu focus and gives the menu exclusive key dispatch while it is open; it closes a dropdown before running the action, so an action may safely open a modal dialog.

menu = gt.menu_new()

f = menu.add_entry("File")
menu.add_item(f, "Save", "Ctrl-S", lambda: save())
menu.add_item(f, "Save As...", "", lambda: save_as())
menu.add_separator(f)
menu.add_item(f, "Quit", "Ctrl-X", gt.main_quit)

h = menu.add_entry("Help")
menu.add_item(h, "About", "", lambda: gt.dialog_message("About", "v1.0"))

menu.set_focus(True)             # open it from your own key handler
menu.is_focused()
menu.set_item_enabled(f, 0, False)   # grey out File▸Save

Limits: 8 top-level entries, 20 items each, 31-character labels, 11-character shortcut strings.


Dialogs and choosers

The blocking helpers run their own event loop and return the answer, so they can be called straight from a key handler or a menu action.

if gt.dialog_confirm("Unsaved changes", "Quit anyway?"):
    gt.main_quit()

gt.dialog_message("Done", "Export finished.")

idx = gt.dialog_run("Conflict", "The file changed on disk.",
                    ["Reload", "Overwrite", "Cancel"])   # index, or -1 if ESC

For a non-blocking dialog driven by your own loop, use the widget form: gt.dialog_new(...), .set(title, message, buttons), .draw(), .key(k), .result() (which is gt.DIALOG_ONGOING until a button is chosen).

File chooser

path = gt.filechooser_run(".", save_mode=False)      # -> path or None
path = gt.filechooser_run_named(".", "untitled.txt") # save dialog, name pre-filled

path, flags = gt.filechooser_run_opts(".", True, [("compress", True), ("backup", False)])

Or embed it: gt.filechooser_new(parent, x, y, w, h), .set_dir(), .draw(), .key().

Colour picker and calendar

colour = gt.colordialog_run("Pick a colour", gt.RED)   # ANSI index, or -1

cal = gt.calendar_new(win, 0, 1, 24, 10)
cal.set_date(2026, 8, 3)
cal.set_marker(lambda y, m, d: d in (1, 15))           # mark those days
print(cal.get_date())
gt.calendar_days_in_month(2026, 2)    # 28
gt.calendar_day_of_week(2026, 8, 3)   # 0=Sunday .. 6=Saturday

Image

img = gt.image_new(win, 0, 1, 40, 20)
if img.load("photo.png"):             # also load_memory(bytes)
    img.draw()

Custom widgets

When no stock widget fits, take the canvas. This is how you get per-cell colour.

def draw():
    W, H = gt.canvas_width(), gt.canvas_height()
    gt.set_color(gt.WHITE, gt.BLUE)
    gt.fill_box(0, 0, W, 1, ord(" "))
    gt.put_str(1, 0, "custom widget")
    gt.set_color_rgb(0x9CF, 0x000)       # 12-bit RGB
    gt.put_str(1, 2, "coloured text")

def key(k):
    if k == 24:                          # Ctrl-X
        gt.main_quit()
    return 1

def mouse(event, x, y, button):
    if event == gt.MOUSE_PRESS:
        print("click", x, y, button)
    return 0

w = gt.custom_new(None, 0, 0, gt.canvas_width(), gt.canvas_height())
w.on_draw(draw)
w.on_key(key)
w.on_mouse(mouse)
w.set_focusable(True)
w.set_focus()

Mouse events are MOUSE_PRESS, MOUSE_RELEASE, MOUSE_MOTION, MOUSE_WHEEL, MOUSE_DOUBLE; buttons are 1 left, 2 middle, 3 right, 4/5 wheel. gt.set_double_click_time(ms) tunes double-click detection. Motion only arrives while a button is held, and the press that starts a drag owns the whole gesture.


Utilities

Rope — a text buffer with cheap edits anywhere

r = gt.rope_from("hello world")
r.insert(5, ",")
r.delete(0, 1)
print(str(r), len(r), r.lines())
print(r.copy(0, 4), r.at(0))
print(r.line_of(3), r.line_start(0))
print(r.find(0, "w"), r.rfind(len(r), "o"))

Threading and the GIL

The GIL is released while gt.main() blocks and re-acquired inside every callback, so callbacks can safely touch Python state. The modal dialog helpers (dialog_run, dialog_confirm, filechooser_run, colordialog_run) hold the GIL for their duration because their internal redraws call back into Python.


API index

Lifecycle & canvasinit, main, main_quit, redraw, present_shutdown, canvas_width, canvas_height, set_double_click_time

Drawingset_color, set_color_rgb, put_str, put_char, fill_box, draw_box, draw_thin_box, color_name

Containersapplication_new, window_new, window_new_centered, frame_new, separator_new, vbox_new, hbox_new, box_new, tabs_new, expander_new

Inputbutton_new, entry_new, checkbox_new, radiobutton_new, combobox_new, switch_new, spinbutton_new, scale_new

Textlabel_new, textview_new, textlist_new, editor_new, editor_langcfg_new, editor_grammar_load, rope_new, rope_from

Data viewstable_new, tree_new, hexview_new

Indicatorsprogressbar_new, gauge_new, spinner_new, segdisplay_new, sparkline_new, statusbar_new

Chartsbarchart_new, piechart_new, piechart_palette, linechart_new, scatter_new, map_new, map_cities, map_find_city, mindmap_new

Menus & dialogsmenu_new, dialog_new, dialog_run, dialog_confirm, dialog_message, filechooser_new, filechooser_run, filechooser_run_named, filechooser_run_opts, colordialog_new, colordialog_run, calendar_new, calendar_days_in_month, calendar_day_of_week, image_new

Escape hatchcustom_new

Constants — colours (BLACKWHITE), keys (KEY_RETURN, KEY_ESCAPE, KEY_TAB, KEY_UP/DOWN/LEFT/RIGHT, KEY_HOME, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN, KEY_BACKSPACE, KEY_DELETE, KEY_F1KEY_F10), mouse (MOUSE_PRESS, MOUSE_RELEASE, MOUSE_MOTION, MOUSE_WHEEL, MOUSE_DOUBLE), layout (BOX_VERTICAL, BOX_HORIZONTAL, ALIGN_START, ALIGN_CENTER, ALIGN_END), SPARKLINE_BLOCKS, SPARKLINE_AREA, DIALOG_ONGOING

Every binding lives in gtcaca_module.cpp; help(gtcaca) and help(gtcaca.Editor) work at the REPL for per-method signatures.

Licence

Public domain, like GTCaca itself.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gtcaca-0.1.28.tar.gz (398.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

gtcaca-0.1.28-cp313-cp313-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.13Windows x86-64

gtcaca-0.1.28-cp313-cp313-manylinux_2_28_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

gtcaca-0.1.28-cp313-cp313-manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

gtcaca-0.1.28-cp313-cp313-macosx_11_0_arm64.whl (723.6 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

gtcaca-0.1.28-cp312-cp312-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.12Windows x86-64

gtcaca-0.1.28-cp312-cp312-manylinux_2_28_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

gtcaca-0.1.28-cp312-cp312-manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

gtcaca-0.1.28-cp312-cp312-macosx_11_0_arm64.whl (723.5 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

gtcaca-0.1.28-cp311-cp311-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.11Windows x86-64

gtcaca-0.1.28-cp311-cp311-manylinux_2_28_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

gtcaca-0.1.28-cp311-cp311-manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

gtcaca-0.1.28-cp311-cp311-macosx_11_0_arm64.whl (720.7 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

gtcaca-0.1.28-cp310-cp310-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.10Windows x86-64

gtcaca-0.1.28-cp310-cp310-manylinux_2_28_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

gtcaca-0.1.28-cp310-cp310-manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

gtcaca-0.1.28-cp310-cp310-macosx_11_0_arm64.whl (719.7 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

gtcaca-0.1.28-cp39-cp39-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.9Windows x86-64

gtcaca-0.1.28-cp39-cp39-manylinux_2_28_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ x86-64

gtcaca-0.1.28-cp39-cp39-manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ ARM64

gtcaca-0.1.28-cp39-cp39-macosx_11_0_arm64.whl (719.8 kB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

File details

Details for the file gtcaca-0.1.28.tar.gz.

File metadata

  • Download URL: gtcaca-0.1.28.tar.gz
  • Upload date:
  • Size: 398.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gtcaca-0.1.28.tar.gz
Algorithm Hash digest
SHA256 641a8dc951472dbdbb3e6dcad4f86e3d535bafda8d450280d2be4763a267e890
MD5 3246f1de04ffb30f942ed2e8795b127c
BLAKE2b-256 5b8e4c5bd3456c632cd23c8758bf5ba41f83e99688622d087bfad670da79a1ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28.tar.gz:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: gtcaca-0.1.28-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gtcaca-0.1.28-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 2567fefb049549ef7d388585da281b9a00247ca8725584f4b18a6936c11c0da5
MD5 fdbe6ee5607ab487a5a7ef9bb606bb78
BLAKE2b-256 8a2088f78ce34604f60cd118cc486ff61f8447cbce401c1376d2c90190964166

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp313-cp313-win_amd64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0deec028e6454d8112e4bddad8d332a28c5f83c0283c68e59f4129f4525693b0
MD5 d44277a6aa55fb34ded3dba843c59c40
BLAKE2b-256 66431ac6337630b5ccab135424f04566ce7bb56a3350b5c756dd5123cf4205f9

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp313-cp313-manylinux_2_28_x86_64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp313-cp313-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 22caf5790aa56ca5cd67174badddd0d9b5849d463b867d7111d2d925cee32c7f
MD5 639093afc11ea8b872b4781c19c461b0
BLAKE2b-256 9bbfc810a14a54c1fe2c4d903e4fab6d18f396a478385b2fa4b260b5b65c4cde

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp313-cp313-manylinux_2_28_aarch64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 044bd22d80dc945498c1ff6507052b2cde5bd612a70e04fecafa4846d4ef81c9
MD5 e87ecc8174ec5cf38852a36619e18ea0
BLAKE2b-256 4fd5f2681a2be3eefe1ebd21196b0018211cc5865699ba2d2404bac0ab912a0d

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: gtcaca-0.1.28-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gtcaca-0.1.28-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 74d864d3ef4fd7d056122c5816435b7801801633667870e9c2cd5f6587a01d14
MD5 9f17009e7a929fb09f3625ac93e4f305
BLAKE2b-256 558d4f07a71d571cf8af7b67ee233b90a167d113b5264a24542009a730b6158b

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp312-cp312-win_amd64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 76e39eb1235585d126b5944dcbb32e8cdd301c3bf538ead8e3ac62aa9fe4dfc5
MD5 3222843f4054b90618d121da190adf8c
BLAKE2b-256 c30011dae6e1cc1f2c72492dc9bd50f5cef6de7495f3696f59e9d66405ac80c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp312-cp312-manylinux_2_28_x86_64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp312-cp312-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7fee7274f6c6932f7f2eea6e1caf51a36952136b3db2aa8898bdff2403967cb8
MD5 a2eb14780a6033028df1456c4908e4b5
BLAKE2b-256 d46dbe2cc2e5f97915d4fd1e7a7714a3836d8ed29ddfc2fc4d8dd1f59b70224a

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp312-cp312-manylinux_2_28_aarch64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 392ca06997781f166973efc12be06bde0beb3729dd67a2627e05eda0f50195c3
MD5 7b8b364f996dc1ae896e35e6b5c08ad7
BLAKE2b-256 e0676d2fadaa35c86e2454eea1f7f1515226817aba89f1741936f85c5aa79e1b

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: gtcaca-0.1.28-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gtcaca-0.1.28-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 d70ddb75ae23e5f7d9df4f26db0397d3f6d8a7d1a546adf1c3738969cefba03d
MD5 d3ee8ac0610d8c61f8d304567169df70
BLAKE2b-256 c979c0c8fe4520fdbb3b4e4a3d6de64d8d5bbe05a72964fd9daa0fe8277d3143

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp311-cp311-win_amd64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 19fcba8787f3422a0655c8c1821849c14aa5627cdab5f5bcbbbdd581a91e681d
MD5 1ac8324612253f60d00c3924ce59efb7
BLAKE2b-256 29076b7cdf7db0254e8a6a9d41c27f127949801fef63564463f6c19476284053

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp311-cp311-manylinux_2_28_x86_64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 eda9abb6704988e7e62c5bcb166d1a0c77af5612b072ddae4f90a12c772a359a
MD5 77dd9ebcd03fa3c6b607a55ca0c627dc
BLAKE2b-256 c8a5ed14580d029aee658df4f191d2bc1ed29ba7788de3946a39fb5e8118dacd

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp311-cp311-manylinux_2_28_aarch64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ca935339e67d4424e587f8fd7a5a37166085d320a7ba9a17a37dab3fb5b7c627
MD5 60a56b44f5342583d0a6a01484cf4054
BLAKE2b-256 b15ad03bf328e970e7e014f1dd591caba8387493bff01deef81e10a1eff46b2a

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: gtcaca-0.1.28-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gtcaca-0.1.28-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 72e56d9a2b0e66119d8a993aa3775dd95bc8a4e1403e7a65dabfb1cf34f52d12
MD5 7f519a0d51321fbe8774f35a222dfe35
BLAKE2b-256 02a4d32b182b7ca45837cbd6d0abf54ea5efac5aff4302725663526d842e8166

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp310-cp310-win_amd64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 05a433a609cd4336da4488b815d2824d55af55e47b15227e1efe91a71c7663cf
MD5 594d1b3f2f7198e662091358c1797dee
BLAKE2b-256 14dbaf36e9fce040551266705a5aca4601c762c05f9ade3ff1bb9dfd38486ce4

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp310-cp310-manylinux_2_28_x86_64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp310-cp310-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7ee924ef7386aa8bba8fa84e8ae8e1f84c8b9245b3105a427c0f047c0dd7dc0e
MD5 faf7e89a70c799466f44f04ca182fd3c
BLAKE2b-256 46aa173c5f8c58fd8060ae3618a73099e9053362ca7c7f04a562ebeddb280003

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp310-cp310-manylinux_2_28_aarch64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 915c35f97b82dee84ec276b070fd6e22449d0567b5849300957f275198ca8490
MD5 2233705474ab7272a22e87d453d0bf26
BLAKE2b-256 189b630509b4ff6d1809aa3dedad8007bfc547a4adfb6d09b3fa5b87bf0267d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: gtcaca-0.1.28-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gtcaca-0.1.28-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 bdb2b0789dbf68c0572efd8536258d44b61e5b9c0a6d64e84d3d18dd42911f34
MD5 e8fc3fad935227c254cc998ac3cb7fc6
BLAKE2b-256 f93c652a12cea95214057a5b9f3363937e3bd55f60722b1c910313c47484e960

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp39-cp39-win_amd64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp39-cp39-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 18d82867c1dc9afa15aa37f5ac0b871641157afe979802bdd8225ae9f81cfcd8
MD5 fb0c250ad098c5c167de0e9b921f9c82
BLAKE2b-256 d664842f3b7fa14db44c2b2321b7acb578a917e471dce9bfb3581f0c5f104e98

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp39-cp39-manylinux_2_28_x86_64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp39-cp39-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp39-cp39-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 d0cb1200a3a2303428fe83e3d07cd630d94788e421572a54f33f149c49bd1cf7
MD5 dc156827dd81bdbfabd2d0e44a6615b5
BLAKE2b-256 ae21fd34bb3dd633076aa3297d727096ddc94809c9b7fed2f0b863728754df22

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp39-cp39-manylinux_2_28_aarch64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gtcaca-0.1.28-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.28-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 836ef75fa6e08484149bb5bbf4ea514747d841ddfe8e5b45e223bd33bf99b6c8
MD5 aafccab87b68c0bf0b11aa3ded820831
BLAKE2b-256 de37762d377e246ade8e5e1a2083c7bd4086fb3785e56d494b03c2435fdfb56b

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.28-cp39-cp39-macosx_11_0_arm64.whl:

Publisher: release.yml on stricaud/gtcaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page