Metadata-Version: 2.4
Name: cs-seq
Version: 20260912
Summary: Stuff to do with counters, sequences and iterables.
Keywords: python2,python3
Author-email: Cameron Simpson <cs@cskk.id.au>
Requires-Python: >=3
Description-Content-Type: text/markdown
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Requires-Dist: cs.deco>=20260912
Requires-Dist: cs.gimmicks>=20260311
Requires-Dist: cs.typingutils>=20260525
Project-URL: MonoRepo Commits, https://bitbucket.org/cameron_simpson/css/commits/branch/main
Project-URL: Monorepo Git Mirror, https://github.com/cameron-simpson/css
Project-URL: Monorepo Hg/Mercurial Mirror, https://hg.sr.ht/~cameron-simpson/css
Project-URL: Source, https://github.com/cameron-simpson/css/blob/main/lib/python/cs/seq.py

Stuff to do with counters, sequences and iterables.

*Latest release 20260912*:
Small doc update.

Note that any function accepting an iterable
will consume some or all of the derived iterator
in the course of its function.



Short summary:


* `ClonedIterator`: OBSOLETE version of ReIterable.


* `common_prefix_length`: Return the length of the common prefix of sequences `seqs`.


* `common_suffix_length`: Return the length of the common suffix of sequences `seqs`.


* `consume`: Consume the iterator `it`. If `last_item(item)` is true for some `item` from the iterator, cease at that item; the default `last_item` returns `False`, consuming everything from the iterator. Return the last item consumed, or `no_items` (default `None`) if there were no items.


* `consumed`: Consume the iterator `it`, a variation on `consume()`. If `last_item(item)` is true for some `item` from the iterator, cease at that item; the default `last_item` returns `False`, consuming everything from the iterator. Return an iterator yielding the last item consumed (if any) and then the remaining items from `it`.


* `first`: Return the first item from an iterable; raise `IndexError` on empty iterables.


* `get0`: Return first element of an iterable, or the default.


* `greedy`: A decorator or function for greedy computation of iterables.


* `imerge`: Merge an iterable of ordered iterables in order.


* `infill`: A generator accepting an iterable of objects which yields `(obj,missing_keys)` 2-tuples indicating missing records requiring infill for each object.


* `infill_from_batches`: A batched version of `infill(objs)` accepting an iterable of batches of objects which yields `(obj,obj_key)` 2-tuples indicating missing records requiring infill for each object.


* `isordered`: Test whether an iterable is ordered. Note that the iterable is iterated, so this is a destructive test for nonsequences.


* `last`: Return the last item from an iterable; raise `IndexError` on empty iterables.


* `not_none`: Filter the iterables for items which are not `None`.


* `onetomany`: A decorator for a method of a sequence to merge the results of passing every element of the sequence to the function, expecting multiple values back.


* `onetoone`: A decorator for a method of a sequence to merge the results of passing every element of the sequence to the function, expecting a single value back.


* `order`: A convenience wrapper for an `Ordered` instance to order the `indexed_items`.


* `Ordered`: A class to yield indexed but out of order values in index order such as you may receive from completion of concurrent actions which you want to process in submission order but otherwise as soon as possible.


* `range`: A class like the builtin `range` exceppt that it will accept `...` as the stop value, indicating an unbound range. Note that if initialised like a normal range it returns a builtin `range` instance.


* `ReIterable`: A thread safe clone of some orginal iterator.


* `Seq`: A numeric sequence implemented as a thread safe wrapper for `itertools.count()`.


* `seq`: Return a new sequential value.


* `skip_map`: A version of `map()` which will skip items where `func(item)` raises an exception in `except_types`, a tuple of exception types. If a skipped exception occurs a warning will be issued unless `quiet` is true (default `False`).


* `splitoff`: Split a sequence into (usually short) prefixes and a tail, for example to construct subdirectory trees based on a UUID.


* `StatefulIterator`: A trivial iterator which wraps another iterator to expose some tracking state.


* `tee`: A generator yielding the items from an iterable which also copies those items to a series of queues.


* `the`: Returns the first element of an iterable, but requires there to be exactly one.


* `TrackingCounter`: A wrapper for a counter which can be incremented and decremented.


* `unrepeated`: A generator yielding items from the iterable `it` with no repetitions.


* `with_neighbours`: Return 3-tuples of `(prev,curr,next)` from the iterable `it` where `curr` is each item from `it` and `prev` and `next` are the preceeding and following items respectively.

