carabiner package

Subpackages

Submodules

carabiner.cast module

Tweaked casting between Python types.

carabiner.cast.cast(object: Any, to: str | type, *args, **kwargs) Any[source]

Cast an object to another type.

Parameters:
  • x – Object to cast.

  • to (str, type) – Type to cast to. Available: str, list, TextIO, TextIOWrapper

Return type:

Casted object.

Raises:

TypeError – If the object cannot be casted to the type.

Examples

>>> cast("abc", list)
['abc']
>>> cast(["abc"], 'str')
"['abc']"
carabiner.cast.cio(x, *args, **kwargs) TextIOWrapper[source]
carabiner.cast.cio(x: str, *args, **kwargs)
carabiner.cast.cio(x: TextIOWrapper, *args, **kwargs)
carabiner.cast.cio(x: StringIO, *args, **kwargs)

Cast an object to a file-like object.

Addtional parameters are passed to open or gzip.open.

If the input is a string, then it is treated as a filename. If it ends in .gz or .gzip, then it is assumed to be a GZIP-compressed file.

If the input is an open file, then the file is closed and reopened with the provided parameters. This can be useful to close for writing and open for reading.

If the input is a io.StringIO object, then the cursor is moved to the start and the object is returned.

Parameters:

x (str or iterable) – Object to cast.

Return type:

TextIOWrapper

Examples

>>> cio('Hello.txt')  
<_io.TextIOWrapper name='Hello.txt' mode='r' encoding='UTF-8'>
>>> cio('Hello.txt', 'w')
<_io.TextIOWrapper name='Hello.txt' mode='w' encoding='UTF-8'>
>>> list(cio(StringIO("Hello\nworld")))
['Hello\n', 'world']
carabiner.cast.clist(x) List[source]
carabiner.cast.clist(x: str) List[str]
carabiner.cast.clist(x: int) List[int]
carabiner.cast.clist(x: float) List[float]
carabiner.cast.clist(x: TextIOWrapper) List[TextIOWrapper]

Cast an object to a list.

Parameters:

x (str or iterable) – Object to cast.

Return type:

list

Examples

>>> clist('Hello world')
['Hello world']
>>> clist(('Hello', 'world'))  
['Hello', 'world']
carabiner.cast.cstr(x) str[source]
carabiner.cast.cstr(x: TextIOWrapper)

Cast an object to a string.

If the object is a file-like object, return the filename.

Parameters:

x – Object to cast.

Return type:

str

Examples

>>> cstr(["Hello", "world"])
"['Hello', 'world']"
>>> cstr(open("test/test-file.txt", "w"))
'test/test-file.txt'
carabiner.cast.flatten(x) Any[source]
carabiner.cast.flatten(x: list) Any
carabiner.cast.flatten(x: str) Any
carabiner.cast.flatten(x: int) Any
carabiner.cast.flatten(x: float) Any
carabiner.cast.flatten(x: tuple) Any
carabiner.cast.flatten(x: set) Any
carabiner.cast.flatten(x: Iterable) Any

Return the only item for iterables of length one.

If x is a lazy iterator, then this returns a lazy iterator if more than one item in x.

Parameters:

x (str, iterable) – Object to flatten.

Return type:

iterable or item

Raises:

TypeError – If x is not a supported type.

Examples

>>> flatten("Hello")
'Hello'
>>> flatten(["Hello"])
'Hello'
>>> flatten(["Hello", "world"])
['Hello', 'world']
>>> flatten(tuple('abc'))
('a', 'b', 'c')
>>> list(flatten(range(3)))
[0, 1, 2]
>>> flatten(range(1))
0

carabiner.cli module

Command-line interface for carabiner.

carabiner.cli.main() None[source]

carabiner.cliutils module

Utilities for constructing command-line interfaces.

class carabiner.cliutils.BaseCLIOption(args: ~typing.Iterable | None = <factory>, kwargs: ~typing.Mapping | None = <factory>)[source]

Bases: object

Store command-line option parameters.

Takes the same parameters as argparse.ArgumentParser().add_arguments(), but automatically appends defaults or “Required” to help string if not already included.

args: Iterable | None
kwargs: Mapping | None
class carabiner.cliutils.CLIApp(name: str, version: str, description: str | None = None, commands: ~typing.Iterable[~carabiner.cliutils.CLICommand] = <factory>)[source]

Bases: object

A command-line app.

Container for subcommands, which in turn contain options. Once assembled, the app can be run with the run() method.

Parameters:
  • name (str) – Name of the app.

  • version (str) – Version of the app.

  • description (str) – Help string.

  • commands (Iterable[CLICommand]) – Set of subcommands.

commands: Iterable[CLICommand]
description: str | None = None
name: str
run() None[source]

Run the app.

version: str
class carabiner.cliutils.CLICommand(name: str, description: str | None = None, options: ~typing.Iterable[~carabiner.cliutils.CLIOption] = <factory>, main: ~typing.Callable | None = None)[source]

Bases: object

Store parameters for a command-line app’s subcommands.

