Update tempora==5.5.0

This commit is contained in:
JonnyWong16 2023-08-23 21:36:05 -07:00
commit dd247d874d
No known key found for this signature in database
GPG key ID: B1F1F9807184697A
26 changed files with 583 additions and 209 deletions

View file

@ -1,9 +1,10 @@
import functools
import time
import inspect
import collections
import types
import functools
import inspect
import itertools
import operator
import time
import types
import warnings
import more_itertools
@ -183,8 +184,9 @@ def method_cache(
# Support cache clear even before cache has been created.
wrapper.cache_clear = lambda: None # type: ignore[attr-defined]
return ( # type: ignore[return-value]
_special_method_cache(method, cache_wrapper) or wrapper
return (
_special_method_cache(method, cache_wrapper) # type: ignore[return-value]
or wrapper
)
@ -554,3 +556,51 @@ def except_(*exceptions, replace=None, use=None):
return wrapper
return decorate
def identity(x):
return x
def bypass_when(check, *, _op=identity):
"""
Decorate a function to return its parameter when ``check``.
>>> bypassed = [] # False
>>> @bypass_when(bypassed)
... def double(x):
... return x * 2
>>> double(2)
4
>>> bypassed[:] = [object()] # True
>>> double(2)
2
"""
def decorate(func):
@functools.wraps(func)
def wrapper(param):
return param if _op(check) else func(param)
return wrapper
return decorate
def bypass_unless(check):
"""
Decorate a function to return its parameter unless ``check``.
>>> enabled = [object()] # True
>>> @bypass_unless(enabled)
... def double(x):
... return x * 2
>>> double(2)
4
>>> del enabled[:] # False
>>> double(2)
2
"""
return bypass_when(check, _op=operator.not_)

View file

@ -3,4 +3,4 @@
from .more import * # noqa
from .recipes import * # noqa
__version__ = '9.1.0'
__version__ = '10.1.0'

View file

@ -2,7 +2,7 @@ import warnings
from collections import Counter, defaultdict, deque, abc
from collections.abc import Sequence
from functools import partial, reduce, wraps
from functools import cached_property, partial, reduce, wraps
from heapq import heapify, heapreplace, heappop
from itertools import (
chain,
@ -17,6 +17,7 @@ from itertools import (
takewhile,
tee,
zip_longest,
product,
)
from math import exp, factorial, floor, log
from queue import Empty, Queue
@ -36,6 +37,7 @@ from .recipes import (
take,
unique_everseen,
all_equal,
batched,
)
__all__ = [
@ -53,6 +55,7 @@ __all__ = [
'circular_shifts',
'collapse',
'combination_index',
'combination_with_replacement_index',
'consecutive_groups',
'constrained_batches',
'consumer',
@ -93,10 +96,13 @@ __all__ = [
'nth_or_last',
'nth_permutation',
'nth_product',
'nth_combination_with_replacement',
'numeric_range',
'one',
'only',
'outer_product',
'padded',
'partial_product',
'partitions',
'peekable',
'permutation_index',
@ -125,6 +131,7 @@ __all__ = [
'strictly_n',
'substrings',
'substrings_indexes',
'takewhile_inclusive',
'time_limited',
'unique_in_window',
'unique_to_each',
@ -472,7 +479,10 @@ def iterate(func, start):
"""
while True:
yield start
start = func(start)
try:
start = func(start)
except StopIteration:
break
def with_iter(context_manager):
@ -2069,7 +2079,6 @@ class numeric_range(abc.Sequence, abc.Hashable):
if self._step == self._zero:
raise ValueError('numeric_range() arg 3 must not be zero')
self._growing = self._step > self._zero
self._init_len()
def __bool__(self):
if self._growing:
@ -2145,7 +2154,8 @@ class numeric_range(abc.Sequence, abc.Hashable):
def __len__(self):
return self._len
def _init_len(self):
@cached_property
def _len(self):
if self._growing:
start = self._start
stop = self._stop
@ -2156,10 +2166,10 @@ class numeric_range(abc.Sequence, abc.Hashable):
step = -self._step
distance = stop - start
if distance <= self._zero:
self._len = 0
return 0
else: # distance > 0 and step > 0: regular euclidean division
q, r = divmod(distance, step)
self._len = int(q) + int(r != self._zero)
return int(q) + int(r != self._zero)
def __reduce__(self):
return numeric_range, (self._start, self._stop, self._step)
@ -2699,6 +2709,9 @@ class seekable:
>>> it.seek(10)
>>> next(it)
'10'
>>> it.relative_seek(-2) # Seeking relative to the current position
>>> next(it)
'9'
>>> it.seek(20) # Seeking past the end of the source isn't a problem
>>> list(it)
[]
@ -2812,6 +2825,10 @@ class seekable:
if remainder > 0:
consume(self, remainder)
def relative_seek(self, count):
index = len(self._cache)
self.seek(max(index + count, 0))
class run_length:
"""
@ -3859,6 +3876,54 @@ def nth_permutation(iterable, r, index):
return tuple(map(pool.pop, result))
def nth_combination_with_replacement(iterable, r, index):
"""Equivalent to
``list(combinations_with_replacement(iterable, r))[index]``.
The subsequences with repetition of *iterable* that are of length *r* can
be ordered lexicographically. :func:`nth_combination_with_replacement`
computes the subsequence at sort position *index* directly, without
computing the previous subsequences with replacement.
>>> nth_combination_with_replacement(range(5), 3, 5)
(0, 1, 1)
``ValueError`` will be raised If *r* is negative or greater than the length
of *iterable*.
``IndexError`` will be raised if the given *index* is invalid.
"""
pool = tuple(iterable)
n = len(pool)
if (r < 0) or (r > n):
raise ValueError
c = factorial(n + r - 1) // (factorial(r) * factorial(n - 1))
if index < 0:
index += c
if (index < 0) or (index >= c):
raise IndexError
result = []
i = 0
while r:
r -= 1
while n >= 0:
num_combs = factorial(n + r - 1) // (
factorial(r) * factorial(n - 1)
)
if index < num_combs:
break
n -= 1
i += 1
index -= num_combs
result.append(pool[i])
return tuple(result)
def value_chain(*args):
"""Yield all arguments passed to the function in the same order in which
they were passed. If an argument itself is iterable then iterate over its
@ -3955,6 +4020,61 @@ def combination_index(element, iterable):
return factorial(n + 1) // (factorial(k + 1) * factorial(n - k)) - index
def combination_with_replacement_index(element, iterable):
"""Equivalent to
``list(combinations_with_replacement(iterable, r)).index(element)``
The subsequences with repetition of *iterable* that are of length *r* can
be ordered lexicographically. :func:`combination_with_replacement_index`
computes the index of the first *element*, without computing the previous
combinations with replacement.
>>> combination_with_replacement_index('adf', 'abcdefg')
20
``ValueError`` will be raised if the given *element* isn't one of the
combinations with replacement of *iterable*.
"""
element = tuple(element)
l = len(element)
element = enumerate(element)
k, y = next(element, (None, None))
if k is None:
return 0
indexes = []
pool = tuple(iterable)
for n, x in enumerate(pool):
while x == y:
indexes.append(n)
tmp, y = next(element, (None, None))
if tmp is None:
break
else:
k = tmp
if y is None:
break
else:
raise ValueError(
'element is not a combination with replacment of iterable'
)
n = len(pool)
occupations = [0] * n
for p in indexes:
occupations[p] += 1
index = 0
for k in range(1, n):
j = l + n - 1 - k - sum(occupations[:k])
i = n - k
if i <= j:
index += factorial(j) // (factorial(i) * factorial(j - i))
return index
def permutation_index(element, iterable):
"""Equivalent to ``list(permutations(iterable, r)).index(element)```
@ -4057,26 +4177,20 @@ def _chunked_even_finite(iterable, N, n):
num_full = N - partial_size * num_lists
num_partial = num_lists - num_full
buffer = []
iterator = iter(iterable)
# Yield num_full lists of full_size
for x in iterator:
buffer.append(x)
if len(buffer) == full_size:
yield buffer
buffer = []
num_full -= 1
if num_full <= 0:
break
partial_start_idx = num_full * full_size
if full_size > 0:
for i in range(0, partial_start_idx, full_size):
yield list(islice(iterable, i, i + full_size))
# Yield num_partial lists of partial_size
for x in iterator:
buffer.append(x)
if len(buffer) == partial_size:
yield buffer
buffer = []
num_partial -= 1
if partial_size > 0:
for i in range(
partial_start_idx,
partial_start_idx + (num_partial * partial_size),
partial_size,
):
yield list(islice(iterable, i, i + partial_size))
def zip_broadcast(*objects, scalar_types=(str, bytes), strict=False):
@ -4115,30 +4229,23 @@ def zip_broadcast(*objects, scalar_types=(str, bytes), strict=False):
if not size:
return
new_item = [None] * size
iterables, iterable_positions = [], []
scalars, scalar_positions = [], []
for i, obj in enumerate(objects):
if is_scalar(obj):
scalars.append(obj)
scalar_positions.append(i)
new_item[i] = obj
else:
iterables.append(iter(obj))
iterable_positions.append(i)
if len(scalars) == size:
if not iterables:
yield tuple(objects)
return
zipper = _zip_equal if strict else zip
for item in zipper(*iterables):
new_item = [None] * size
for i, elem in zip(iterable_positions, item):
new_item[i] = elem
for i, elem in zip(scalar_positions, scalars):
new_item[i] = elem
for i, new_item[i] in zip(iterable_positions, item):
pass
yield tuple(new_item)
@ -4163,22 +4270,23 @@ def unique_in_window(iterable, n, key=None):
raise ValueError('n must be greater than 0')
window = deque(maxlen=n)
uniques = set()
counts = defaultdict(int)
use_key = key is not None
for item in iterable:
if len(window) == n:
to_discard = window[0]
if counts[to_discard] == 1:
del counts[to_discard]
else:
counts[to_discard] -= 1
k = key(item) if use_key else item
if k in uniques:
continue
if len(uniques) == n:
uniques.discard(window[0])
uniques.add(k)
if k not in counts:
yield item
counts[k] += 1
window.append(k)
yield item
def duplicates_everseen(iterable, key=None):
"""Yield duplicate elements after their first appearance.
@ -4221,12 +4329,7 @@ def duplicates_justseen(iterable, key=None):
This function is analagous to :func:`unique_justseen`.
"""
return flatten(
map(
lambda group_tuple: islice_extended(group_tuple[1])[1:],
groupby(iterable, key),
)
)
return flatten(g for _, g in groupby(iterable, key) for _ in g)
def minmax(iterable_or_value, *others, key=None, default=_marker):
@ -4390,3 +4493,77 @@ def gray_product(*iterables):
o[j] = -o[j]
f[j] = f[j + 1]
f[j + 1] = j + 1
def partial_product(*iterables):
"""Yields tuples containing one item from each iterator, with subsequent
tuples changing a single item at a time by advancing each iterator until it
is exhausted. This sequence guarantees every value in each iterable is
output at least once without generating all possible combinations.
This may be useful, for example, when testing an expensive function.
>>> list(partial_product('AB', 'C', 'DEF'))
[('A', 'C', 'D'), ('B', 'C', 'D'), ('B', 'C', 'E'), ('B', 'C', 'F')]
"""
iterators = list(map(iter, iterables))
try:
prod = [next(it) for it in iterators]
except StopIteration:
return
yield tuple(prod)
for i, it in enumerate(iterators):
for prod[i] in it:
yield tuple(prod)
def takewhile_inclusive(predicate, iterable):
"""A variant of :func:`takewhile` that yields one additional element.
>>> list(takewhile_inclusive(lambda x: x < 5, [1, 4, 6, 4, 1]))
[1, 4, 6]
:func:`takewhile` would return ``[1, 4]``.
"""
for x in iterable:
if predicate(x):
yield x
else:
yield x
break
def outer_product(func, xs, ys, *args, **kwargs):
"""A generalized outer product that applies a binary function to all
pairs of items. Returns a 2D matrix with ``len(xs)`` rows and ``len(ys)``
columns.
Also accepts ``*args`` and ``**kwargs`` that are passed to ``func``.
Multiplication table:
>>> list(outer_product(mul, range(1, 4), range(1, 6)))
[(1, 2, 3, 4, 5), (2, 4, 6, 8, 10), (3, 6, 9, 12, 15)]
Cross tabulation:
>>> xs = ['A', 'B', 'A', 'A', 'B', 'B', 'A', 'A', 'B', 'B']
>>> ys = ['X', 'X', 'X', 'Y', 'Z', 'Z', 'Y', 'Y', 'Z', 'Z']
>>> rows = list(zip(xs, ys))
>>> count_rows = lambda x, y: rows.count((x, y))
>>> list(outer_product(count_rows, sorted(set(xs)), sorted(set(ys))))
[(2, 3, 0), (1, 0, 4)]
Usage with ``*args`` and ``**kwargs``:
>>> animals = ['cat', 'wolf', 'mouse']
>>> list(outer_product(min, animals, animals, key=len))
[('cat', 'cat', 'cat'), ('cat', 'wolf', 'wolf'), ('cat', 'wolf', 'mouse')]
"""
ys = tuple(ys)
return batched(
starmap(lambda x, y: func(x, y, *args, **kwargs), product(xs, ys)),
n=len(ys),
)

View file

@ -440,6 +440,7 @@ class seekable(Generic[_T], Iterator[_T]):
def peek(self, default: _U) -> _T | _U: ...
def elements(self) -> SequenceView[_T]: ...
def seek(self, index: int) -> None: ...
def relative_seek(self, count: int) -> None: ...
class run_length:
@staticmethod
@ -578,6 +579,9 @@ def all_unique(
iterable: Iterable[_T], key: Callable[[_T], _U] | None = ...
) -> bool: ...
def nth_product(index: int, *args: Iterable[_T]) -> tuple[_T, ...]: ...
def nth_combination_with_replacement(
iterable: Iterable[_T], r: int, index: int
) -> tuple[_T, ...]: ...
def nth_permutation(
iterable: Iterable[_T], r: int, index: int
) -> tuple[_T, ...]: ...
@ -586,6 +590,9 @@ def product_index(element: Iterable[_T], *args: Iterable[_T]) -> int: ...
def combination_index(
element: Iterable[_T], iterable: Iterable[_T]
) -> int: ...
def combination_with_replacement_index(
element: Iterable[_T], iterable: Iterable[_T]
) -> int: ...
def permutation_index(
element: Iterable[_T], iterable: Iterable[_T]
) -> int: ...
@ -664,3 +671,14 @@ def constrained_batches(
strict: bool = ...,
) -> Iterator[tuple[_T]]: ...
def gray_product(*iterables: Iterable[_T]) -> Iterator[tuple[_T, ...]]: ...
def partial_product(*iterables: Iterable[_T]) -> Iterator[tuple[_T, ...]]: ...
def takewhile_inclusive(
predicate: Callable[[_T], bool], iterable: Iterable[_T]
) -> Iterator[_T]: ...
def outer_product(
func: Callable[[_T, _U], _V],
xs: Iterable[_T],
ys: Iterable[_U],
*args: Any,
**kwargs: Any,
) -> Iterator[tuple[_V, ...]]: ...

View file

@ -9,11 +9,10 @@ Some backward-compatible usability improvements have been made.
"""
import math
import operator
import warnings
from collections import deque
from collections.abc import Sized
from functools import reduce
from functools import partial, reduce
from itertools import (
chain,
combinations,
@ -29,7 +28,6 @@ from itertools import (
zip_longest,
)
from random import randrange, sample, choice
from sys import hexversion
__all__ = [
'all_equal',
@ -52,7 +50,9 @@ __all__ = [
'pad_none',
'pairwise',
'partition',
'polynomial_eval',
'polynomial_from_roots',
'polynomial_derivative',
'powerset',
'prepend',
'quantify',
@ -65,6 +65,7 @@ __all__ = [
'sieve',
'sliding_window',
'subslices',
'sum_of_squares',
'tabulate',
'tail',
'take',
@ -77,6 +78,18 @@ __all__ = [
_marker = object()
# zip with strict is available for Python 3.10+
try:
zip(strict=True)
except TypeError:
_zip_strict = zip
else:
_zip_strict = partial(zip, strict=True)
# math.sumprod is available for Python 3.12+
_sumprod = getattr(math, 'sumprod', lambda x, y: dotproduct(x, y))
def take(n, iterable):
"""Return first *n* items of the iterable as a list.
@ -293,7 +306,7 @@ def _pairwise(iterable):
"""
a, b = tee(iterable)
next(b, None)
yield from zip(a, b)
return zip(a, b)
try:
@ -303,7 +316,7 @@ except ImportError:
else:
def pairwise(iterable):
yield from itertools_pairwise(iterable)
return itertools_pairwise(iterable)
pairwise.__doc__ = _pairwise.__doc__
@ -334,13 +347,9 @@ def _zip_equal(*iterables):
for i, it in enumerate(iterables[1:], 1):
size = len(it)
if size != first_size:
break
else:
# If we didn't break out, we can use the built-in zip.
return zip(*iterables)
# If we did break out, there was a mismatch.
raise UnequalIterablesError(details=(first_size, i, size))
raise UnequalIterablesError(details=(first_size, i, size))
# All sizes are equal, we can use the built-in zip.
return zip(*iterables)
# If any one of the iterables didn't have a length, start reading
# them until one runs out.
except TypeError:
@ -433,12 +442,9 @@ def partition(pred, iterable):
if pred is None:
pred = bool
evaluations = ((pred(x), x) for x in iterable)
t1, t2 = tee(evaluations)
return (
(x for (cond, x) in t1 if not cond),
(x for (cond, x) in t2 if cond),
)
t1, t2, p = tee(iterable, 3)
p1, p2 = tee(map(pred, p))
return (compress(t1, map(operator.not_, p1)), compress(t2, p2))
def powerset(iterable):
@ -712,12 +718,14 @@ def convolve(signal, kernel):
is immediately consumed and stored.
"""
# This implementation intentionally doesn't match the one in the itertools
# documentation.
kernel = tuple(kernel)[::-1]
n = len(kernel)
window = deque([0], maxlen=n) * n
for x in chain(signal, repeat(0, n - 1)):
window.append(x)
yield sum(map(operator.mul, kernel, window))
yield _sumprod(kernel, window)
def before_and_after(predicate, it):
@ -778,9 +786,7 @@ def sliding_window(iterable, n):
For a variant with more features, see :func:`windowed`.
"""
it = iter(iterable)
window = deque(islice(it, n), maxlen=n)
if len(window) == n:
yield tuple(window)
window = deque(islice(it, n - 1), maxlen=n)
for x in it:
window.append(x)
yield tuple(window)
@ -807,12 +813,8 @@ def polynomial_from_roots(roots):
>>> polynomial_from_roots(roots) # x^3 - 4 * x^2 - 17 * x + 60
[1, -4, -17, 60]
"""
# Use math.prod for Python 3.8+,
prod = getattr(math, 'prod', lambda x: reduce(operator.mul, x, 1))
roots = list(map(operator.neg, roots))
return [
sum(map(prod, combinations(roots, k))) for k in range(len(roots) + 1)
]
factors = zip(repeat(1), map(operator.neg, roots))
return list(reduce(convolve, factors, [1]))
def iter_index(iterable, value, start=0):
@ -830,9 +832,13 @@ def iter_index(iterable, value, start=0):
except AttributeError:
# Slow path for general iterables
it = islice(iterable, start, None)
for i, element in enumerate(it, start):
if element is value or element == value:
i = start - 1
try:
while True:
i = i + operator.indexOf(it, value) + 1
yield i
except ValueError:
pass
else:
# Fast path for sequences
i = start - 1
@ -850,43 +856,45 @@ def sieve(n):
>>> list(sieve(30))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
"""
isqrt = getattr(math, 'isqrt', lambda x: int(math.sqrt(x)))
data = bytearray((0, 1)) * (n // 2)
data[:3] = 0, 0, 0
limit = isqrt(n) + 1
limit = math.isqrt(n) + 1
for p in compress(range(limit), data):
data[p * p : n : p + p] = bytes(len(range(p * p, n, p + p)))
data[2] = 1
return iter_index(data, 1) if n > 2 else iter([])
def batched(iterable, n):
def _batched(iterable, n):
"""Batch data into lists of length *n*. The last batch may be shorter.
>>> list(batched('ABCDEFG', 3))
[['A', 'B', 'C'], ['D', 'E', 'F'], ['G']]
[('A', 'B', 'C'), ('D', 'E', 'F'), ('G',)]
This recipe is from the ``itertools`` docs. This library also provides
:func:`chunked`, which has a different implementation.
On Python 3.12 and above, this is an alias for :func:`itertools.batched`.
"""
if hexversion >= 0x30C00A0: # Python 3.12.0a0
warnings.warn(
(
'batched will be removed in a future version of '
'more-itertools. Use the standard library '
'itertools.batched function instead'
),
DeprecationWarning,
)
if n < 1:
raise ValueError('n must be at least one')
it = iter(iterable)
while True:
batch = list(islice(it, n))
batch = tuple(islice(it, n))
if not batch:
break
yield batch
try:
from itertools import batched as itertools_batched
except ImportError:
batched = _batched
else:
def batched(iterable, n):
return itertools_batched(iterable, n)
batched.__doc__ = _batched.__doc__
def transpose(it):
"""Swap the rows and columns of the input.
@ -894,21 +902,21 @@ def transpose(it):
[(1, 11), (2, 22), (3, 33)]
The caller should ensure that the dimensions of the input are compatible.
If the input is empty, no output will be produced.
"""
# TODO: when 3.9 goes end-of-life, add stric=True to this.
return zip(*it)
return _zip_strict(*it)
def matmul(m1, m2):
"""Multiply two matrices.
>>> list(matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)]))
[[49, 80], [41, 60]]
[(49, 80), (41, 60)]
The caller should ensure that the dimensions of the input matrices are
compatible with each other.
"""
n = len(m2[0])
return batched(starmap(dotproduct, product(m1, transpose(m2))), n)
return batched(starmap(_sumprod, product(m1, transpose(m2))), n)
def factor(n):
@ -916,15 +924,54 @@ def factor(n):
>>> list(factor(360))
[2, 2, 2, 3, 3, 5]
"""
isqrt = getattr(math, 'isqrt', lambda x: int(math.sqrt(x)))
for prime in sieve(isqrt(n) + 1):
for prime in sieve(math.isqrt(n) + 1):
while True:
quotient, remainder = divmod(n, prime)
if remainder:
if n % prime:
break
yield prime
n = quotient
n //= prime
if n == 1:
return
if n >= 2:
if n > 1:
yield n
def polynomial_eval(coefficients, x):
"""Evaluate a polynomial at a specific value.
Example: evaluating x^3 - 4 * x^2 - 17 * x + 60 at x = 2.5:
>>> coefficients = [1, -4, -17, 60]
>>> x = 2.5
>>> polynomial_eval(coefficients, x)
8.125
"""
n = len(coefficients)
if n == 0:
return x * 0 # coerce zero to the type of x
powers = map(pow, repeat(x), reversed(range(n)))
return _sumprod(coefficients, powers)
def sum_of_squares(it):
"""Return the sum of the squares of the input values.
>>> sum_of_squares([10, 20, 30])
1400
"""
return _sumprod(*tee(it))
def polynomial_derivative(coefficients):
"""Compute the first derivative of a polynomial.
Example: evaluating the derivative of x^3 - 4 * x^2 - 17 * x + 60
>>> coefficients = [1, -4, -17, 60]
>>> derivative_coefficients = polynomial_derivative(coefficients)
>>> derivative_coefficients
[3, -8, -17]
"""
n = len(coefficients)
powers = reversed(range(1, n))
return list(map(operator.mul, coefficients, powers))

View file

@ -21,7 +21,7 @@ def tabulate(
function: Callable[[int], _T], start: int = ...
) -> Iterator[_T]: ...
def tail(n: int, iterable: Iterable[_T]) -> Iterator[_T]: ...
def consume(iterator: Iterable[object], n: int | None = ...) -> None: ...
def consume(iterator: Iterable[_T], n: int | None = ...) -> None: ...
@overload
def nth(iterable: Iterable[_T], n: int) -> _T | None: ...
@overload
@ -101,7 +101,7 @@ def sliding_window(
iterable: Iterable[_T], n: int
) -> Iterator[tuple[_T, ...]]: ...
def subslices(iterable: Iterable[_T]) -> Iterator[list[_T]]: ...
def polynomial_from_roots(roots: Sequence[int]) -> list[int]: ...
def polynomial_from_roots(roots: Sequence[_T]) -> list[_T]: ...
def iter_index(
iterable: Iterable[object],
value: Any,
@ -111,9 +111,12 @@ def sieve(n: int) -> Iterator[int]: ...
def batched(
iterable: Iterable[_T],
n: int,
) -> Iterator[list[_T]]: ...
) -> Iterator[tuple[_T]]: ...
def transpose(
it: Iterable[Iterable[_T]],
) -> tuple[Iterator[_T], ...]: ...
def matmul(m1: Sequence[_T], m2: Sequence[_T]) -> Iterator[list[_T]]: ...
) -> Iterator[tuple[_T, ...]]: ...
def matmul(m1: Sequence[_T], m2: Sequence[_T]) -> Iterator[tuple[_T]]: ...
def factor(n: int) -> Iterator[int]: ...
def polynomial_eval(coefficients: Sequence[_T], x: _U) -> _U: ...
def sum_of_squares(it: Iterable[_T]) -> _T: ...
def polynomial_derivative(coefficients: Sequence[_T]) -> list[_T]: ...

View file

@ -22,8 +22,8 @@ from pytz.tzfile import build_tzinfo
# The IANA (nee Olson) database is updated several times a year.
OLSON_VERSION = '2022g'
VERSION = '2022.7.1' # pip compatible version number.
OLSON_VERSION = '2023c'
VERSION = '2023.3' # pip compatible version number.
__version__ = VERSION
OLSEN_VERSION = OLSON_VERSION # Old releases had this misspelling
@ -1311,7 +1311,6 @@ common_timezones = \
'America/Whitehorse',
'America/Winnipeg',
'America/Yakutat',
'America/Yellowknife',
'Antarctica/Casey',
'Antarctica/Davis',
'Antarctica/DumontDUrville',

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -238,7 +238,7 @@ SY Syria
SZ Eswatini (Swaziland)
TC Turks & Caicos Is
TD Chad
TF French Southern Territories
TF French S. Terr.
TG Togo
TH Thailand
TJ Tajikistan

View file

@ -72,11 +72,11 @@ Leap 2016 Dec 31 23:59:60 + S
# Any additional leap seconds will come after this.
# This Expires line is commented out for now,
# so that pre-2020a zic implementations do not reject this file.
#Expires 2023 Jun 28 00:00:00
#Expires 2023 Dec 28 00:00:00
# POSIX timestamps for the data in this file:
#updated 1467936000 (2016-07-08 00:00:00 UTC)
#expires 1687910400 (2023-06-28 00:00:00 UTC)
#expires 1703721600 (2023-12-28 00:00:00 UTC)
# Updated through IERS Bulletin C64
# File expires on: 28 June 2023
# Updated through IERS Bulletin C65
# File expires on: 28 December 2023

View file

@ -75,6 +75,8 @@ R K 2014 o - May 15 24 1 S
R K 2014 o - Jun 26 24 0 -
R K 2014 o - Jul 31 24 1 S
R K 2014 o - S lastTh 24 0 -
R K 2023 ma - Ap lastF 0 1 S
R K 2023 ma - O lastTh 24 0 -
Z Africa/Cairo 2:5:9 - LMT 1900 O
2 K EE%sT
Z Africa/Bissau -1:2:20 - LMT 1912 Ja 1 1u
@ -172,7 +174,7 @@ R M 2021 o - May 16 2 0 -
R M 2022 o - Mar 27 3 -1 -
R M 2022 o - May 8 2 0 -
R M 2023 o - Mar 19 3 -1 -
R M 2023 o - Ap 30 2 0 -
R M 2023 o - Ap 23 2 0 -
R M 2024 o - Mar 10 3 -1 -
R M 2024 o - Ap 14 2 0 -
R M 2025 o - F 23 3 -1 -
@ -188,7 +190,7 @@ R M 2029 o - F 18 2 0 -
R M 2029 o - D 30 3 -1 -
R M 2030 o - F 10 2 0 -
R M 2030 o - D 22 3 -1 -
R M 2031 o - F 2 2 0 -
R M 2031 o - Ja 26 2 0 -
R M 2031 o - D 14 3 -1 -
R M 2032 o - Ja 18 2 0 -
R M 2032 o - N 28 3 -1 -
@ -204,7 +206,7 @@ R M 2036 o - N 23 2 0 -
R M 2037 o - O 4 3 -1 -
R M 2037 o - N 15 2 0 -
R M 2038 o - S 26 3 -1 -
R M 2038 o - N 7 2 0 -
R M 2038 o - O 31 2 0 -
R M 2039 o - S 18 3 -1 -
R M 2039 o - O 23 2 0 -
R M 2040 o - S 2 3 -1 -
@ -220,7 +222,7 @@ R M 2044 o - Au 28 2 0 -
R M 2045 o - Jul 9 3 -1 -
R M 2045 o - Au 20 2 0 -
R M 2046 o - Jul 1 3 -1 -
R M 2046 o - Au 12 2 0 -
R M 2046 o - Au 5 2 0 -
R M 2047 o - Jun 23 3 -1 -
R M 2047 o - Jul 28 2 0 -
R M 2048 o - Jun 7 3 -1 -
@ -236,7 +238,7 @@ R M 2052 o - Jun 2 2 0 -
R M 2053 o - Ap 13 3 -1 -
R M 2053 o - May 25 2 0 -
R M 2054 o - Ap 5 3 -1 -
R M 2054 o - May 17 2 0 -
R M 2054 o - May 10 2 0 -
R M 2055 o - Mar 28 3 -1 -
R M 2055 o - May 2 2 0 -
R M 2056 o - Mar 12 3 -1 -
@ -252,7 +254,7 @@ R M 2060 o - Mar 7 2 0 -
R M 2061 o - Ja 16 3 -1 -
R M 2061 o - F 27 2 0 -
R M 2062 o - Ja 8 3 -1 -
R M 2062 o - F 19 2 0 -
R M 2062 o - F 12 2 0 -
R M 2062 o - D 31 3 -1 -
R M 2063 o - F 4 2 0 -
R M 2063 o - D 16 3 -1 -
@ -268,7 +270,7 @@ R M 2067 o - D 11 2 0 -
R M 2068 o - O 21 3 -1 -
R M 2068 o - D 2 2 0 -
R M 2069 o - O 13 3 -1 -
R M 2069 o - N 24 2 0 -
R M 2069 o - N 17 2 0 -
R M 2070 o - O 5 3 -1 -
R M 2070 o - N 9 2 0 -
R M 2071 o - S 20 3 -1 -
@ -284,7 +286,7 @@ R M 2075 o - S 15 2 0 -
R M 2076 o - Jul 26 3 -1 -
R M 2076 o - S 6 2 0 -
R M 2077 o - Jul 18 3 -1 -
R M 2077 o - Au 29 2 0 -
R M 2077 o - Au 22 2 0 -
R M 2078 o - Jul 10 3 -1 -
R M 2078 o - Au 14 2 0 -
R M 2079 o - Jun 25 3 -1 -
@ -294,13 +296,13 @@ R M 2080 o - Jul 21 2 0 -
R M 2081 o - Jun 1 3 -1 -
R M 2081 o - Jul 13 2 0 -
R M 2082 o - May 24 3 -1 -
R M 2082 o - Jul 5 2 0 -
R M 2082 o - Jun 28 2 0 -
R M 2083 o - May 16 3 -1 -
R M 2083 o - Jun 20 2 0 -
R M 2084 o - Ap 30 3 -1 -
R M 2084 o - Jun 11 2 0 -
R M 2085 o - Ap 22 3 -1 -
R M 2085 o - Jun 3 2 0 -
R M 2085 o - May 27 2 0 -
R M 2086 o - Ap 14 3 -1 -
R M 2086 o - May 19 2 0 -
R M 2087 o - Mar 30 3 -1 -
@ -997,8 +999,86 @@ R P 2020 2021 - Mar Sa<=30 0 1 S
R P 2020 o - O 24 1 0 -
R P 2021 o - O 29 1 0 -
R P 2022 o - Mar 27 0 1 S
R P 2022 ma - O Sa<=30 2 0 -
R P 2023 ma - Mar Sa<=30 2 1 S
R P 2022 2035 - O Sa<=30 2 0 -
R P 2023 o - Ap 29 2 1 S
R P 2024 o - Ap 13 2 1 S
R P 2025 o - Ap 5 2 1 S
R P 2026 2054 - Mar Sa<=30 2 1 S
R P 2036 o - O 18 2 0 -
R P 2037 o - O 10 2 0 -
R P 2038 o - S 25 2 0 -
R P 2039 o - S 17 2 0 -
R P 2039 o - O 22 2 1 S
R P 2039 2067 - O Sa<=30 2 0 -
R P 2040 o - S 1 2 0 -
R P 2040 o - O 13 2 1 S
R P 2041 o - Au 24 2 0 -
R P 2041 o - S 28 2 1 S
R P 2042 o - Au 16 2 0 -
R P 2042 o - S 20 2 1 S
R P 2043 o - Au 1 2 0 -
R P 2043 o - S 12 2 1 S
R P 2044 o - Jul 23 2 0 -
R P 2044 o - Au 27 2 1 S
R P 2045 o - Jul 15 2 0 -
R P 2045 o - Au 19 2 1 S
R P 2046 o - Jun 30 2 0 -
R P 2046 o - Au 11 2 1 S
R P 2047 o - Jun 22 2 0 -
R P 2047 o - Jul 27 2 1 S
R P 2048 o - Jun 6 2 0 -
R P 2048 o - Jul 18 2 1 S
R P 2049 o - May 29 2 0 -
R P 2049 o - Jul 3 2 1 S
R P 2050 o - May 21 2 0 -
R P 2050 o - Jun 25 2 1 S
R P 2051 o - May 6 2 0 -
R P 2051 o - Jun 17 2 1 S
R P 2052 o - Ap 27 2 0 -
R P 2052 o - Jun 1 2 1 S
R P 2053 o - Ap 12 2 0 -
R P 2053 o - May 24 2 1 S
R P 2054 o - Ap 4 2 0 -
R P 2054 o - May 16 2 1 S
R P 2055 o - May 1 2 1 S
R P 2056 o - Ap 22 2 1 S
R P 2057 o - Ap 7 2 1 S
R P 2058 ma - Mar Sa<=30 2 1 S
R P 2068 o - O 20 2 0 -
R P 2069 o - O 12 2 0 -
R P 2070 o - O 4 2 0 -
R P 2071 o - S 19 2 0 -
R P 2072 o - S 10 2 0 -
R P 2072 o - O 15 2 1 S
R P 2073 o - S 2 2 0 -
R P 2073 o - O 7 2 1 S
R P 2074 o - Au 18 2 0 -
R P 2074 o - S 29 2 1 S
R P 2075 o - Au 10 2 0 -
R P 2075 o - S 14 2 1 S
R P 2075 ma - O Sa<=30 2 0 -
R P 2076 o - Jul 25 2 0 -
R P 2076 o - S 5 2 1 S
R P 2077 o - Jul 17 2 0 -
R P 2077 o - Au 28 2 1 S
R P 2078 o - Jul 9 2 0 -
R P 2078 o - Au 13 2 1 S
R P 2079 o - Jun 24 2 0 -
R P 2079 o - Au 5 2 1 S
R P 2080 o - Jun 15 2 0 -
R P 2080 o - Jul 20 2 1 S
R P 2081 o - Jun 7 2 0 -
R P 2081 o - Jul 12 2 1 S
R P 2082 o - May 23 2 0 -
R P 2082 o - Jul 4 2 1 S
R P 2083 o - May 15 2 0 -
R P 2083 o - Jun 19 2 1 S
R P 2084 o - Ap 29 2 0 -
R P 2084 o - Jun 10 2 1 S
R P 2085 o - Ap 21 2 0 -
R P 2085 o - Jun 2 2 1 S
R P 2086 o - Ap 13 2 0 -
R P 2086 o - May 18 2 1 S
Z Asia/Gaza 2:17:52 - LMT 1900 O
2 Z EET/EEST 1948 May 15
2 K EE%sT 1967 Jun 5
@ -1754,8 +1834,8 @@ Z America/Scoresbysund -1:27:52 - LMT 1916 Jul 28
-1 E -01/+00
Z America/Nuuk -3:26:56 - LMT 1916 Jul 28
-3 - -03 1980 Ap 6 2
-3 E -03/-02 2023 Mar 25 22
-2 - -02
-3 E -03/-02 2023 O 29 1u
-2 E -02/-01
Z America/Thule -4:35:8 - LMT 1916 Jul 28
-4 Th A%sT
Z Europe/Tallinn 1:39 - LMT 1880
@ -2175,13 +2255,13 @@ Z Europe/Volgograd 2:57:40 - LMT 1920 Ja 3
3 - +03 1930 Jun 21
4 - +04 1961 N 11
4 R +04/+05 1988 Mar 27 2s
3 R +03/+04 1991 Mar 31 2s
3 R MSK/MSD 1991 Mar 31 2s
4 - +04 1992 Mar 29 2s
3 R +03/+04 2011 Mar 27 2s
4 - +04 2014 O 26 2s
3 - +03 2018 O 28 2s
3 R MSK/MSD 2011 Mar 27 2s
4 - MSK 2014 O 26 2s
3 - MSK 2018 O 28 2s
4 - +04 2020 D 27 2s
3 - +03
3 - MSK
Z Europe/Saratov 3:4:18 - LMT 1919 Jul 1 0u
3 - +03 1930 Jun 21
4 R +04/+05 1988 Mar 27 2s
@ -2194,11 +2274,11 @@ Z Europe/Saratov 3:4:18 - LMT 1919 Jul 1 0u
Z Europe/Kirov 3:18:48 - LMT 1919 Jul 1 0u
3 - +03 1930 Jun 21
4 R +04/+05 1989 Mar 26 2s
3 R +03/+04 1991 Mar 31 2s
3 R MSK/MSD 1991 Mar 31 2s
4 - +04 1992 Mar 29 2s
3 R +03/+04 2011 Mar 27 2s
4 - +04 2014 O 26 2s
3 - +03
3 R MSK/MSD 2011 Mar 27 2s
4 - MSK 2014 O 26 2s
3 - MSK
Z Europe/Samara 3:20:20 - LMT 1919 Jul 1 0u
3 - +03 1930 Jun 21
4 - +04 1935 Ja 27
@ -3070,9 +3150,6 @@ Z America/Cambridge_Bay 0 - -00 1920
-5 - EST 2000 N 5
-6 - CST 2001 Ap 1 3
-7 C M%sT
Z America/Yellowknife 0 - -00 1935
-7 Y M%sT 1980
-7 C M%sT
Z America/Inuvik 0 - -00 1953
-8 Y P%sT 1979 Ap lastSu 2
-7 Y M%sT 1980
@ -4171,6 +4248,7 @@ L America/Argentina/Cordoba America/Rosario
L America/Tijuana America/Santa_Isabel
L America/Denver America/Shiprock
L America/Toronto America/Thunder_Bay
L America/Edmonton America/Yellowknife
L Pacific/Auckland Antarctica/South_Pole
L Asia/Shanghai Asia/Chongqing
L Asia/Shanghai Asia/Harbin

View file

@ -121,9 +121,8 @@ CA +744144-0944945 America/Resolute Central - NU (Resolute)
CA +624900-0920459 America/Rankin_Inlet Central - NU (central)
CA +5024-10439 America/Regina CST - SK (most areas)
CA +5017-10750 America/Swift_Current CST - SK (midwest)
CA +5333-11328 America/Edmonton Mountain - AB; BC (E); SK (W)
CA +5333-11328 America/Edmonton Mountain - AB; BC (E); NT (E); SK (W)
CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west)
CA +6227-11421 America/Yellowknife Mountain - NT (central)
CA +682059-1334300 America/Inuvik Mountain - NT (west)
CA +4906-11631 America/Creston MST - BC (Creston)
CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
@ -139,7 +138,7 @@ CG -0416+01517 Africa/Brazzaville
CH +4723+00832 Europe/Zurich
CI +0519-00402 Africa/Abidjan
CK -2114-15946 Pacific/Rarotonga
CL -3327-07040 America/Santiago Chile (most areas)
CL -3327-07040 America/Santiago most of Chile
CL -5309-07055 America/Punta_Arenas Region of Magallanes
CL -2709-10926 Pacific/Easter Easter Island
CM +0403+00942 Africa/Douala
@ -151,10 +150,10 @@ CU +2308-08222 America/Havana
CV +1455-02331 Atlantic/Cape_Verde
CW +1211-06900 America/Curacao
CX -1025+10543 Indian/Christmas
CY +3510+03322 Asia/Nicosia Cyprus (most areas)
CY +3510+03322 Asia/Nicosia most of Cyprus
CY +3507+03357 Asia/Famagusta Northern Cyprus
CZ +5005+01426 Europe/Prague
DE +5230+01322 Europe/Berlin Germany (most areas)
DE +5230+01322 Europe/Berlin most of Germany
DE +4742+00841 Europe/Busingen Busingen
DJ +1136+04309 Africa/Djibouti
DK +5540+01235 Europe/Copenhagen
@ -187,7 +186,7 @@ GF +0456-05220 America/Cayenne
GG +492717-0023210 Europe/Guernsey
GH +0533-00013 Africa/Accra
GI +3608-00521 Europe/Gibraltar
GL +6411-05144 America/Nuuk Greenland (most areas)
GL +6411-05144 America/Nuuk most of Greenland
GL +7646-01840 America/Danmarkshavn National Park (east coast)
GL +7029-02158 America/Scoresbysund Scoresbysund/Ittoqqortoormiit
GL +7634-06847 America/Thule Thule/Pituffik
@ -235,7 +234,7 @@ KP +3901+12545 Asia/Pyongyang
KR +3733+12658 Asia/Seoul
KW +2920+04759 Asia/Kuwait
KY +1918-08123 America/Cayman
KZ +4315+07657 Asia/Almaty Kazakhstan (most areas)
KZ +4315+07657 Asia/Almaty most of Kazakhstan
KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda
KZ +5312+06337 Asia/Qostanay Qostanay/Kostanay/Kustanay
KZ +5017+05710 Asia/Aqtobe Aqtobe/Aktobe
@ -259,12 +258,12 @@ MD +4700+02850 Europe/Chisinau
ME +4226+01916 Europe/Podgorica
MF +1804-06305 America/Marigot
MG -1855+04731 Indian/Antananarivo
MH +0709+17112 Pacific/Majuro Marshall Islands (most areas)
MH +0709+17112 Pacific/Majuro most of Marshall Islands
MH +0905+16720 Pacific/Kwajalein Kwajalein
MK +4159+02126 Europe/Skopje
ML +1239-00800 Africa/Bamako
MM +1647+09610 Asia/Yangon
MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas)
MN +4755+10653 Asia/Ulaanbaatar most of Mongolia
MN +4801+09139 Asia/Hovd Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
MN +4804+11430 Asia/Choibalsan Dornod, Sukhbaatar
MO +221150+1133230 Asia/Macau
@ -302,7 +301,7 @@ NO +5955+01045 Europe/Oslo
NP +2743+08519 Asia/Kathmandu
NR -0031+16655 Pacific/Nauru
NU -1901-16955 Pacific/Niue
NZ -3652+17446 Pacific/Auckland New Zealand (most areas)
NZ -3652+17446 Pacific/Auckland most of New Zealand
NZ -4357-17633 Pacific/Chatham Chatham Islands
OM +2336+05835 Asia/Muscat
PA +0858-07932 America/Panama
@ -310,7 +309,7 @@ PE -1203-07703 America/Lima
PF -1732-14934 Pacific/Tahiti Society Islands
PF -0900-13930 Pacific/Marquesas Marquesas Islands
PF -2308-13457 Pacific/Gambier Gambier Islands
PG -0930+14710 Pacific/Port_Moresby Papua New Guinea (most areas)
PG -0930+14710 Pacific/Port_Moresby most of Papua New Guinea
PG -0613+15534 Pacific/Bougainville Bougainville
PH +1435+12100 Asia/Manila
PK +2452+06703 Asia/Karachi
@ -356,7 +355,7 @@ RU +4310+13156 Asia/Vladivostok MSK+07 - Amur River
RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky
RU +5934+15048 Asia/Magadan MSK+08 - Magadan
RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island
RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); North Kuril Is
RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); N Kuril Is
RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka
RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea
RW -0157+03004 Africa/Kigali
@ -397,7 +396,7 @@ TT +1039-06131 America/Port_of_Spain
TV -0831+17913 Pacific/Funafuti
TW +2503+12130 Asia/Taipei
TZ -0648+03917 Africa/Dar_es_Salaam
UA +5026+03031 Europe/Kyiv Ukraine (most areas)
UA +5026+03031 Europe/Kyiv most of Ukraine
UG +0019+03225 Africa/Kampala
UM +2813-17722 Pacific/Midway Midway Islands
UM +1917+16637 Pacific/Wake Wake Island
@ -420,7 +419,7 @@ US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural)
US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer)
US +394421-1045903 America/Denver Mountain (most areas)
US +433649-1161209 America/Boise Mountain - ID (south); OR (east)
US +332654-1120424 America/Phoenix MST - Arizona (except Navajo)
US +332654-1120424 America/Phoenix MST - AZ (except Navajo)
US +340308-1181434 America/Los_Angeles Pacific
US +611305-1495401 America/Anchorage Alaska (most areas)
US +581807-1342511 America/Juneau Alaska - Juneau area
@ -428,7 +427,7 @@ US +571035-1351807 America/Sitka Alaska - Sitka area
US +550737-1313435 America/Metlakatla Alaska - Annette Island
US +593249-1394338 America/Yakutat Alaska - Yakutat
US +643004-1652423 America/Nome Alaska (west)
US +515248-1763929 America/Adak Aleutian Islands
US +515248-1763929 America/Adak Alaska - western Aleutians
US +211825-1575130 Pacific/Honolulu Hawaii
UY -345433-0561245 America/Montevideo
UZ +3940+06648 Asia/Samarkand Uzbekistan (west)

View file

@ -18,7 +18,10 @@
# Please see the theory.html file for how these names are chosen.
# If multiple timezones overlap a country, each has a row in the
# table, with each column 1 containing the country code.
# 4. Comments; present if and only if a country has multiple timezones.
# 4. Comments; present if and only if countries have multiple timezones,
# and useful only for those countries. For example, the comments
# for the row with countries CH,DE,LI and name Europe/Zurich
# are useful only for DE, since CH and LI have no other timezones.
#
# If a timezone covers multiple countries, the most-populous city is used,
# and that country is listed first in column 1; any other countries
@ -34,7 +37,7 @@
#country-
#codes coordinates TZ comments
AD +4230+00131 Europe/Andorra
AE,OM,RE,SC,TF +2518+05518 Asia/Dubai UAE, Oman, Réunion, Seychelles, Crozet, Scattered Is
AE,OM,RE,SC,TF +2518+05518 Asia/Dubai Crozet, Scattered Is
AF +3431+06912 Asia/Kabul
AL +4120+01950 Europe/Tirane
AM +4011+04430 Asia/Yerevan
@ -45,7 +48,7 @@ AQ -6448-06406 Antarctica/Palmer Palmer
AQ -6734-06808 Antarctica/Rothera Rothera
AQ -720041+0023206 Antarctica/Troll Troll
AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF)
AR -3124-06411 America/Argentina/Cordoba Argentina (most areas: CB, CC, CN, ER, FM, MN, SE, SF)
AR -3124-06411 America/Argentina/Cordoba most areas: CB, CC, CN, ER, FM, MN, SE, SF
AR -2447-06525 America/Argentina/Salta Salta (SA, LP, NQ, RN)
AR -2411-06518 America/Argentina/Jujuy Jujuy (JY)
AR -2649-06513 America/Argentina/Tucuman Tucumán (TM)
@ -56,7 +59,7 @@ AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ)
AR -3319-06621 America/Argentina/San_Luis San Luis (SL)
AR -5138-06913 America/Argentina/Rio_Gallegos Santa Cruz (SC)
AR -5448-06818 America/Argentina/Ushuaia Tierra del Fuego (TF)
AS,UM -1416-17042 Pacific/Pago_Pago Samoa, Midway
AS,UM -1416-17042 Pacific/Pago_Pago Midway
AT +4813+01620 Europe/Vienna
AU -3133+15905 Australia/Lord_Howe Lord Howe Island
AU -5430+15857 Antarctica/Macquarie Macquarie Island
@ -101,26 +104,25 @@ CA +4439-06336 America/Halifax Atlantic - NS (most areas); PE
CA +4612-05957 America/Glace_Bay Atlantic - NS (Cape Breton)
CA +4606-06447 America/Moncton Atlantic - New Brunswick
CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas)
CA,BS +4339-07923 America/Toronto Eastern - ON, QC (most areas), Bahamas
CA,BS +4339-07923 America/Toronto Eastern - ON, QC (most areas)
CA +6344-06828 America/Iqaluit Eastern - NU (most areas)
CA +4953-09709 America/Winnipeg Central - ON (west); Manitoba
CA +744144-0944945 America/Resolute Central - NU (Resolute)
CA +624900-0920459 America/Rankin_Inlet Central - NU (central)
CA +5024-10439 America/Regina CST - SK (most areas)
CA +5017-10750 America/Swift_Current CST - SK (midwest)
CA +5333-11328 America/Edmonton Mountain - AB; BC (E); SK (W)
CA +5333-11328 America/Edmonton Mountain - AB; BC (E); NT (E); SK (W)
CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west)
CA +6227-11421 America/Yellowknife Mountain - NT (central)
CA +682059-1334300 America/Inuvik Mountain - NT (west)
CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson)
CA +6043-13503 America/Whitehorse MST - Yukon (east)
CA +6404-13925 America/Dawson MST - Yukon (west)
CA +4916-12307 America/Vancouver Pacific - BC (most areas)
CH,DE,LI +4723+00832 Europe/Zurich Swiss time
CH,DE,LI +4723+00832 Europe/Zurich Büsingen
CI,BF,GH,GM,GN,IS,ML,MR,SH,SL,SN,TG +0519-00402 Africa/Abidjan
CK -2114-15946 Pacific/Rarotonga
CL -3327-07040 America/Santiago Chile (most areas)
CL -3327-07040 America/Santiago most of Chile
CL -5309-07055 America/Punta_Arenas Region of Magallanes
CL -2709-10926 Pacific/Easter Easter Island
CN +3114+12128 Asia/Shanghai Beijing Time
@ -129,10 +131,10 @@ CO +0436-07405 America/Bogota
CR +0956-08405 America/Costa_Rica
CU +2308-08222 America/Havana
CV +1455-02331 Atlantic/Cape_Verde
CY +3510+03322 Asia/Nicosia Cyprus (most areas)
CY +3510+03322 Asia/Nicosia most of Cyprus
CY +3507+03357 Asia/Famagusta Northern Cyprus
CZ,SK +5005+01426 Europe/Prague
DE,DK,NO,SE,SJ +5230+01322 Europe/Berlin Germany (most areas), Scandinavia
DE,DK,NO,SE,SJ +5230+01322 Europe/Berlin most of Germany
DO +1828-06954 America/Santo_Domingo
DZ +3647+00303 Africa/Algiers
EC -0210-07950 America/Guayaquil Ecuador (mainland)
@ -153,7 +155,7 @@ GB,GG,IM,JE +513030-0000731 Europe/London
GE +4143+04449 Asia/Tbilisi
GF +0456-05220 America/Cayenne
GI +3608-00521 Europe/Gibraltar
GL +6411-05144 America/Nuuk Greenland (most areas)
GL +6411-05144 America/Nuuk most of Greenland
GL +7646-01840 America/Danmarkshavn National Park (east coast)
GL +7029-02158 America/Scoresbysund Scoresbysund/Ittoqqortoormiit
GL +7634-06847 America/Thule Thule/Pituffik
@ -183,12 +185,12 @@ JO +3157+03556 Asia/Amman
JP +353916+1394441 Asia/Tokyo
KE,DJ,ER,ET,KM,MG,SO,TZ,UG,YT -0117+03649 Africa/Nairobi
KG +4254+07436 Asia/Bishkek
KI,MH,TV,UM,WF +0125+17300 Pacific/Tarawa Gilberts, Marshalls, Tuvalu, Wallis & Futuna, Wake
KI,MH,TV,UM,WF +0125+17300 Pacific/Tarawa Gilberts, Marshalls, Wake
KI -0247-17143 Pacific/Kanton Phoenix Islands
KI +0152-15720 Pacific/Kiritimati Line Islands
KP +3901+12545 Asia/Pyongyang
KR +3733+12658 Asia/Seoul
KZ +4315+07657 Asia/Almaty Kazakhstan (most areas)
KZ +4315+07657 Asia/Almaty most of Kazakhstan
KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda
KZ +5312+06337 Asia/Qostanay Qostanay/Kostanay/Kustanay
KZ +5017+05710 Asia/Aqtobe Aqtöbe/Aktobe
@ -205,14 +207,14 @@ MA +3339-00735 Africa/Casablanca
MD +4700+02850 Europe/Chisinau
MH +0905+16720 Pacific/Kwajalein Kwajalein
MM,CC +1647+09610 Asia/Yangon
MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas)
MN +4755+10653 Asia/Ulaanbaatar most of Mongolia
MN +4801+09139 Asia/Hovd Bayan-Ölgii, Govi-Altai, Hovd, Uvs, Zavkhan
MN +4804+11430 Asia/Choibalsan Dornod, Sükhbaatar
MO +221150+1133230 Asia/Macau
MQ +1436-06105 America/Martinique
MT +3554+01431 Europe/Malta
MU -2010+05730 Indian/Mauritius
MV,TF +0410+07330 Indian/Maldives Maldives, Kerguelen, St Paul I, Amsterdam I
MV,TF +0410+07330 Indian/Maldives Kerguelen, St Paul I, Amsterdam I
MX +1924-09909 America/Mexico_City Central Mexico
MX +2105-08646 America/Cancun Quintana Roo
MX +2058-08937 America/Merida Campeche, Yucatán
@ -225,7 +227,7 @@ MX +2313-10625 America/Mazatlan Baja California Sur, Nayarit (most areas), Sinal
MX +2048-10515 America/Bahia_Banderas Bahía de Banderas
MX +2904-11058 America/Hermosillo Sonora
MX +3232-11701 America/Tijuana Baja California
MY,BN +0133+11020 Asia/Kuching Sabah, Sarawak, Brunei
MY,BN +0133+11020 Asia/Kuching Sabah, Sarawak
MZ,BI,BW,CD,MW,RW,ZM,ZW -2558+03235 Africa/Maputo Central Africa Time
NA -2234+01706 Africa/Windhoek
NC -2216+16627 Pacific/Noumea
@ -237,7 +239,7 @@ NR -0031+16655 Pacific/Nauru
NU -1901-16955 Pacific/Niue
NZ,AQ -3652+17446 Pacific/Auckland New Zealand time
NZ -4357-17633 Pacific/Chatham Chatham Islands
PA,CA,KY +0858-07932 America/Panama EST - Panama, Cayman, ON (Atikokan), NU (Coral H)
PA,CA,KY +0858-07932 America/Panama EST - ON (Atikokan), NU (Coral H)
PE -1203-07703 America/Lima
PF -1732-14934 Pacific/Tahiti Society Islands
PF -0900-13930 Pacific/Marquesas Marquesas Islands
@ -285,13 +287,13 @@ RU +4310+13156 Asia/Vladivostok MSK+07 - Amur River
RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky
RU +5934+15048 Asia/Magadan MSK+08 - Magadan
RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island
RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); North Kuril Is
RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); N Kuril Is
RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka
RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea
SA,AQ,KW,YE +2438+04643 Asia/Riyadh Arabia, Syowa
SB,FM -0932+16012 Pacific/Guadalcanal Solomons, Pohnpei
SA,AQ,KW,YE +2438+04643 Asia/Riyadh Syowa
SB,FM -0932+16012 Pacific/Guadalcanal Pohnpei
SD +1536+03232 Africa/Khartoum
SG,MY +0117+10351 Asia/Singapore Singapore, peninsular Malaysia
SG,MY +0117+10351 Asia/Singapore peninsular Malaysia
SR +0550-05510 America/Paramaribo
SS +0451+03137 Africa/Juba
ST +0020+00644 Africa/Sao_Tome
@ -299,7 +301,7 @@ SV +1342-08912 America/El_Salvador
SY +3330+03618 Asia/Damascus
TC +2128-07108 America/Grand_Turk
TD +1207+01503 Africa/Ndjamena
TH,CX,KH,LA,VN +1345+10031 Asia/Bangkok Indochina (most areas)
TH,CX,KH,LA,VN +1345+10031 Asia/Bangkok north Vietnam
TJ +3835+06848 Asia/Dushanbe
TK -0922-17114 Pacific/Fakaofo
TL -0833+12535 Asia/Dili
@ -308,7 +310,7 @@ TN +3648+01011 Africa/Tunis
TO -210800-1751200 Pacific/Tongatapu
TR +4101+02858 Europe/Istanbul
TW +2503+12130 Asia/Taipei
UA +5026+03031 Europe/Kyiv Ukraine (most areas)
UA +5026+03031 Europe/Kyiv most of Ukraine
US +404251-0740023 America/New_York Eastern (most areas)
US +421953-0830245 America/Detroit Eastern - MI (most areas)
US +381515-0854534 America/Kentucky/Louisville Eastern - KY (Louisville area)
@ -328,7 +330,7 @@ US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural)
US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer)
US +394421-1045903 America/Denver Mountain (most areas)
US +433649-1161209 America/Boise Mountain - ID (south); OR (east)
US,CA +332654-1120424 America/Phoenix MST - Arizona (except Navajo), Creston BC
US,CA +332654-1120424 America/Phoenix MST - AZ (most areas), Creston BC
US +340308-1181434 America/Los_Angeles Pacific
US +611305-1495401 America/Anchorage Alaska (most areas)
US +581807-1342511 America/Juneau Alaska - Juneau area
@ -336,13 +338,13 @@ US +571035-1351807 America/Sitka Alaska - Sitka area
US +550737-1313435 America/Metlakatla Alaska - Annette Island
US +593249-1394338 America/Yakutat Alaska - Yakutat
US +643004-1652423 America/Nome Alaska (west)
US +515248-1763929 America/Adak Aleutian Islands
US,UM +211825-1575130 Pacific/Honolulu Hawaii
US +515248-1763929 America/Adak Alaska - western Aleutians
US +211825-1575130 Pacific/Honolulu Hawaii
UY -345433-0561245 America/Montevideo
UZ +3940+06648 Asia/Samarkand Uzbekistan (west)
UZ +4120+06918 Asia/Tashkent Uzbekistan (east)
VE +1030-06656 America/Caracas
VN +1045+10640 Asia/Ho_Chi_Minh Vietnam (south)
VN +1045+10640 Asia/Ho_Chi_Minh south Vietnam
VU -1740+16825 Pacific/Efate
WS -1350-17144 Pacific/Apia
ZA,LS,SZ -2615+02800 Africa/Johannesburg

View file

@ -383,9 +383,9 @@ def parse_timedelta(str):
Note that months and years strict intervals, not aligned
to a calendar:
>>> now = datetime.datetime.now()
>>> later = now + parse_timedelta('1 year')
>>> diff = later.replace(year=now.year) - now
>>> date = datetime.datetime.fromisoformat('2000-01-01')
>>> later = date + parse_timedelta('1 year')
>>> diff = later.replace(year=date.year) - date
>>> diff.seconds
20940

View file

@ -28,7 +28,7 @@ def now():
A client may override this function to change the default behavior,
such as to use local time or timezone-naïve times.
"""
return datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
return datetime.datetime.now(pytz.utc)
def from_timestamp(ts):
@ -38,7 +38,7 @@ def from_timestamp(ts):
A client may override this function to change the default behavior,
such as to use local time or timezone-naïve times.
"""
return datetime.datetime.utcfromtimestamp(ts).replace(tzinfo=pytz.utc)
return datetime.datetime.fromtimestamp(ts, pytz.utc)
class DelayedCommand(datetime.datetime):

View file

@ -48,20 +48,21 @@ class Stopwatch:
def reset(self):
self.elapsed = datetime.timedelta(0)
with contextlib.suppress(AttributeError):
del self.start_time
del self._start
def _diff(self):
return datetime.timedelta(seconds=time.monotonic() - self._start)
def start(self):
self.start_time = datetime.datetime.utcnow()
self._start = time.monotonic()
def stop(self):
stop_time = datetime.datetime.utcnow()
self.elapsed += stop_time - self.start_time
del self.start_time
self.elapsed += self._diff()
del self._start
return self.elapsed
def split(self):
local_duration = datetime.datetime.utcnow() - self.start_time
return self.elapsed + local_duration
return self.elapsed + self._diff()
# context manager support
def __enter__(self):