## Functions

### ClonedIterator(it: Iterable, no_neighbour=None)

OBSOLETE version of ReIterable

A thread safe clone of some orginal iterator.

`next()` of this yields the next item from the supplied iterator.
`iter()` of this returns a generator yielding from the
historic items and then from the original iterator.

Note that this accrues all of the items from the original
iterator in memory.

### common_prefix_length(it: Iterable, no_neighbour=None)

Return the length of the common prefix of sequences `seqs`.

### common_suffix_length(it: Iterable, no_neighbour=None)

Return the length of the common suffix of sequences `seqs`.

### consume(it: Iterable, no_neighbour=None)

Consume the iterator `it`.
If `last_item(item)` is true for some `item` from the iterator,
cease at that item; the default `last_item` returns `False`,
consuming everything from the iterator.
Return the last item consumed, or `no_items` (default `None`) if there were no items.

### consumed(it: Iterable, no_neighbour=None)

Consume the iterator `it`, a variation on `consume()`.
If `last_item(item)` is true for some `item` from the iterator,
cease at that item; the default `last_item` returns `False`,
consuming everything from the iterator.
Return an iterator yielding the last item consumed (if any)
and then the remaining items from `it`.

### first(it: Iterable, no_neighbour=None)

Return the first item from an iterable; raise `IndexError` on empty iterables.

### get0(it: Iterable, no_neighbour=None)

Return first element of an iterable, or the default.

### greedy(it: Iterable, no_neighbour=None)

A decorator or function for greedy computation of iterables.

If `g` is omitted or callable
this is a decorator for a generator function
causing it to compute greedily,
capacity limited by `queue_depth`.

If `g` is iterable
this function dispatches it in a `Thread` to compute greedily,
capacity limited by `queue_depth`.

Example with an iterable:

    for packet in greedy(parse_data_stream(stream)):
        ... process packet ...

which does some readahead of the stream.

Example as a function decorator:

    @greedy
    def g(n):
        for item in range(n):
            yield n

This can also be used directly on an existing iterable:

    for item in greedy(range(n)):
        yield n

Normally a generator runs on demand.
This function dispatches a `Thread` to run the iterable
(typically a generator)
putting yielded values to a queue
and returns a new generator yielding from the queue.

The `queue_depth` parameter specifies the depth of the queue
and therefore how many values the original generator can compute
before blocking at the queue's capacity.

The default `queue_depth` is `0` which creates a `Channel`
as the queue - a zero storage buffer - which lets the generator
compute only a single value ahead of time.

A larger `queue_depth` allocates a `Queue` with that much storage
allowing the generator to compute as many as `queue_depth+1` values
ahead of time.

Here's a comparison of the behaviour:

Example without `@greedy`
where the "yield 1" step does not occur until after the "got 0":

    >>> from time import sleep
    >>> def g():
    ...   for i in range(2):
    ...     print("yield", i)
    ...     yield i
    ...   print("g done")
    ...
    >>> G = g(); sleep(0.1)
    >>> for i in G:
    ...   print("got", i)
    ...   sleep(0.1)
    ...
    yield 0
    got 0
    yield 1
    got 1
    g done

Example with `@greedy`
where the "yield 1" step computes before the "got 0":

    >>> from time import sleep
    >>> @greedy
    ... def g():
    ...   for i in range(2):
    ...     print("yield", i)
    ...     yield i
    ...   print("g done")
    ...
    >>> G = g(); sleep(0.1)
    yield 0
    >>> for i in G:
    ...   print("got", repr(i))
    ...   sleep(0.1)
    ...
    yield 1
    got 0
    g done
    got 1

Example with `@greedy(queue_depth=1)`
where the "yield 1" step computes before the "got 0":

    >>> from cs.x import X
    >>> from time import sleep
    >>> @greedy
    ... def g():
    ...   for i in range(3):
    ...     X("Y")
    ...     print("yield", i)
    ...     yield i
    ...   print("g done")
    ...
    >>> G = g(); sleep(2)
    yield 0
    yield 1
    >>> for i in G:
    ...   print("got", repr(i))
    ...   sleep(0.1)
    ...
    yield 2
    got 0
    yield 3
    got 1
    g done
    got 2

### imerge(it: Iterable, no_neighbour=None)

Merge an iterable of ordered iterables in order.

Parameters:
* `iters`: an iterable of iterators
* `reverse`: keyword parameter: if true, yield items in reverse order.
  This requires the iterables themselves to also be in
  reversed order.