Parameters:
  • name (str) – Subcommand name.

  • description (str, optional) – Help string.

  • options (Iterable[CLIOption]) – Iterable of option objects.

  • main (Callable) – Function to run when this command is called.

description: str | None = None
main: Callable | None = None
name: str
options: Iterable[CLIOption]
class carabiner.cliutils.CLIOption(*args, **kwargs)[source]

Bases: BaseCLIOption

Store command-line option parameters.

Takes the same parameters as argparse.ArgumentParser().add_arguments(), but automatically appends defaults or “Required” to help string if not already included.

Provides a replace method so that options can be re-used but with a few parameters altered.

replace(**kwargs)[source]

Substitute named parameters and return a new CLIOPtion object

carabiner.cliutils.clicommand(main: Callable[[Namespace], None], message: str | None = None, name: str | None = None) Callable[[Namespace], None][source]

Convert a function to act informatively as the main function in a CLI app.

Parameters:
  • message (str, optional) – Message to prepend to reporting of parameters.

  • name (str, optional) – Name of the app.

Returns:

Decorator for function to be used as a main function in a CLI app.

Return type:

Callable

Examples

>>> from argparse import Namespace
>>> def main_func(args): print("Hello world!")
>>> args = Namespace(a=1, b="Testing")
>>> clicommand(main_func, name="Main program")(args)  
🚀 Processing with the following parameters:
        a: 1
        b: Testing
Hello world!
⏰ Completed Main program in 0:00:00.000132

carabiner.collections module

Useful data structures.

class carabiner.collections.MultiKeyDict(*args, **kwargs)[source]

Bases: UserDict

Dictionary where multiple keys can be accessed at once.

Examples

>>> d = MultiKeyDict(a=1, b=2, c=3)
>>> d
{'a': 1, 'b': 2, 'c': 3}
>>> d['c']
{'c': 3}
>>> d['a', 'b']
{'a': 1, 'b': 2}

carabiner.decorators module

Decorators to faciltiate functional programming.

carabiner.decorators.decorator_with_params(decorator: Callable[[Callable, Any], Callable]) Callable[[Callable, Any], Callable][source]

Convert a decorator to be used with optional parameters.

Can itself be used as a decorator.

The input decorator should take a function as its first argment, and further optional parameters. This decorator_with_params will return a decorator that can be used with or without specifying the optional parameters. (Normally this a very convoluted code.)

Parameters:

decorator (Callable) – Decorator to convert.

Returns:

Converted decorator.

Return type:

Callable

Examples

>>> def decor(f, suffix="World"): return lambda x: f(x + suffix)
...
>>> @decor
... def printer(x): print(x)
...
>>> @decor(suffix="everyone")
... def printer2(x): print(x)
...
Traceback (most recent call last):
    ...
TypeError: decor() missing 1 required positional argument: 'f'
>>> decor2 = decorator_with_params(decor)
>>> @decor2(suffix="everyone")
... def printer3(x): print(x)
...
>>> printer("Hello ")
Hello World
>>> printer3("Hello ")
Hello everyone
carabiner.decorators.return_none_on_error(f: Callable, exception: Exception | None = None) Callable[source]

Force a function to return None instead of raising an exception.

Parameters:
  • f (Callable, optional) – Function to convert. If not provided, returns a decorator.

  • exception (Exception, optional) – Exception type to bypass. Default: all exceptions.

Returns:

If f is provided, then decorated f. Otherwise returns a decorator.

Return type:

Callable

Examples

>>> def error_maker(x): raise KeyError
...
>>> @return_none_on_error
... def error_maker2(x): raise KeyError
...
>>> @return_none_on_error(exception=ValueError)
... def error_maker3(x): raise KeyError
...
>>> error_maker('a')
Traceback (most recent call last):
    ...
KeyError
>>> error_maker2('a')
>>> error_maker3('a')
Traceback (most recent call last):
    ...
KeyError
carabiner.decorators.vectorize(f: Callable) Callable[source]

Convert a scalar function into a vectorized mapping function.

The converted function returns a lazy iterable if passed an iterable, and a scalar if passed a scalar.

Parameters:

f (Callable) – Scalar function to convert.

Returns:

Vectorized function.

Return type:

Callable

Examples

>>> @vectorize
... def vector_adder(x): return x + 1
...
>>> list(vector_adder(range(3)))
[1, 2, 3]
>>> list(vector_adder((4, 5, 6)))
[5, 6, 7]
>>> vector_adder([10])
11
>>> vector_adder(10)
11

carabiner.itertools module

Utilities for iterables.

carabiner.itertools.batched(iterable: Iterable[Any], n: int) Iterable[Iterable[Any]][source]

Copy of the Python function for versions where it’s not available.

# batched(‘ABCDEFG’, 3) –> ABC DEF G

Parameters:
  • iterable (Iterable) – Iterable to batch.

  • n (int) – Batch size.

Returns:

Iterable of iterables with size n.

Return type:

Iterable

Examples

