big 0.13
The big package is a grab-bag of cool code for use in your programs.
Requires Python: >=3.6

![# big](https://raw.githubusercontent.com/larryhastings/big/master/resources/images/big.header.png)

##### Copyright 2022-2026 by Larry Hastings

[![# test badge](https://img.shields.io/github/actions/workflow/status/larryhastings/big/test.yml?branch=master&label=test)](https://github.com/larryhastings/big/actions/workflows/test.yml) [![# coverage badge](https://img.shields.io/github/actions/workflow/status/larryhastings/big/coverage.yml?branch=master&label=coverage)](https://github.com/larryhastings/big/actions/workflows/coverage.yml) [![# python versions badge](https://img.shields.io/pypi/pyversions/big.svg?logo=python&logoColor=FBE072)](https://pypi.org/project/big/)


**big** is a Python package of small functions and classes
that aren't big enough to get a package of their own.
It's zillions of useful little bits of
Python code I always want to have handy.

For years, I've copied-and-pasted all my little
helper functions between projects--we've all done it.
But now I've finally taken the time to consolidate all those
useful little functions into one *big* package--no more
copy-and-paste, I just install one package and I'm ready to go.
And, since it's a public package, you can use 'em too!

Not only that, but I've taken my time and re-thought and
retooled a lot of this code.  All the difficult-to-use,
overspecialized, cheap hacks I've lived with for years have
been upgraded with elegant, intuitive APIs and dazzling
functionality.
**big** is chock full of the sort of little functions and classes
we've all hacked together a million times--only with all the
API gotchas fixed, and thoroughly tested with 100% coverage.
It's the missing batteries Python never shippet.
It's the code you *would* have written... if only you had the time.
And every API is a pleasure to use!

**big** requires Python 3.6 or newer.  It has no
required dependencies to run.  (**big**'s test suite
havs a few external dependencies, but **big** itself will
run fine without them.)
**big** is 100% pure Python code--no C extension
needed, no compilation step.

The current version is [0.13.](#013)

*Think big!*

## Why use big?

It's true that much of the code in **big** is short,
and one might reasonably have the reaction
"that's so short, it's easier to write it from scratch
every time I need it than remember where it is and how
to call it".  I still see value in these short functions
in **big** because:

1. everything in **big** is tested,
2. every interface in **big** has been thoughtfully
   considered and designed.

For example, consider
[`Log(*destinations, **options)`](#logdestinations-options).
It's easy to write a quick little disposable log function.
I should know; I've done it myself, many times.
But big's `Log` class is feature-rich, thoroughly debugged,
and lightning fast.  Rather than waste your time hacking
together something cheap, just use big!


## Using big

To use **big**, just install the **big** package (and its dependencies)
from PyPI using your favorite Python package manager.

Once **big** is installed, you can simply import it.  However, the
top-level **big** package doesn't contain anything but a version number.
Internally **big** is broken up into submodules, aggregated together
loosely by problem domain, and you can selectively import just the
functions you want.  For example, if you only want to use the text functions,
just import the **text** submodule:

```Python
import big.text
```

If you'd prefer to import everything all at once, simply import the
**big.all** module.  This one module imports all the other modules,
and imports all their symbols too.  So, one convenient way to work
with **big** is this:

```Python
import big.all as big
```

That will make every symbol defined in **big** accessible from the `big`
object. For example, if you want to use
[`multisplit`,](#multisplits-separatorsnone--keepfalse-maxsplit-1-reversefalse-separatefalse-stripfalse)
you can access it with just `big.multisplit`.

You can also use **big.all** with `import *`:

```Python
from big.all import *
```

but that's up to you.  Me, I generally use `import big.all as big` .

**big** is licensed using the
[MIT license.](https://opensource.org/licenses/MIT)
You're free to use it and even ship it in your own programs,
as long as you leave my copyright notice on the source code.

## The best of big

Although **big** is *crammed full* of fabulous code, a few of
its subsystems rise above the rest.  If you're curious what
**big** might do for you, here are the six things in **big**
I'm proudest of:

* [**`linked_list`**](#linked_list)
* [**`string`**](#string)
* [**Bound inner classes**](#bound-inner-classes)
* [**The `multi-` family of string functions**](#The-multi--family-of-string-functions)
* [`big.state`](#bigstate)
* [**Enhanced `TopologicalSorter`**](#enhanced-topologicalsorter)

And here are six little functions/classes I use all the time:

* [`eval_template_string`](#eval_template_strings-globals-localsnone--parse_expressionstrue-parse_commentsfalse-parse_whitespace_eaterfalse)
* [`iterator_context`](#iterator_contextiterator-start0)
* [`Log`](#logdestinations-options)
* [`ModuleManager`](#ModuleManager)
* [`pushd`](#pushddirectory)
* [`re_partition`](#re_partitiontext-pattern-count1--flags0-reversefalse)


# Index

### Modules

<dl><dd>

[`big.all`](#bigall)

[`big.boundinnerclass`](#bigboundinnerclass)

[`big.builtin`](#bigbuiltin)

[`big.deprecated`](#bigdeprecated)

[`big.file`](#bigfile)

[`big.graph`](#biggraph)

[`big.heap`](#bigheap)

[`big.itertools`](#bigitertools)

[`big.log`](#biglog)

[`big.metadata`](#bigmetadata)

[`big.scheduler`](#bigscheduler)

[`big.state`](#bigstate)

[`big.template`](#bigtemplate)

[`big.text`](#bigtext)

[`big.time`](#bigtime)

[`big.tokens`](#bigtokens)

[`big.types`](#bigtypes)

[`big.version`](#bigversion)

</dd></dl>

### Functions, classes, and values

<dl><dd>

[`accessor(attribute='state', state_manager='state_manager')`](#accessorattributestate-state_managerstate_manager)

[`ascii_linebreaks`](#ascii_linebreaks)

[`ascii_linebreaks_without_crlf`](#ascii_linebreaks_without_crlf)

[`ascii_whitespace`](#ascii_whitespace)

[`ascii_whitespace_without_crlf`](#ascii_whitespace_without_crlf)

[`bound_inner_base(cls)`](#bound_inner_basecls)

[`BoundInnerClass`](#boundinnerclasscls)

[`BOUNDINNERCLASS_OUTER_ATTR`](#boundinnerclass_outer_attr)

[`BOUNDINNERCLASS_OUTER_SLOTS`](#boundinnerclass_outer_slots)

[`bound_to(cls)`](#bound_tocls)

[`bytes_linebreaks`](#bytes_linebreaks)

[`bytes_linebreaks_without_crlf`](#bytes_linebreaks_without_crlf)

[`bytes_whitespace`](#bytes_whitespace)

[`bytes_whitespace_without_crlf`](#bytes_whitespace_without_crlf)

[`combine_splits(s, *split_arrays)`](#combine_splitss-split_arrays)

[`ClassRegistry()`](#classregistry)

[`CycleError()`](#cycleerror)

[`date_ensure_timezone(d, timezone)`](#date_ensure_timezoned-timezone)

[`date_set_timezone(d, timezone)`](#date_set_timezoned-timezone)

[`datetime_ensure_timezone(d, timezone)`](#datetime_ensure_timezoned-timezone)

[`datetime_set_timezone(d, timezone)`](#datetime_set_timezoned-timezone)

[`default_clock()`](#default_clock)

[`decode_python_script(script, *, newline=None, use_bom=True, use_source_code_encoding=True)`](#decode_python_scriptscript--newlinenone-use_bomtrue-use_source_code_encodingtrue)

[`Delimiter(close, *, escape='', multiline=True, quoting=False)`](#delimiterclose--escape-multilinetrue-quotingfalse)

[`dispatch(state_manager='state_manager', *, prefix='', suffix='')`](#dispatchstate_managerstate_manager--prefix-suffix)

[`encode_strings(o, *, encoding='ascii')`](#encode_stringso--encodingascii)

[`Event(scheduler, event, time, priority, sequence)`](#eventscheduler-event-time-priority-sequence)

[`Event.cancel()`](#eventcancel)

[`eval_template_string(s, globals, locals=None, *, ...)`](#eval_template_strings-globals-localsnone--parse_expressionstrue-parse_commentsfalse-parse_whitespace_eaterfalse)

[`fgrep(path, text, *, encoding=None, enumerate=False, case_insensitive=False)`](#fgreppath-text--encodingnone-enumeratefalse-case_insensitivefalse)

[`file_mtime(path)`](#file_mtimepath)

[`file_mtime_ns(path)`](#file_mtime_nspath)

[`file_size(path)`](#file_sizepath)

[`format_map(s, mapping)`](#format_maps-mapping)

[`generate_tokens(s)`](#generate_tokenss)

[`gently_title(s, *, apostrophes=None, double_quotes=None)`](#gently_titles--apostrophesnone-double_quotesnone)

[`get_float(o, default=_sentinel)`](#get_floato-default_sentinel)

[`get_int(o, default=_sentinel)`](#get_into-default_sentinel)

[`get_int_or_float(o, default=_sentinel)`](#get_int_or_floato-default_sentinel)

[`grep(path, pattern, *, encoding=None, enumerate=False, flags=0)`](#greppath-pattern--encodingnone-enumeratefalse-flags0)

[`Heap(i=None)`](#heapinone)

[`Heap.append(o)`](#heapappendo)

[`Heap.clear()`](#heapclear)

[`Heap.copy()`](#heapcopy)

[`Heap.extend(i)`](#heapextendi)

[`Heap.remove(o)`](#heapremoveo)

[`Heap.popleft()`](#heappopleft)

[`Heap.append_and_popleft(o)`](#heapappend_and_poplefto)

[`Heap.popleft_and_append(o)`](#heappopleft_and_appendo)

[`Heap.queue`](#heapqueue)

[`int_to_words(i, *, flowery=True, ordinal=False)`](#int_to_wordsi--flowerytrue-ordinalfalse)

[`Interpolation(expression, *filters, debug='')`](#interpolationexpression-filters-debug)

[`is_bound(cls)`](#is_boundcls)

[`is_boundinnerclass(cls)`](#is_boundinnerclasscls)

[`is_unboundinnerclass(cls)`](#is_unboundinnerclasscls)

[`IteratorContext`](#iterator_contextiterator-start0)

[`iterator_context(iterator, start=0)`](#iterator_contextiterator-start0)

[`iterator_filter(iterator, *, ...)`](#iterator_filteriterator--stop_at_valueundefined-stop_at_innone-stop_at_predicatenone-stop_at_countnone-reject_valueundefined-reject_innone-reject_predicatenone-only_valueundefined-only_innone-only_predicatenone)

[`linebreaks`](#linebreaks)

[`linebreaks_without_crlf`](#linebreaks_without_crlf)

[`linked_list(iterable=(), *, lock=None)`](#linked_listiterable--locknone)

[`linked_list.append(object)`](#linked_listappendobject)

[`linked_list.clear()`](#linked_listclear)

[`linked_list.copy(*, lock=None)`](#linked_listcopy-locknone)

[`linked_list.count(value)`](#linked_listcountvalue)

[`linked_list.cut(start=None, stop=None, *, lock=None)`](#linked_listcutstartnone-stopnone--locknone)

[`linked_list.extend(iterable)`](#linked_listextenditerable)

[`linked_list.extendleft(iterable)`](#linked_listextendleftiterable)

[`linked_list.find(value)`](#linked_listfindvalue)

[`linked_list.index(value, start=0, stop=sys.maxsize)`](#linked_listindexvalue-start0-stopsysmaxsize)

[`linked_list.insert(index, object)`](#linked_listinsertindex-object)

[`linked_list.match(predicate)`](#linked_listmatchpredicate)

[`linked_list.pop(index=-1)`](#linked_listpopindex-1)

[`linked_list.prepend(object)`](#linked_listprependobject)

[`linked_list.rcount(value)`](#linked_listrcountvalue)

[`linked_list.rcut(start=None, stop=None, *, lock=None)`](#linked_listrcutstartnone-stopnone--locknone)

[`linked_list.remove(value, default=undefined)`](#linked_listremovevalue-defaultundefined)

[`linked_list.reverse()`](#linked_listreverse)

[`linked_list.rextend(iterable)`](#linked_listrextenditerable)

[`linked_list.rfind(value)`](#linked_listrfindvalue)

[`linked_list.rmatch(predicate)`](#linked_listrmatchpredicate)

[`linked_list.rotate(n)`](#linked_listrotaten)

[`linked_list.rpop(index=0)`](#linked_listrpopindex0)

[`linked_list.rremove(value, default=undefined)`](#linked_listrremovevalue-defaultundefined)

[`linked_list.rsplice(other, *, where=None)`](#linked_listrspliceother--wherenone)

[`linked_list.sort(key=None, reverse=False)`](#linked_listsortkeynone-reversefalse)

[`linked_list.splice(other, *, where=None)`](#linked_listspliceother--wherenone)

[`linked_list.tail()`](#linked_listtail)

[`linked_list_iterator`](#linked_list_iterator)

[`linked_list_iterator.after(count=1)`](#linked_list_iteratoraftercount1)

[`linked_list_iterator.append(value)`](#linked_list_iteratorappendvalue)

[`linked_list_iterator.before(count=1)`](#linked_list_iteratorbeforecount1)

[`linked_list_iterator.copy()`](#linked_list_iteratorcopy)

[`linked_list_iterator.count(value)`](#linked_list_iteratorcountvalue)

[`linked_list_iterator.cut(stop=None, *, lock=None)`](#linked_list_iteratorcutstopnone--locknone)

[`linked_list_iterator.exhaust()`](#linked_list_iteratorexhaust)

[`linked_list_iterator.extend(iterable)`](#linked_list_iteratorextenditerable)

[`linked_list_iterator.find(value)`](#linked_list_iteratorfindvalue)

[`linked_list_iterator.insert(index, object)`](#linked_list_iteratorinsertindex-object)

[`linked_list_iterator.is_special()`](#linked_list_iteratoris_special)

[`linked_list_iterator.linked_list`](#linked_list_iteratorlinked_list)

[`linked_list_iterator.match(predicate)`](#linked_list_iteratormatchpredicate)

[`linked_list_iterator.next(default=undefined, *, count=1)`](#linked_list_iteratornextdefaultundefined--count1)

[`linked_list_iterator.pop(index=0)`](#linked_list_iteratorpopindex0)

[`linked_list_iterator.prepend(value)`](#linked_list_iteratorprependvalue)

[`linked_list_iterator.previous(default=undefined, *, count=1)`](#linked_list_iteratorpreviousdefaultundefined--count1)

[`linked_list_iterator.rcount(value)`](#linked_list_iteratorrcountvalue)

[`linked_list_iterator.rcut(stop=None, *, lock=None)`](#linked_list_iteratorrcutstopnone--locknone)

[`linked_list_iterator.remove(value, default=undefined)`](#linked_list_iteratorremovevalue-defaultundefined)

[`linked_list_iterator.reset()`](#linked_list_iteratorreset)

[`linked_list_iterator.rextend(iterable)`](#linked_list_iteratorrextenditerable)

[`linked_list_iterator.rfind(value)`](#linked_list_iteratorrfindvalue)

[`linked_list_iterator.rmatch(predicate)`](#linked_list_iteratorrmatchpredicate)

[`linked_list_iterator.rpop(index=0)`](#linked_list_iteratorrpopindex0)

[`linked_list_iterator.rremove(value, default=undefined)`](#linked_list_iteratorrremovevalue-defaultundefined)

[`linked_list_iterator.rsplice(other)`](#linked_list_iteratorrspliceother)

[`linked_list_iterator.rtruncate()`](#linked_list_iteratorrtruncate)

[`linked_list_iterator.special()`](#linked_list_iteratorspecial)

[`linked_list_iterator.splice(other)`](#linked_list_iteratorspliceother)

[`linked_list_iterator.truncate()`](#linked_list_iteratortruncate)

[`linked_list_reverse_iterator`](#linked_list_reverse_iterator)

[`linked_list_reverse_iterator.after(count=1)`](#linked_list_reverse_iteratoraftercount1)

[`linked_list_reverse_iterator.append(value)`](#linked_list_reverse_iteratorappendvalue)

[`linked_list_reverse_iterator.before(count=1)`](#linked_list_reverse_iteratorbeforecount1)

[`linked_list_reverse_iterator.copy()`](#linked_list_reverse_iteratorcopy)

[`linked_list_reverse_iterator.count(value)`](#linked_list_reverse_iteratorcountvalue)

[`linked_list_reverse_iterator.cut(stop=None, *, lock=None)`](#linked_list_reverse_iteratorcutstopnone--locknone)

[`linked_list_reverse_iterator.exhaust()`](#linked_list_reverse_iteratorexhaust)

[`linked_list_reverse_iterator.extend(iterable)`](#linked_list_reverse_iteratorextenditerable)

[`linked_list_reverse_iterator.find(value)`](#linked_list_reverse_iteratorfindvalue)

[`linked_list_reverse_iterator.insert(index, object)`](#linked_list_reverse_iteratorinsertindex-object)

[`linked_list_reverse_iterator.is_special()`](#linked_list_reverse_iteratoris_special)

[`linked_list_reverse_iterator.linked_list`](#linked_list_reverse_iteratorlinked_list)

[`linked_list_reverse_iterator.match(predicate)`](#linked_list_reverse_iteratormatchpredicate)

[`linked_list_reverse_iterator.next(default=undefined, *, count=1)`](#linked_list_reverse_iteratornextdefaultundefined--count1)

[`linked_list_reverse_iterator.pop(index=0)`](#linked_list_reverse_iteratorpopindex0)

[`linked_list_reverse_iterator.prepend(value)`](#linked_list_reverse_iteratorprependvalue)

[`linked_list_reverse_iterator.previous(default=undefined, *, count=1)`](#linked_list_reverse_iteratorpreviousdefaultundefined--count1)

[`linked_list_reverse_iterator.rcount(value)`](#linked_list_reverse_iteratorrcountvalue)

[`linked_list_reverse_iterator.rcut(stop=None, *, lock=None)`](#linked_list_reverse_iteratorrcutstopnone--locknone)

[`linked_list_reverse_iterator.remove(value, default=undefined)`](#linked_list_reverse_iteratorremovevalue-defaultundefined)

[`linked_list_reverse_iterator.reset()`](#linked_list_reverse_iteratorreset)

[`linked_list_reverse_iterator.rextend(iterable)`](#linked_list_reverse_iteratorrextenditerable)

[`linked_list_reverse_iterator.rfind(value)`](#linked_list_reverse_iteratorrfindvalue)

[`linked_list_reverse_iterator.rmatch(predicate)`](#linked_list_reverse_iteratorrmatchpredicate)

[`linked_list_reverse_iterator.rpop(index=0)`](#linked_list_reverse_iteratorrpopindex0)

[`linked_list_reverse_iterator.rremove(value, default=undefined)`](#linked_list_reverse_iteratorrremovevalue-defaultundefined)

[`linked_list_reverse_iterator.rsplice(other)`](#linked_list_reverse_iteratorrspliceother)

[`linked_list_reverse_iterator.rtruncate()`](#linked_list_reverse_iteratorrtruncate)

[`linked_list_reverse_iterator.special()`](#linked_list_reverse_iteratorspecial)

[`linked_list_reverse_iterator.splice(other)`](#linked_list_reverse_iteratorspliceother)

[`linked_list_reverse_iterator.truncate()`](#linked_list_reverse_iteratortruncate)

[`Log(*destinations, **options)`](#logdestinations-options)

[`Log.box(s)`](#logboxs)

[`Log.Callable(callable)`](#logcallablecallable)

[`Log.close(block=True)`](#logcloseblocktrue)

[`Log.Destination`](#logdestination)

[`Log.Destination.Buffer(destination=None)`](#logdestinationbufferdestinationnone)

[`Log.enter(message)`](#logentermessage)

[`Log.exit()`](#logexit)

[`Log.File(path, initial_mode="at", *, flush=False)`](#logfilepath-initial_modeat--flushfalse)

[`Log.FileHandle(handle, *, flush=False)`](#logfilehandlehandle--flushfalse)

[`Log.flush(block=True)`](#logflushblocktrue)

[`Log.List(list)`](#loglistlist)

[`Log.map_destination(o)`](#logmap_destinationo)

[`Log.print(*args, end='\n', sep=' ', flush=False, format='print')`](#logprintargs-endn-sep--flushfalse-formatprint)

[`Log.Print()`](#logprint)

[`Log.reset()`](#logreset)

[`Log.Sink()`](#logsink)

[`Log.TmpFile(*, flush=False)`](#logtmpfile-flushfalse)

[`Log.write(formatted)`](#logwriteformatted)

[`merge_columns(*columns, column_separator=" ", overflow_response=OverflowResponse.RAISE, overflow_before=0, overflow_after=0)`](#merge_columnscolumns-column_separator--overflow_responseoverflowresponseraise-overflow_before0-overflow_after0)

[`metadata.version`](#metadataversion)

[`ModuleManager()`](#modulemanager)

[`multipartition(s, separators, count=1, *, reverse=False, separate=True)`](#multipartitions-separators-count1--reversefalse-separatetrue)

[`multisplit(s, separators, *, keep=False, maxsplit=-1, reverse=False, separate=False, strip=False)`](#multisplits-separatorsnone--keepfalse-maxsplit-1-reversefalse-separatefalse-stripfalse)

[`multistrip(s, separators, left=True, right=True)`](#multistrips-separators-lefttrue-righttrue)

[`normalize_whitespace(s, separators=None, replacement=None)`](#normalize_whitespaces-separatorsnone-replacementnone)

[`OldDestination()`](#olddestination)

[`OldLog(clock=None)`](#oldlogclocknone)

[`parse_template_string(s, *, ...)`](#parse_template_strings--parse_expressionstrue-parse_commentsfalse-parse_statementsfalse-parse_whitespace_eaterfalse-quotes--multiline_quotes-escape)

[`parse_timestamp_3339Z(s, *, timezone=None)`](#parse_timestamp_3339zs--timezonenone)

[`Pattern(s, flags=0)`](#patterns-flags0)

[`pure_virtual()`](#pure_virtual)

[`PushbackIterator(iterable=None)`](#pushbackiteratoriterablenone)

[`PushbackIterator.next(default=None)`](#pushbackiteratornextdefaultnone)

[`PushbackIterator.push(o)`](#pushbackiteratorpusho)

[`prefix_format(time_seconds_width, time_fractional_width, thread_name_width=12)`](#prefix_formattime_seconds_width-time_fractional_width-thread_name_width12)

[`pushd(directory)`](#pushddirectory)

[`python_delimiters`](#python_delimiters)

[`python_delimiters_version`](#python_delimiters_version)

[`read_python_file(path, *, newline=None, use_bom=True, use_source_code_encoding=True)`](#read_python_filepath--newlinenone-use_bomtrue-use_source_code_encodingtrue)

[`re_partition(text, pattern, count=1, *, flags=0, reverse=False)`](#re_partitiontext-pattern-count1--flags0-reversefalse)

[`re_rpartition(text, pattern, count=1, *, flags=0)`](#re_rpartitiontext-pattern-count1--flags0)

[`Regulator()`](#regulator)

[`Regulator.lock`](#regulatorlock)

[`Regulator.now()`](#regulatornow)

[`Regulator.sleep(t)`](#regulatorsleept)

[`Regulator.wake()`](#regulatorwake)

[`reversed_re_finditer(pattern, string, flags=0)`](#reversed_re_finditerpattern-string-flags0)

[`safe_mkdir(path)`](#safe_mkdirpath)

[`safe_unlink(path)`](#safe_unlinkpath)

[`Scheduler(regulator=default_regulator)`](#schedulerregulatordefault_regulator)

[`Scheduler.schedule(o, time, *, absolute=False, priority=DEFAULT_PRIORITY)`](#schedulerscheduleo-time--absolutefalse-prioritydefault_priority)

[`Scheduler.cancel(event)`](#schedulercancelevent)

[`Scheduler.queue`](#schedulerqueue)

[`Scheduler.non_blocking()`](#schedulernon_blocking)

[`search_path(paths, extensions=('',), *, case_sensitive=None, preserve_extension=True, want_directories=False, want_files=True)`](#search_pathpaths-extensions--case_sensitivenone-preserve_extensiontrue-want_directoriesfalse-want_filestrue)

[`SingleThreadedRegulator()`](#singlethreadedregulator)

[`split_delimiters(s, delimiters={...}, *, state=(), yields=None)`](#split_delimiterss-delimiters--state-yieldsnone)

[`split_quoted_strings(s, quotes=('"', "'"), *, escape='\\', multiline_quotes=(), state='')`](#split_quoted_stringss-quotes---escape-multiline_quotes-state)

[`split_text_with_code(s, *, tab_width=8, allow_code=True, code_indent=4, convert_tabs_to_spaces=True)`](#split_text_with_codes--tab_width8-allow_codetrue-code_indent4-convert_tabs_to_spacestrue)

[`split_title_case(s, *, split_allcaps=True)`](#split_title_cases--split_allcapstrue)

[`SinkEvent`](#sinkevent)

[`SinkEndEvent`](#sinkendevent)

[`SinkEnterEvent`](#sinkenterevent)

[`SinkExitEvent`](#sinkexitevent)

[`SinkLogEvent`](#sinklogevent)

[`SinkStartEvent`](#sinkstartevent)

[`SinkWriteEvent`](#sinkwriteevent)

[`SpecialNodeError`](#specialnodeerror)

[`State()`](#state)

[`StateManager(state, *, on_enter='on_enter', on_exit='on_exit', state_class=None)`](#statemanagerstate--on_enteron_enter-on_exiton_exit-state_classnone)

[`Statement(statement)`](#statementstatement)

[`string(s='', *, ...)`](#strings--sourcenone-line_number1-column_number1-first_column_number1-tab_width8)

[`string.bisect(index)`](#stringbisectindex)

[`string.cat(*strings)`](#stringcatstrings)

[`string.compile(flags=0)`](#stringcompileflags0)

[`string.generate_tokens()`](#stringgenerate_tokens)

[`strip_indents(lines, *, tab_width=8, linebreaks=linebreaks)`](#strip_indentslines--tab_width8-linebreakslinebreaks)

[`strip_line_comments(lines, line_comment_markers, *, escape='\\', quotes=(), multiline_quotes=(), linebreaks=linebreaks)`](#strip_line_commentslines-line_comment_markers--escape-quotes-multiline_quotes-linebreakslinebreaks)

[`str_linebreaks`](#str_linebreaks)

[`str_linebreaks_without_crlf`](#str_linebreaks_without_crlf)

[`str_whitespace`](#str_whitespace)

[`str_whitespace_without_crlf`](#str_whitespace_without_crlf)

[`timestamp_3339Z(t=None, want_microseconds=None)`](#timestamp_3339ztnone-want_microsecondsnone)

[`timestamp_human(t=None, want_microseconds=None, *, tzinfo=None)`](#timestamp_humantnone-want_microsecondsnone--tzinfonone)

[`ThreadSafeRegulator()`](#threadsaferegulator)

[`TMPFILE`](#tmpfile)

[`TopologicalSorter(graph=None)`](#topologicalsortergraphnone)

[`TopologicalSorter.copy()`](#topologicalsortercopy)

[`TopologicalSorter.cycle()`](#topologicalsortercycle)

[`TopologicalSorter.print()`](#topologicalsorterprintprintprint)

[`TopologicalSorter.remove(node)`](#topologicalsorterremovenode)

[`TopologicalSorter.reset()`](#topologicalsorterreset)

[`TopologicalSorter.View`](#topologicalsorterview-1)

[`TopologicalSorter.view()`](#topologicalsorterview)

[`TopologicalSorter.View.close()`](#topologicalsorterviewclose)

[`TopologicalSorter.View.copy()`](#topologicalsorterviewcopy)

[`TopologicalSorter.View.done(*nodes)`](#topologicalsorterviewdonenodes)

[`TopologicalSorter.View.print(print=print)`](#topologicalsorterviewprintprintprint)

[`TopologicalSorter.View.ready()`](#topologicalsorterviewready)

[`TopologicalSorter.View.reset()`](#topologicalsorterviewreset)

[`touch(path)`](#touchpath)

[`TransitionError`](#transitionerror)

[`translate_filename_to_exfat(s)`](#translate_filename_to_exfats)

[`translate_filename_to_unix(s)`](#translate_filename_to_unixs)

[`try_float(o)`](#try_floato)

[`try_int(o)`](#try_into)

[`type_bound_to(instance)`](#type_bound_toinstance)

[`unbound(cls)`](#unboundcls)

[`UnboundInnerClass`](#unboundinnerclasscls)

[`UndefinedIndexError`](#undefinedindexerror)

[`unicode_linebreaks`](#unicode_linebreaks)

[`unicode_linebreaks_without_crlf`](#unicode_linebreaks_without_crlf)

[`unicode_whitespace`](#unicode_whitespace)

[`unicode_whitespace_without_crlf`](#unicode_whitespace_without_crlf)

[`Version(s=None, *, epoch=None, release=None, release_level=None, serial=None, post=None, dev=None, local=None)`](#versionsnone--epochnone-releasenone-release_levelnone-serialnone-postnone-devnone-localnone)

[`Version.format(s)`](#versionformats)

[`whitespace`](#whitespace)

[`whitespace_without_crlf`](#whitespace_without_crlf)

[`wrap_words(words, margin=79, *, two_spaces=True)`](#wrap_wordswords-margin79--two_spacestrue)

</dd></dl>

### Tutorials

<dl><dd>

[**The `multi-` family of string functions**](#The-multi--family-of-string-functions)

[**Whitespace and line-breaking characters in Python and big**](#whitespace-and-line-breaking-characters-in-python-and-big)

[**Word wrapping and formatting**](#word-wrapping-and-formatting)

[**Bound inner classes**](#bound-inner-classes)

[**Enhanced `TopologicalSorter`**](#enhanced-topologicalsorter)

</dd></dl>


# API Reference, By Module


## `big.all`

<dl><dd>

This submodule doesn't define any of its own symbols.  Instead, it
imports every other submodule in **big**, and uses `import *` to
import every symbol from every other submodule, too.  Every
public symbol in **big** is available in `big.all`.

When I'm using big in my own projects, I tend to import it as

```Python
import big.all as big
```

That way, all big's symbols are available as one big flat namespace.


</dd></dl>

## `big.boundinnerclass`

<dl><dd>

Class decorators that implement bound inner classes.  See the
[**Bound inner classes**](#bound-inner-classes)
tutorial for more information.

</dd></dl>

#### `BoundInnerClass(cls)`

<dl><dd>

Class decorator for an inner class.  When accessing the inner class
through an instance of the outer class, "binds" the inner class to
the instance.  This changes the signature of the inner class's `__init__`
from
```Python
def __init__(self, *args, **kwargs):`
```
to
```Python
def __init__(self, outer, *args, **kwargs):
```
where `outer` is the instance of the outer class.

Compare this to functions:

* If you put a *function* inside a class,
  and access it through an instance *I* of that class,
  the *function* becomes a *method.*  When you call
  the *method,* *I* is automatically passed in as the
  first argument.
* If you put a *class* inside a class,
  and access it through an instance of that class,
  the *class* becomes a *bound inner class.*  When
  you call the *bound inner class,* *I* is automatically
  passed in as the second argument to `__init__`,
  after `self`.

Note that this has an implication for all subclasses.
If class ***B*** is decorated with `BoundInnerClass`,
and class ***S*** is a subclass of ***B***, such that
`issubclass(`***S***`, `***B***`)`,
class ***S*** *must* be decorated with either
`BoundInnerClass` or `UnboundInnerClass`.
</dd></dl>

#### `UnboundInnerClass(cls)`

<dl><dd>

Class decorator for an inner class that prevents binding
the inner class to an instance of the outer class.

If class ***B*** is decorated with `BoundInnerClass`,
and class ***S*** is a subclass of ***B***, such that
`issubclass(`***S***`, `***B***`)` returns `True`,
class ***S*** *must* be decorated with either
`BoundInnerClass` or `UnboundInnerClass`.
</dd></dl>

#### `bound_inner_base(cls)`

<dl><dd>
Simple wrapper for Python 3.6 compatibility for bound inner classes.

Returns the base class for declaring a subclass of a
bound inner class while still in the outer class scope.
Only needed for Python 3.6 compatibility; unnecessary
in Python 3.7+, or when the child class is defined
after exiting the outer class scope.

See the [**Bound inner classes**](#bound-inner-classes) tutorial for more information.
</dd></dl>

#### `bound_to(cls)`

<dl><dd>

Returns the outer instance that `cls` is bound to, or `None`.

If `cls` is a bindable inner class that was bound to an outer
instance, returns that outer instance.  If `cls` is any other
variety of type object, returns `None`.  Raises `TypeError` if
`cls` is not a class object.

[`BoundInnerClass`](#boundinnerclasscls) doesn't keep strong
references to outer instances.  If `cls` was bound to an object
that has since been destroyed, `bound_to` will return `None`.

See the [**Bound inner classes**](#bound-inner-classes) tutorial for more information.
</dd></dl>

#### `BOUNDINNERCLASS_OUTER_ATTR`

<dl><dd>

A string constant containing the attribute name that
[`BoundInnerClass`](#boundinnerclasscls) uses to store
its per-instance cache on the outer instance.
If your outer class uses `__slots__`, you must include
this attribute in your slots definition.

However, rather than using this attribute directly,
we suggest you use [`BOUNDINNERCLASS_OUTER_SLOTS`](#boundinnerclass_outer_slots)
to add the necessary attribute to your `__slots__` tuple.

See the [**Bound inner classes**](#bound-inner-classes) tutorial for more information.
</dd></dl>

#### `BOUNDINNERCLASS_OUTER_SLOTS`

<dl><dd>

A tuple containing [`BOUNDINNERCLASS_OUTER_ATTR`](#boundinnerclass_outer_attr).
If your outer class uses `__slots__`, you can add this to your
slots definition to ensure [`BoundInnerClass`](#boundinnerclasscls) works correctly.

Example:

```Python
class Foo:
    __slots__ = ('x', 'y', 'z') + BOUNDINNERCLASS_SLOTS

    @BoundInnerClass
    class Bar:
        ...
```

See the [**Bound inner classes**](#bound-inner-classes) tutorial for more information.
</dd></dl>

#### `is_bound(cls)`

<dl><dd>

Returns `True` if `cls` is a bound inner class that has been
bound to a specific outer instance.  Said another way,
`is_bound(cls)` returns `True` if
[`bound_to(cls)`](#bound_tocls) would return a non-`None` value.

Returns `False` for unbound inner classes and non-participating classes.
Raises `TypeError` if `cls` is not a class object.

See the [**Bound inner classes**](#bound-inner-classes) tutorial for more information.
</dd></dl>

#### `is_boundinnerclass(cls)`

<dl><dd>

Returns `True` if `cls` was decorated with
[`@BoundInnerClass`](#boundinnerclasscls),
or is a bound wrapper class created from one.

Returns `False` for [`@UnboundInnerClass`](#unboundinnerclasscls)
classes and regular classes.
Raises `TypeError` if `cls` is not a class object.

See the [**Bound inner classes**](#bound-inner-classes) tutorial for more information.
</dd></dl>

#### `is_unboundinnerclass(cls)`

<dl><dd>

Returns `True` if `cls` was decorated with
[`@UnboundInnerClass`](#unboundinnerclasscls),
or is a wrapper class created from one.

Returns `False` for [`@BoundInnerClass`](#boundinnerclasscls)
classes and regular classes.
Raises `TypeError` if `cls` is not a class object.

See the [**Bound inner classes**](#bound-inner-classes) tutorial for more information.
</dd></dl>

#### `type_bound_to(instance)`

<dl><dd>

Returns the outer instance that `type(instance)` is bound to, or `None`.

This is a convenience function equivalent to calling
[`bound_to(type(instance))`](#bound_tocls).

[`BoundInnerClass`](#boundinnerclasscls) doesn't keep strong
references to outer instances.  If `type(instance)` was bound
to an object that has since been destroyed, `type_bound_to`
will return `None`.

See the [**Bound inner classes**](#bound-inner-classes) tutorial for more information.
</dd></dl>

#### `unbound(cls)`

<dl><dd>

Returns the unbound version of a bound class.

If `cls` is a bound inner class, returns the original unbound class.
If `cls` is already unbound (or not a bindable inner class), returns `cls`.

Raises `ValueError` if `cls` inherits directly from a bound class
(e.g. `class Child(o.Inner)`), since such classes have no unbound
version.  Raises `TypeError` if `cls` is not a class object.

See the [**Bound inner classes**](#bound-inner-classes) tutorial for more information.
</dd></dl>


## `big.builtin`

<dl><dd>

Fundamental functions and types that don't fit neatly into
any other submodule.  (Named `builtin` to avoid a name collision
with Python's `builtins` module.)

</dd></dl>

#### `ClassRegistry()`

<dl><dd>

A `dict` subclass with attribute-style access, useful as
a class decorator for registering base classes.

[`BoundInnerClass`](#boundinnerclasscls) encourages heavily-nested
classes, but Python's scoping rules make it clumsy to reference
base classes defined in a different class scope.  `ClassRegistry`
solves this by giving you a place to store references to base
classes you can access later.

To use, create a `ClassRegistry` instance, then use it as a
decorator to register classes.  Access registered classes as
attributes on the `ClassRegistry`.  By default the class's
`__name__` is used as the attribute name; pass a string argument
to use a custom name instead.

When using with [`BoundInnerClass`](#boundinnerclasscls), put
`@base()` *above* `@BoundInnerClass`.
</dd></dl>

#### `get_float(o, default=_sentinel)`

<dl><dd>

Returns `float(o)`, unless that conversion fails,
in which case returns the default value.  If
you don't pass in an explicit default value,
the default value is `o`.
</dd></dl>

#### `get_int(o, default=_sentinel)`

<dl><dd>

Returns `int(o)`, unless that conversion fails,
in which case returns the default value.  If
you don't pass in an explicit default value,
the default value is `o`.
</dd></dl>

#### `get_int_or_float(o, default=_sentinel)`

<dl><dd>

Converts `o` into a number, preferring an int to a float.

If `o` is already an int or float, returns `o` unchanged.  Otherwise,
tries `int(o)`.  If that conversion succeeds, returns the result.
Otherwise, tries `float(o)`.  If that conversion succeeds, returns
the result.  Otherwise returns the default value.  If you don't
pass in an explicit default value, the default value is `o`.
</dd></dl>

#### `ModuleManager()`

<dl><dd>

A class that manages your module's namespace, including `__all__`.

`ModuleManager` makes it easy to populate `__all__` and clean up
temporary symbols.  Instantiate a `ModuleManager` at module scope,
use its methods to declare exports and deletions, then call the
instance at the end of your module to finalize.

`ModuleManager` provides two methods, both of which can be used
as decorators or called with string arguments:

`mm.export(*args)` adds symbols to `__all__`.  When used as a
decorator, adds the decorated function or class by name.  When
called with strings, adds those strings to `__all__`.

`mm.delete(*args)` marks symbols for deletion.  When used as a
decorator, marks the decorated function or class for deletion.
When called with strings, marks those names for deletion.

When the `ModuleManager` instance is called, it deletes all
symbols on the deletions list from the module namespace.
It also automatically deletes itself, and any module-level
references to its `export` and `delete` methods.
</dd></dl>

#### `pure_virtual()`

<dl><dd>

A decorator for class methods.  When you have a method in
a base class that's "pure virtual"--that must not be called,
but must be overridden in child classes--decorate it with
`@pure_virtual()`.  Calling that method will throw a
`NotImplementedError`.

Note that the body of any function decorated with
`@pure_virtual()` is ignored.  By convention the body
of these methods should contain only a single ellipsis,
literally like this:

```Python
class BaseClass:
    @big.pure_virtual()
    def on_reset(self):
        ...
```
</dd></dl>

#### `try_float(o)`

<dl><dd>

Returns `True` if `o` can be converted into a `float`,
and `False` if it can't.
</dd></dl>

#### `try_int(o)`

<dl><dd>

Returns `True` if `o` can be converted into an `int`,
and `False` if it can't.
</dd></dl>


## `big.deprecated`

<dl><dd>

Old versions of functions (and classes) from **big**.  These
versions are deprecated, either because the name was changed,
or the semantics were changed, or both.

Unlike the other modules, the contents of `big.deprecated` aren't
automatically imported into `big.all`.  (`big.all` does import
the `deprecated` submodule, it just doesn't `from deprected import *`
all the symbols.)

</dd></dl>

## `big.file`

<dl><dd>

Functions for working with files, directories, and I/O.

</dd></dl>

#### `fgrep(path, text, *, encoding=None, enumerate=False, case_insensitive=False)`

<dl><dd>

Find the lines of a file that match some text, like the UNIX `fgrep` utility
program.

`path` should be an object representing a path to an existing file, one of:

* a string,
* a bytes object, or
* a `pathlib.Path` object.

`text` should be either string or bytes.

`encoding` is used as the file encoding when opening the file.

* If `text` is a str, the file is opened in text mode.
* If `text` is a bytes object, the file is opened in binary mode.
  `encoding` must be `None` when the file is opened in binary mode.

If `case_insensitive` is true, perform the search in a case-insensitive
manner.

Returns a list of lines in the file containing `text`.  The lines are either
strings or bytes objects, depending on the type of `pattern`.  The lines
have their newlines stripped but preserve all other whitespace.

If `enumerate` is true, returns a list of tuples of (line_number, line).
The first line of the file is line number 1.

For simplicity of implementation, the entire file is read in to memory
at one time.  If `case_insensitive` is true, `fgrep` also makes a lowercased
copy.
</dd></dl>

#### `file_mtime(path)`

<dl><dd>

Returns the modification time of `path`, in seconds since the epoch.
Note that seconds is a float, indicating the sub-second with some
precision.
</dd></dl>

#### `file_mtime_ns(path)`

<dl><dd>

Returns the modification time of `path`, in nanoseconds since the epoch.
</dd></dl>

#### `file_size(path)`

<dl><dd>

Returns the size of the file at `path`, as an integer representing the
number of bytes.
</dd></dl>

#### `grep(path, pattern, *, encoding=None, enumerate=False, flags=0)`

<dl><dd>

Look for matches to a regular expression pattern in the lines of a file,
similarly to the UNIX `grep` utility program.

`path` should be an object representing a path to an existing file, one of:

* a string,
* a bytes object, or
* a `pathlib.Path` object.

`pattern` should be an object containing a regular expression, one of:

* a string,
* a bytes object, or
* an `re.Pattern`, initialized with either `str` or `bytes`.

`encoding` is used as the file encoding when opening the file.

If `pattern` uses a `str`, the file is opened in text mode.
If `pattern` uses a bytes object, the file is opened in binary mode.
`encoding` must be `None` when the file is opened in binary mode.

`flags` is passed in as the `flags` argument to `re.compile` if `pattern`
is a string or bytes.  (It's ignored if `pattern` is an `re.Pattern` object.)

Returns a list of lines in th