This function relies on the source iterables being ordered
and their elements being comparable, through slightly misordered
iterables (for example, as extracted from web server logs)
will produce only slightly misordered results, as the merging
is done on the basis of the front elements of each iterable.

### infill(it: Iterable, no_neighbour=None)

A generator accepting an iterable of objects
which yields `(obj,missing_keys)` 2-tuples
indicating missing records requiring infill for each object.

Parameters:
* `objs`: an iterable of objects
* `obj_keys`: a callable accepting an object and returning
  an iterable of the expected keys
* `existsing_keys`: a callable accepting an object and returning
  an iterable of the existing keys
* `all`: optional flag, default `False`: if true then yield
  `(obj,())` for objects with no missing records

Example:

    for obj, missing_key in infill(objs,...):
      ... infill a record for missing_key ...

### infill_from_batches(it: Iterable, no_neighbour=None)

A batched version of `infill(objs)` accepting an iterable of
batches of objects which yields `(obj,obj_key)` 2-tuples
indicating missing records requiring infill for each object.

This is aimed at processing batches of objects where it is
more efficient to prepare each batch as a whole, such as a
Django `QuerySet` which lets the caller make single database
queries for a batch of `Model` instances.
Thus this function can be used with `cs.djutils.model_batches_qs`
for more efficient infill processing.

Parameters:
* `objss`: an iterable of iterables of objects
* `obj_keys`: a callable accepting an object and returning
  an iterable of the expected keys
* `existsing_keys`: a callable accepting an object and returning
  an iterable of the existing keys
* `all`: optional flag, default `False`: if true then yield
  `(obj,())` for objects with no missing records
* `amend_batch`: optional callable to amend the batch of objects,
  for example to amend a `QuerySet` with `.select_related()` or similar

### isordered(it: Iterable, no_neighbour=None)

Test whether an iterable is ordered.
Note that the iterable is iterated, so this is a destructive
test for nonsequences.

### last(it: Iterable, no_neighbour=None)

Return the last item from an iterable; raise `IndexError` on empty iterables.

### not_none(it: Iterable, no_neighbour=None)

Filter the iterables for items which are not `None`.

### onetomany(it: Iterable, no_neighbour=None)

A decorator for a method of a sequence to merge the results of
passing every element of the sequence to the function, expecting
multiple values back.

Example:

      class X(list):
            @onetomany
            def chars(self, item):
                  return item
      strs = X(['Abc', 'Def'])
      all_chars = X.chars()

### onetoone(it: Iterable, no_neighbour=None)

A decorator for a method of a sequence to merge the results of
passing every element of the sequence to the function, expecting a
single value back.

Example:

      class X(list):
            @onetoone
            def lower(self, item):
                  return item.lower()
      strs = X(['Abc', 'Def'])
      lower_strs = X.lower()

### order(it: Iterable, no_neighbour=None)

A convenience wrapper for an `Ordered` instance to order the `indexed_items`.

Example:

    >>> # an iterator yielding unordered results, just because
    >>> unordered_results = iter( ((2, "third"), (0, "first"), (1, "second")) )
    >>> for i, result in order(unordered_results):
    ...   print(i, result)
    ...
    0 first
    1 second
    2 third

### seq(it: Iterable, no_neighbour=None)

Return a new sequential value.

### skip_map(it: Iterable, no_neighbour=None)

A version of `map()` which will skip items where `func(item)`
raises an exception in `except_types`, a tuple of exception types.
If a skipped exception occurs a warning will be issued unless
`quiet` is true (default `False`).

### splitoff(it: Iterable, no_neighbour=None)

Split a sequence into (usually short) prefixes and a tail,
for example to construct subdirectory trees based on a UUID.

Example:

    >>> from uuid import UUID
    >>> uuid = 'd6d9c510-785c-468c-9aa4-b7bda343fb79'
    >>> uu = UUID(uuid).hex
    >>> uu
    'd6d9c510785c468c9aa4b7bda343fb79'
    >>> splitoff(uu, 2, 2)
    ['d6', 'd9', 'c510785c468c9aa4b7bda343fb79']

### tee(it: Iterable, no_neighbour=None)

A generator yielding the items from an iterable
which also copies those items to a series of queues.

Parameters:
* `iterable`: the iterable to copy
* `Qs`: the queues, objects accepting a `.put` method.

Note: the item is `.put` onto every queue
before being yielded from this generator.

### the(it: Iterable, no_neighbour=None)

