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.30.tar.gz (400.5 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.30-cp313-cp313-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.13Windows x86-64

gtcaca-0.1.30-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.30-cp313-cp313-manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.13macOS 11.0+ ARM64

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

Uploaded CPython 3.12Windows x86-64

gtcaca-0.1.30-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.30-cp312-cp312-manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.11Windows x86-64

gtcaca-0.1.30-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.30-cp311-cp311-manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.11macOS 11.0+ ARM64

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

Uploaded CPython 3.10Windows x86-64

gtcaca-0.1.30-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.30-cp310-cp310-manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.10macOS 11.0+ ARM64

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

Uploaded CPython 3.9Windows x86-64

gtcaca-0.1.30-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.30-cp39-cp39-manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ ARM64

gtcaca-0.1.30-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.30.tar.gz.

File metadata

  • Download URL: gtcaca-0.1.30.tar.gz
  • Upload date:
  • Size: 400.5 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.30.tar.gz
Algorithm Hash digest
SHA256 2d22ac4a2df6abd4384ed563f2e2020065af922187cafb17e5c379f88cc4d80e
MD5 cc6438f55d8b8cffe2179f8536ffffeb
BLAKE2b-256 bc56ae64a1bf029c86389801ab0fab536efe93a3796bfc80713e486ae5e9924a

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30.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.30-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: gtcaca-0.1.30-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.30-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 698c234694e37f8067eb80cb6eb83fcd7cbbc0c2b6f14ebcc141ac4b4f7f4332
MD5 18678a519e55d257541a69055fe6759f
BLAKE2b-256 bc34801130c9ddabd6587507c83fd45024c692bd18979f2c940c9ee6e08ce224

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 26a1fa1a7aec5194a2ab3df14938e4bd36a14c68b61b0522c1b90133c743d462
MD5 de7b1aa5c6721a5d7ac069a3d7cba0d1
BLAKE2b-256 201b345774c0a53e880b4f8cdcc475fe3916fc896ce2a08dda038624140e8a83

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp313-cp313-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3fc3b2b1022dc7dd12e132a6bfb9bd0a0e037a722d834dba05682d22797597ba
MD5 6bd986880f8ff7c6f5b06754a0cb7f9d
BLAKE2b-256 297843bc7044ea74799ee6813e5436374c332694064c64039ae720a3907024ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b3c1b23f76c645da0d1b5d1eeb67cce21b8a8995cef56e3c2fe65c33a6c93a80
MD5 dabc0b648f2b1bd0b58def453bf38fae
BLAKE2b-256 f5af18d2963ee9e00ae1fd0548e6c8d519b633b4a2ff30b0f5e5a0e53e6b54c8

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: gtcaca-0.1.30-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.30-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 4fba4c1464bd21dd8600293387b5f9e317559acb31600998c6d3cd9df4ea5958
MD5 7be2b04b6e44f900945300f59c8232b6
BLAKE2b-256 66966026c8050346d4a9a18212e33205e926225ffdb8644aaa414bdaa1f0365b

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0f3e632d5018153bbf97d3d1f5dca9b630bea8a6041caeb696c2413446cd7287
MD5 67165160317b6e21cc9eed319d6ffcbb
BLAKE2b-256 25042b2c70d46919dbbc0523654e367ed4ad770ec788a403d3daa6b7bafa357f

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp312-cp312-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9b665b63a2a4f0a048a6053b6404b2eb7c11beed7a7629ff3318cf0e501a7176
MD5 baa4cb96039fa9d0f4d4e8b69db666d7
BLAKE2b-256 ef68d54c3e04971ebfd7046fdb6cb5e41be891029e9ba1a3a0d9c312d3e06e04

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fa438d762cfa36c357caa038140ca382f57c5a9f16d7f9447d91abb61726282e
MD5 7838fbf50ba0a96e55f671bfcef25050
BLAKE2b-256 975f32cc700fea3d2a7e13ebbc561bbcb3ff37d99623d38bc721bed59a716807

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: gtcaca-0.1.30-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.30-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 618ab0cd48a57d0e7838c9d25d46b6833eb735faf969f2c110e0cfaa37a939cb
MD5 1045bcf26c28cef1a8c82bbea9114b21
BLAKE2b-256 389902e47fd617c63156a03f998e50b8cd8262b0d4886e9a2d8ca12cdbb53eb2

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c1a55b5c9f18d7186886ef8ff3e348ea8252cafdbe02d75ee1f8dd2d84f76f08
MD5 48a9330c4097f31500f07a3719026fc7
BLAKE2b-256 39dd2b57ca1eb5ba36c98f5977cfb7794ae2197215b88e94cf9fd3cdd78bc98a

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 078d4f01f7b2227f71ba80e04624e47c24a0a86d76227dbb499bc6d5896dd724
MD5 370e46a57737f32af0cd438ba29d9db3
BLAKE2b-256 42c6ec5adc01701740d026b9293c7659e771cd0d7a6404565d84ff0d11bd9ece

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b05a5f831ba0cfef718b258feab67a3de0bf343c0e1f79bf8978bd0239972c35
MD5 ba8c0ce08694d6fe990d14d1946b17ad
BLAKE2b-256 128cfccf1342f4f0c164b1ecec27dfbdb84ede6ad12df5c8b14851a8b2e3fdc5

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: gtcaca-0.1.30-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.30-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 8d4a67baca4896cd50a578860ae0c09b975c0577198f771758588fff2f4cdf5c
MD5 61c9514ed9d60d588a8f0875119a82d3
BLAKE2b-256 22c20fc7f59ae368567c3962da14fca98f995c98d29ebfab993a44ade54b276e

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0e860883232935cabb0b137c3c9f04a49ac3509652cc61501a43c19385953ef9
MD5 7ccabacb3b46e17995d529e80ccc96ca
BLAKE2b-256 8d05c87b9bf3d492278368b9cc6bbedafd1231f42758837792a803ea5c3b66cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp310-cp310-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 391b6da990d23e5b0380abb5bd08faea90100f076b8adaa362ed3884a31a06a2
MD5 a59d10a25fb816fe33b3c56ab6e96625
BLAKE2b-256 0e5d2644072c9f0a7aa3d66c4f838e7387d0ada6a62790d79e6dc320be08ead4

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5a316233e64b69101c9b8fdc1701eb2e72d6cafc52e1560868407a4f3bcddf37
MD5 aa3497d25f1261284cdb947245422d6f
BLAKE2b-256 aefec22cde4e467ab58736b2eb85ecc69be20963e44d8347d2bddf97c4710eec

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: gtcaca-0.1.30-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.30-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 969cb80196d4fb46aa122a1539d5163a77b787fa4cd677aa2263f3d8d34a3dc5
MD5 e07680db9969daec9afda9bb75ba92b4
BLAKE2b-256 791976fcb2508d8f4bcdb6141633865aaa259b0fb3ab50abe9db9fcfde676178

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp39-cp39-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 512dff2660326e7d2b593b84db0d959fdc3cdbe80fbfc078f1ac0d77c6ab3fd0
MD5 d0200d88084c2ead806dc9f6eccd4632
BLAKE2b-256 b021faf07de70a033b0b7b055d4e6aa60b443047e8c700e767911a7fafe83475

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp39-cp39-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp39-cp39-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5d6d6126715accfbad365ec81195abf06036121c9f0c117984406ac92cf481a4
MD5 7a0a7462c862a1f059c2b1837af5591d
BLAKE2b-256 c81f28c127675cdade840c14886163f0fff4adcc37d133f908d770e7e57c4efe

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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.30-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gtcaca-0.1.30-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6c7ad9e919970b0e7db01a0fa8724744e626ccc19c2ae1192d04814f669a1a98
MD5 da4145f03d5cd7310c8f51ae469b06ce
BLAKE2b-256 220559d51f21941c2c84a99de607fa786682a1a6df74f49c7101a44469bf2443

See more details on using hashes here.

Provenance

The following attestation bundles were made for gtcaca-0.1.30-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