>>> for batch in batched('abcdef', 3): print(list(batch))
...
['a', 'b', 'c']
['d', 'e', 'f']
carabiner.itertools.tenumerate(x: Iterable[Any], *args, **kwargs) Iterable[Any][source]

Standard enumerate but with a progress bar.

Additional arguments are passed to tqdm.tqdm.

Parameters:

iterable (Iterable) – Iterable to enumerate.

Returns:

Iterable of tuples containing index and item.

Return type:

Iterable

carabiner.random module

Tools for randomness.

carabiner.random.random() x in the interval [0, 1).
carabiner.random.sample_iter(iterable: Iterable, k: int = 1, shuffle_output: bool = True) List[source]

Random sampling from an iterable of unknown length without needing it to be held entirely in memory.

This allows sampling from an iterable without needing the iterable to be held entirely in memory at one time and without knowing the length of the iterable ahead of time. A typical case might be selecting lines from a large text file while reading the file in a single pass.

One limitation is that the sampled population must fit in memory.

Based in Reservoir Sampling: https://en.wikipedia.org/wiki/Reservoir_sampling

Originally written here: https://bugs.python.org/issue41311

Based on GitHub Gist: https://gist.github.com/oscarbenjamin/4c1b977181f34414a425f68589e895d1

Parameters:
  • iterable (Iterable) – Sequence of items which may or may not be held in memory.

  • k (int, optional) – Number of items to sample. Default: 1.

  • shuffle_output (bool, optional) – Return items in random order (default). Otherwise return in original order.

Returns:

Sequence sampled from iterable.

Return type:

list

Examples

>>> from string import ascii_letters
>>> from itertools import chain
>>> from random import seed
>>> seed(1)
>>> sample_iter(chain.from_iterable(ascii_letters for _ in range(1000000)), 10)
['X', 'c', 'w', 'q', 'T', 'e', 'u', 'w', 'E', 'h']
>>> seed(1)
>>> sample_iter(chain.from_iterable(ascii_letters for _ in range(1000000)), 10, shuffle_output=False)
['T', 'h', 'u', 'X', 'E', 'e', 'w', 'q', 'c', 'w']

carabiner.utils module

Miscellaneous utilities.

carabiner.utils.colorblind_palette(i: Any | None = None, name: str = 'vibrant') Tuple[str][source]

Provide hexadecimal codes for Tol’s colorblind-friendly qualitative palette.

Parameters:

i (int, slice, iterable, optional) – Index(es) of colors to return. If not supplied, returns all.

Returns:

Sequence of colors encoded as hexadecimals.

Return type:

tuple

Raises:

NotImplementedError – If i is not an integer, slice, or iterable.

Examples

>>> colorblind_palette(range(2), name="vibrant_0")
('#EE7733', '#0077BB')
>>> colorblind_palette(range(2))
('#0077BB', '#33BBEE')
>>> colorblind_palette(slice(3, 6))
('#EE7733', '#CC3311', '#EE3377')
>>> colorblind_palette(name="vibrant_0")
('#EE7733', '#0077BB', '#33BBEE', '#EE3377', '#CC3311', '#009988', '#BBBBBB', '#000000')
>>> colorblind_palette(name="muted")
('#332288', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', '#CC6677', '#882255', '#AA4499', '#DDDDDD')
carabiner.utils.pprint_dict(object: Mapping, message: str | None = None) None[source]

Pretty-print a dictionary to stderr, optionally prepended with a message.

Can accept either a dictionary or an object with a __dict__ attribute. Useful for summarizing command line arguments.

Parameters:
  • object (dict or object) – Dictionary or object to print.

  • message (str, optional) – Message to prepend.

Raises:

TypeError – If object is not a dictionary or not an object with a __dict__ attribute.

Examples

>>> d = {"option A": 1, "option B": True, "option C": "Nothing"}
>>> pprint_dict(d)  
        option A: 1
        option B: True
        option C: Nothing
>>> pprint_dict(d, message="Your options")  
Your options:
        option A: 1
        option B: True
        option C: Nothing
carabiner.utils.print_err(*args, **kwargs) None[source]

Print to stderr instead of stdout.

Arguments are passed to standard print.

Return type:

None

Examples

>>> print_err("Hello world!")  
Hello world!
>>> print_err("Hello world!", end='~\n')  
Hello world!~
>>> print_err("Hello", "world!", end='~\n')  
Hello world!~
carabiner.utils.upper_and_lower(x: Iterable[str], sort: bool = True) Tuple[str][source]

Convert a list of strings into the unique set of uppercase and lowercase versions.

Useful for listing command-line options which are case-insensitive.

Parameters:
  • x (Iterable of strings) – Strings to convert.

  • sort (bool, optional) – Whether to sort the output. Default: True

Returns:

Set of unique lowercase and uppercase strings.

Return type:

tuple

Examples

>>> upper_and_lower(["A", "B"])
('A', 'B', 'a', 'b')
>>> upper_and_lower(["Cat", "dog"])
('CAT', 'Cat', 'DOG', 'cat', 'dog')

Module contents