Returns the first element of an iterable, but requires there to be
exactly one.

### unrepeated(it: Iterable, no_neighbour=None)

A generator yielding items from the iterable `it` with no repetitions.

Parameters:
* `it`: the iterable to process
* `seen`: an optional setlike container supporting `in` and `.add()`
* `signature`: an optional signature function for items from `it`
  which produces the value to compare to recognise repeated items;
  its values are stored in the `seen` set

The default `signature` function is equality;
the items are stored n `seen` and compared.
This requires the items to be hashable and support equality tests.
The same applies to whatever values the `signature` function produces.

Another common signature is identity: `id`, useful for
traversing a graph which may have cycles.

Since `seen` accrues all the signature values for yielded items
generally it will grow monotonicly as iteration proceeeds.
If the items are complex or large it is well worth providing a signature
function even if the items themselves can be used in a set.

### with_neighbours(it: Iterable, no_neighbour=None)

Return 3-tuples of `(prev,curr,next)` from the iterable `it`
where `curr` is each item from `it` and `prev` and `next` are
the preceeding and following items respectively.

The first item will have a `prev` of `no_neighbour`
and the last item will have a `next` of `no_neighbour`.

`no_neighbour` defaults to `None`, but may be specified as
another sentinel if `None` is anticipated in the iterable.

Examples:

    >>> list(with_neighbours((1,2,3)))
    [(None, 1, 2), (1, 2, 3), (2, 3, None)]
    >>> list(with_neighbours(()))
    []
    >>> list(with_neighbours((1,)))
    [(None, 1, None)]
    >>> list(with_neighbours((1,2)))
    [(None, 1, 2), (1, 2, None)]
    >>> list(with_neighbours((1,None,3),"END"))
    [('END', 1, None), (1, None, 3), (None, 3, 'END')]

## Classes

### class Ordered

Return 3-tuples of `(prev,curr,next)` from the iterable `it`
where `curr` is each item from `it` and `prev` and `next` are
the preceeding and following items respectively.

The first item will have a `prev` of `no_neighbour`
and the last item will have a `next` of `no_neighbour`.

`no_neighbour` defaults to `None`, but may be specified as
another sentinel if `None` is anticipated in the iterable.

Examples:

    >>> list(with_neighbours((1,2,3)))
    [(None, 1, 2), (1, 2, 3), (2, 3, None)]
    >>> list(with_neighbours(()))
    []
    >>> list(with_neighbours((1,)))
    [(None, 1, None)]
    >>> list(with_neighbours((1,2)))
    [(None, 1, 2), (1, 2, None)]
    >>> list(with_neighbours((1,None,3),"END"))
    [('END', 1, None), (1, None, 3), (None, 3, 'END')]

####`Ordered.__dict__`

Read-only proxy of a mapping.

####`Ordered.__firstlineno__`

int([x]) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating-point
numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4

####`Ordered.__static_attributes__`

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple.
If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

#### `Ordered.drain(self) -> Generator[Tuple[cs.typingutils.Sortable, Any], NoneType, NoneType]`

A generator yielding (index,value) 2-tuples from the heap until it is empty.

#### `Ordered.push(self, index, value) -> Generator[Tuple[cs.typingutils.Sortable, Any], NoneType, NoneType]`

A generator to push an (index,value) 2-tuple onto the heap
and then yield (index,value) 2-tuples from the heap while it
is not empty and the top element equals the expected next index
from `self.indices`.

### class ReIterable(collections.abc.Iterable, typing.Generic)

Return 3-tuples of `(prev,curr,next)` from the iterable `it`
where `curr` is each item from `it` and `prev` and `next` are
the preceeding and following items respectively.

The first item will have a `prev` of `no_neighbour`
and the last item will have a `next` of `no_neighbour`.

`no_neighbour` defaults to `None`, but may be specified as
another sentinel if `None` is anticipated in the iterable.

Examples:

    >>> list(with_neighbours((1,2,3)))
    [(None, 1, 2), (1, 2, 3), (2, 3, None)]
    >>> list(with_neighbours(()))
    []
    >>> list(with_neighbours((1,)))
    [(None, 1, None)]
    >>> list(with_neighbours((1,2)))
    [(None, 1, 2), (1, 2, None)]
    >>> list(with_neighbours((1,None,3),"END"))
    [('END', 1, None), (1, None, 3), (None, 3, 'END')]

#### `ReIterable.__init__(self, it: Iterable)`

Initialise the clone with the iterable `it`.

