Skip to content

Instantly share code, notes, and snippets.

View L3viathan's full-sized avatar
🦊

Jonathan Oberländer L3viathan

🦊
View GitHub Profile
@L3viathan
L3viathan / dots.py
Last active January 8, 2024 08:46
Infinite progress indicator thing
import sys
from time import sleep
from contextlib import contextmanager
@contextmanager
def dots():
def _dots():
while True:
for i, char in enumerate("⠁⠃⠇⡇⣇⣧⣷⣿"):
if i:
@L3viathan
L3viathan / pytest_allow_extensionless.py
Created September 21, 2023 20:32
Tiny pytest plugin that allows collecting any file regardless of extension. If you don't manually specify test files, this will probably crash.
from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader
import pytest
class ModuleWithoutExtension(pytest.Module):
def _importtestmodule(self):
print(self.path, type(self.path))
spec = spec_from_loader(self.path.name, SourceFileLoader(self.path.name, str(self.path)))
@L3viathan
L3viathan / expiry.py
Created August 18, 2023 14:48
Allow annotated variables as lasting only for a bit
import sys
import threading
from time import sleep
from typing import Annotated, get_origin, get_args
from collections import namedtuple
timeout = namedtuple("timeout", "s")
@L3viathan
L3viathan / sumtypes.py
Last active July 24, 2023 15:31
Sum types in Python
class SubscriptableSneaky:
def __init__(self, ns, name):
self.ns = ns
self.args = []
self.name = name
def __getitem__(self, items):
if not isinstance(items, tuple):
items = items,
self.args = [item.name for item in items]
@L3viathan
L3viathan / matchmeta.py
Created February 16, 2023 19:10
custom match-case rules
class MatchMeta(type):
def __instancecheck__(cls, inst):
return cls.isinstance(inst)
def matching(fn):
class cls(metaclass=MatchMeta):
isinstance = fn
return cls
@L3viathan
L3viathan / tssh
Last active November 22, 2023 08:39
Start a tmux pane for each of the specified hosts, in synchronized-panes mode
#!/bin/bash
if (( $# > 6 )); then
layout=tiled
else
layout=even-vertical
fi
hosts=( "$@" )
tmux new-window
tmux send-keys "ssh ${hosts[0]}"
for i in $(seq 1 $((${#hosts[@]} - 1)))
@L3viathan
L3viathan / README.md
Last active October 15, 2022 20:43
character-level coverage tracking

Proof-of-concept: character-based coverage tool

image

As of 3.11, code objects have a new co_positions() method that yields tuples of the form (lineno_start, lineno_end, char_start, char_end) for each bytecode instruction. Combined with setting f_trace_opcodes to True on a frame, trace functions can theoretically track coverage on a character level.

There are a bunch of issues though, shown in part in the code:

  • Some instructions correctly cover a wide range of code: JUMP_* instructions from branching code basically seems to span the entire length of the jump, i.e. from the if to the end of the indented block. MAKE_FUNCTION covers the entire function definition. These issues seem to be easy to resolve on first glance, because you can just ignore the corresponding opcodes.
@L3viathan
L3viathan / algebraic_effects.py
Created September 20, 2022 19:15
Simple demo of algebraic effects in Python. This doesn't show the full potential; it's just a proof-of-concept
import sys
class Effect:
def __enter__(self):
self.local_handlers = sys._getframe().f_back.f_locals.setdefault("_effect_handlers", [])
self.local_handlers.append(self)
def __exit__(self, *args):
self.local_handlers.pop()
@L3viathan
L3viathan / overload.py
Created August 18, 2022 08:50
Multiple dispatch via type annotations
def overload(fn, overloads={}, nope=object()):
def wrapper(*args, **kwargs):
for sig, func in overloads.get(fn.__qualname__, []):
try:
bound = sig.bind(*args, **kwargs)
except TypeError:
continue
for name, value in bound.arguments.items():
if not isinstance(value, func.__annotations__[name]):
break
@L3viathan
L3viathan / defer.py
Created July 29, 2022 10:31
Go-like defer statements
import sys
import inspect
from contextlib import contextmanager
from collections import defaultdict
deferred_lines = defaultdict(list)
def defer_trace(frame, event, arg):