From 1bedec188b13f727354fd08331dfffe10e23aaa0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 30 Jan 2022 13:00:12 +0200 Subject: [PATCH] Don't deprecate Unit --- src/humanize/time.py | 92 +++++++++++++------------------------------- tests/test_time.py | 2 +- 2 files changed, 28 insertions(+), 66 deletions(-) diff --git a/src/humanize/time.py b/src/humanize/time.py index e4bbc11..21f6a08 100644 --- a/src/humanize/time.py +++ b/src/humanize/time.py @@ -8,7 +8,7 @@ import datetime as dt import math import warnings -from enum import Enum, EnumMeta +from enum import Enum from functools import total_ordering from .i18n import _gettext as _ @@ -25,7 +25,7 @@ @total_ordering -class _Unit(Enum): +class Unit(Enum): MICROSECONDS = 0 MILLISECONDS = 1 SECONDS = 2 @@ -41,44 +41,6 @@ def __lt__(self, other): return NotImplemented -class _UnitMeta(EnumMeta): - """Metaclass for an enum that emits deprecation warnings when accessed.""" - - def __getattribute__(self, name): - # Temporarily comment out to avoid warning during 'import humanize' - # warnings.warn( - # "`Unit` has been deprecated. " - # "The enum is still available as the private member `_Unit`.", - # DeprecationWarning, - # ) - return EnumMeta.__getattribute__(_Unit, name) - - def __getitem__(cls, name): - warnings.warn( - "`Unit` has been deprecated. " - "The enum is still available as the private member `_Unit`.", - DeprecationWarning, - ) - return _Unit.__getitem__(name) - - def __call__( - cls, value, names=None, *, module=None, qualname=None, type=None, start=1 - ): - warnings.warn( - "`Unit` has been deprecated. " - "The enum is still available as the private member `_Unit`.", - DeprecationWarning, - ) - return _Unit.__call__( - value, names, module=module, qualname=qualname, type=type, start=start - ) - - -class Unit(Enum, metaclass=_UnitMeta): - # Temporary alias for _Unit to allow backwards-compatible usage. - pass - - def _now(): return dt.datetime.now() @@ -200,8 +162,8 @@ def naturaldelta( DeprecationWarning, stacklevel=2, ) - tmp = _Unit[minimum_unit.upper()] - if tmp not in (_Unit.SECONDS, _Unit.MILLISECONDS, _Unit.MICROSECONDS): + tmp = Unit[minimum_unit.upper()] + if tmp not in (Unit.SECONDS, Unit.MILLISECONDS, Unit.MICROSECONDS): raise ValueError(f"Minimum unit '{minimum_unit}' not supported") minimum_unit = tmp @@ -219,13 +181,13 @@ def naturaldelta( if not years and days < 1: if seconds == 0: - if minimum_unit == _Unit.MICROSECONDS and delta.microseconds < 1000: + if minimum_unit == Unit.MICROSECONDS and delta.microseconds < 1000: return ( _ngettext("%d microsecond", "%d microseconds", delta.microseconds) % delta.microseconds ) - elif minimum_unit == _Unit.MILLISECONDS or ( - minimum_unit == _Unit.MICROSECONDS + elif minimum_unit == Unit.MILLISECONDS or ( + minimum_unit == Unit.MICROSECONDS and 1000 <= delta.microseconds < 1_000_000 ): milliseconds = delta.microseconds / 1000 @@ -370,20 +332,20 @@ def _quotient_and_remainder(value, divisor, unit, minimum_unit, suppress): represent the remainder because it would require a unit smaller than the `minimum_unit`. - >>> from humanize.time import _quotient_and_remainder, _Unit - >>> _quotient_and_remainder(36, 24, _Unit.DAYS, _Unit.DAYS, []) + >>> from humanize.time import _quotient_and_remainder, Unit + >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.DAYS, []) (1.5, 0) If unit is in `suppress`, the quotient will be zero and the remainder will be the initial value. The idea is that if we cannot use `unit`, we are forced to use a lower unit so we cannot do the division. - >>> _quotient_and_remainder(36, 24, _Unit.DAYS, _Unit.HOURS, [_Unit.DAYS]) + >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, [Unit.DAYS]) (0, 36) In other case return quotient and remainder as `divmod` would do it. - >>> _quotient_and_remainder(36, 24, _Unit.DAYS, _Unit.HOURS, []) + >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, []) (1, 12) """ @@ -402,20 +364,20 @@ def _carry(value1, value2, ratio, unit, min_unit, suppress): (carry to right). The idea is that if we cannot represent `value1` we need to represent it in a lower unit. - >>> from humanize.time import _carry, _Unit - >>> _carry(2, 6, 24, _Unit.DAYS, _Unit.SECONDS, [_Unit.DAYS]) + >>> from humanize.time import _carry, Unit + >>> _carry(2, 6, 24, Unit.DAYS, Unit.SECONDS, [Unit.DAYS]) (0, 54) If the unit is the minimum unit, `value2` is divided by `ratio` and added to `value1` (carry to left). We assume that `value2` has a lower unit so we need to carry it to `value1`. - >>> _carry(2, 6, 24, _Unit.DAYS, _Unit.DAYS, []) + >>> _carry(2, 6, 24, Unit.DAYS, Unit.DAYS, []) (2.25, 0) Otherwise, just return the same input: - >>> _carry(2, 6, 24, _Unit.DAYS, _Unit.SECONDS, []) + >>> _carry(2, 6, 24, Unit.DAYS, Unit.SECONDS, []) (2, 6) """ if unit == min_unit: @@ -431,21 +393,21 @@ def _suitable_minimum_unit(min_unit, suppress): If not suppressed, return the same unit: - >>> from humanize.time import _suitable_minimum_unit, _Unit - >>> _suitable_minimum_unit(_Unit.HOURS, []).name + >>> from humanize.time import _suitable_minimum_unit, Unit + >>> _suitable_minimum_unit(Unit.HOURS, []).name 'HOURS' But if suppressed, find a unit greather than the original one that is not suppressed: - >>> _suitable_minimum_unit(_Unit.HOURS, [_Unit.HOURS]).name + >>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS]).name 'DAYS' - >>> _suitable_minimum_unit(_Unit.HOURS, [_Unit.HOURS, _Unit.DAYS]).name + >>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS, Unit.DAYS]).name 'MONTHS' """ if min_unit in suppress: - for unit in _Unit: + for unit in Unit: if unit > min_unit and unit not in suppress: return unit @@ -459,12 +421,12 @@ def _suitable_minimum_unit(min_unit, suppress): def _suppress_lower_units(min_unit, suppress): """Extend suppressed units (if any) with all units lower than the minimum unit. - >>> from humanize.time import _suppress_lower_units, _Unit - >>> [x.name for x in sorted(_suppress_lower_units(_Unit.SECONDS, [_Unit.DAYS]))] + >>> from humanize.time import _suppress_lower_units, Unit + >>> [x.name for x in sorted(_suppress_lower_units(Unit.SECONDS, [Unit.DAYS]))] ['MICROSECONDS', 'MILLISECONDS', 'DAYS'] """ suppress = set(suppress) - for u in _Unit: + for u in Unit: if u == min_unit: break suppress.add(u) @@ -543,11 +505,11 @@ def precisedelta(value, minimum_unit="seconds", suppress=(), format="%0.2f") -> if date is None: return value - suppress = [_Unit[s.upper()] for s in suppress] + suppress = [Unit[s.upper()] for s in suppress] # Find a suitable minimum unit (it can be greater the one that the # user gave us if it is suppressed). - min_unit = _Unit[minimum_unit.upper()] + min_unit = Unit[minimum_unit.upper()] min_unit = _suitable_minimum_unit(min_unit, suppress) del minimum_unit @@ -561,7 +523,7 @@ def precisedelta(value, minimum_unit="seconds", suppress=(), format="%0.2f") -> usecs = delta.microseconds MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS, MONTHS, YEARS = list( - _Unit + Unit ) # Given DAYS compute YEARS and the remainder of DAYS as follows: @@ -610,7 +572,7 @@ def precisedelta(value, minimum_unit="seconds", suppress=(), format="%0.2f") -> ] texts = [] - for unit, fmt in zip(reversed(_Unit), fmts): + for unit, fmt in zip(reversed(Unit), fmts): singular_txt, plural_txt, value = fmt if value > 0 or (not texts and unit == min_unit): fmt_txt = _ngettext(singular_txt, plural_txt, value) diff --git a/tests/test_time.py b/tests/test_time.py index 24004c8..db03357 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -645,7 +645,7 @@ def test_precisedelta_bogus_call(): def test_time_unit(): - years, minutes = time._Unit["YEARS"], time._Unit["MINUTES"] + years, minutes = time.Unit["YEARS"], time.Unit["MINUTES"] assert minutes < years assert years > minutes assert minutes == minutes