####`ReIterable.__annotations__`

dict() -> new empty dictionary
dict(mapping) -> new dictionary initialized from a mapping object's
    (key, value) pairs
dict(iterable) -> new dictionary initialized as if via:
    d = {}
    for k, v in iterable:
        d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
    in the keyword argument list.  For example:  dict(one=1, two=2)

####`ReIterable.__dict__`

Read-only proxy of a mapping.

####`ReIterable.__firstlineno__`

int([x]) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating-point
numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4

#### `ReIterable.__iter__(self)`

Iterate over the clone, returning a new iterator.

In mild violation of the iterator protocol, instead of
returning `self`, `iter(self)` returns a generator yielding
the historic and then current contents of the original iterator.

#### `ReIterable.__next__(self)`

Return the next item from the original iterator.

####`ReIterable.__orig_bases__`

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple.
If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

####`ReIterable.__parameters__`

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple.
If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

####`ReIterable.__static_attributes__`

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple.
If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

### class Seq

Return 3-tuples of `(prev,curr,next)` from the iterable `it`
where `curr` is each item from `it` and `prev` and `next` are
the preceeding and following items respectively.

The first item will have a `prev` of `no_neighbour`
and the last item will have a `next` of `no_neighbour`.

`no_neighbour` defaults to `None`, but may be specified as
another sentinel if `None` is anticipated in the iterable.

Examples:

    >>> list(with_neighbours((1,2,3)))
    [(None, 1, 2), (1, 2, 3), (2, 3, None)]
    >>> list(with_neighbours(()))
    []
    >>> list(with_neighbours((1,)))
    [(None, 1, None)]
    >>> list(with_neighbours((1,2)))
    [(None, 1, 2), (1, 2, None)]
    >>> list(with_neighbours((1,None,3),"END"))
    [('END', 1, None), (1, None, 3), (None, 3, 'END')]

####`Seq.__firstlineno__`

int([x]) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating-point
numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4

####`Seq.__slots__`

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple.
If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

####`Seq.__static_attributes__`

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple.
If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

### class StatefulIterator

Return 3-tuples of `(prev,curr,next)` from the iterable `it`
where `curr` is each item from `it` and `prev` and `next` are
the preceeding and following items respectively.

The first item will have a `prev` of `no_neighbour`
and the last item will have a `next` of `no_neighbour`.

`no_neighbour` defaults to `None`, but may be specified as
another sentinel if `None` is anticipated in the iterable.

Examples:

    >>> list(with_neighbours((1,2,3)))
    [(None, 1, 2), (1, 2, 3), (2, 3, None)]
    >>> list(with_neighbours(()))
    []
    >>> list(with_neighbours((1,)))
    [(None, 1, None)]
    >>> list(with_neighbours((1,2)))
    [(None, 1, 2), (1, 2, None)]
    >>> list(with_neighbours((1,None,3),"END"))
    [('END', 1, None), (1, None, 3), (None, 3, 'END')]

####`StatefulIterator.__dict__`

Read-only proxy of a mapping.

####`StatefulIterator.__firstlineno__`

int([x]) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating-point
numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4

####`StatefulIterator.__static_attributes__`

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple.
If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

### class TrackingCounter

Return 3-tuples of `(prev,curr,next)` from the iterable `it`
where `curr` is each item from `it` and `prev` and `next` are
the preceeding and following items respectively.

The first item will have a `prev` of `no_neighbour`
and the last item will have a `next` of `no_neighbour`.

`no_neighbour` defaults to `None`, but may be specified as
another sentinel if `None` is anticipated in the iterable.

Examples:

    >>> list(with_neighbours((1,2,3)))
    [(None, 1, 2), (1, 2, 3), (2, 3, None)]
    >>> list(with_neighbours(()))
    []
    >>> list(with_neighbours((1,)))
    [(None, 1, None)]
    >>> list(with_neighbours((1,2)))
    [(None, 1, 2), (1, 2, None)]
    >>> list(with_neighbours((1,None,3),"END"))
    [('END', 1, None), (1, None, 3), (None, 3, 'END')]

#### `TrackingCounter.__init__(self, value=0, name=None, lock=None)`

Initialise the counter to `value` (default 0) with the optional `name`.

####`TrackingCounter.__dict__`

Read-only proxy of a mapping.

####`TrackingCounter.__firstlineno__`

int([x]) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating-point
numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4

####`TrackingCounter.__static_attributes__`

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple.
If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

#### `TrackingCounter.check(self)`

Internal consistency check.

#### `TrackingCounter.dec(self, tag=None)`

Decrement the counter.
Wake up any threads waiting for its new value.

#### `TrackingCounter.inc(self, tag=None)`

Increment the counter.
Wake up any threads waiting for its new value.

#### `TrackingCounter.wait(self, value)`

Wait for the counter to reach the specified `value`.

### class range

Return 3-tuples of `(prev,curr,next)` from the iterable `it`
where `curr` is each item from `it` and `prev` and `next` are
the preceeding and following items respectively.

The first item will have a `prev` of `no_neighbour`
and the last item will have a `next` of `no_neighbour`.

`no_neighbour` defaults to `None`, but may be specified as
another sentinel if `None` is anticipated in the iterable.

Examples:

    >>> list(with_neighbours((1,2,3)))
    [(None, 1, 2), (1, 2, 3), (2, 3, None)]
    >>> list(with_neighbours(()))
    []
    >>> list(with_neighbours((1,)))
    [(None, 1, None)]
    >>> list(with_neighbours((1,2)))
    [(None, 1, 2), (1, 2, None)]
    >>> list(with_neighbours((1,None,3),"END"))
    [('END', 1, None), (1, None, 3), (None, 3, 'END')]

#### `range.__class_getitem__(index)`

You can also index this `range` type` with a slice, obtaining
a range matching the slice.

####`range.__dict__`

Read-only proxy of a mapping.

####`range.__firstlineno__`

int([x]) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating-point
numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4

####`range.__static_attributes__`

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple.
If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

# Release Log



*Release 20260912*:
Small doc update.

*Release 20260622*:
* Rename ClonedIteraor to ReIterable, sugestion by λambda @ python.discord.
* New consume(Iterable) function to "run" an iterable without storing the results.
* New consumed(Iterator) returning an Iterator with the last consumed item and the tail of the original iterator.

*Release 20260526*:
Update some type annotations for pre-Python 3.13.

*Release 20260525.1*:
order: yield sorted indexed item, convenience wrapper for Ordered.

*Release 20260525*:
Ordered class for pushing out of order results and yielding in order results.

*Release 20260403*:
New generator with_neighbours(iterable) to yield (prev,curr,next) 3-tuples.

*Release 20251231.1*:
range: support range[type] returning a GenericAlias.

*Release 20251231*:
range: support making a range like range[1::2] for the odd numbers.

*Release 20251230*:
* New not_none(*iterables) generator yielding items which are not none, handy in * expansions.
* New range() class accepting ... for the stop.

*Release 20250914*:
ClonedIterator: it may be an Iterable, not just an Iterator.

*Release 20250801*:
ClonedIterator: bugfix direct iteration, noticed by @Matiss.

*Release 20250724*:
New ClonedIterator class to provide a reiterable clone of an iterator.

*Release 20250306*:
New infill() and infill_from_batches() generators for identifying missing records requiring an infill.

*Release 20250103*:
New skip_map(func, *iterables, except_types, quiet=False) generator function, like map() but skipping certain exceptions.

*Release 20221118*:
Small doc improvement.

*Release 20220530*:
Seq: calling a Seq is like next(seq).

*Release 20210924*:
New greedy(iterable) or @greedy(generator_function) to let generators precompute.

*Release 20210913*:
New unrepeated() generator removing duplicates from an iterable.

*Release 20201025*:
New splitoff() function to split a sequence into (usually short) prefixes and a tail.

*Release 20200914*:
New common_prefix_length and common_suffix_length for comparing prefixes and suffixes of sequences.

*Release 20190103*:
Documentation update.

*Release 20190101*:
* New and UNTESTED class StatefulIterator to associate some externally visible state with an iterator.
* Seq: accept optional `lock` parameter.

*Release 20171231*:
* Python 2 backport for imerge().
* New tee function to duplicate an iterable to queues.
* Function isordered() is now a test instead of an assertion.
* Drop NamedTuple, NamedTupleClassFactory (unused).

*Release 20160918*:
* New function isordered() to test ordering of a sequence.
* imerge: accept new `reverse` parameter for merging reversed iterables.

*Release 20160828*:
Modify DISTINFO to say "install_requires", fixes pypi requirements.

*Release 20160827*:
TrackingCounter: accept presupplied lock object. Python 3 exec fix.

*Release 20150118*:
metadata update

*Release 20150111*:
Initial PyPI release.
