• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""Python 2/3 compat layer leftovers."""
2
3import decimal as _decimal
4import math as _math
5import warnings
6from contextlib import redirect_stderr, redirect_stdout
7from io import BytesIO
8from io import StringIO as UnicodeIO
9from types import SimpleNamespace
10
11from .textTools import Tag, bytechr, byteord, bytesjoin, strjoin, tobytes, tostr
12
13warnings.warn(
14    "The py23 module has been deprecated and will be removed in a future release. "
15    "Please update your code.",
16    DeprecationWarning,
17)
18
19__all__ = [
20    "basestring",
21    "bytechr",
22    "byteord",
23    "BytesIO",
24    "bytesjoin",
25    "open",
26    "Py23Error",
27    "range",
28    "RecursionError",
29    "round",
30    "SimpleNamespace",
31    "StringIO",
32    "strjoin",
33    "Tag",
34    "tobytes",
35    "tostr",
36    "tounicode",
37    "unichr",
38    "unicode",
39    "UnicodeIO",
40    "xrange",
41    "zip",
42]
43
44
45class Py23Error(NotImplementedError):
46    pass
47
48
49RecursionError = RecursionError
50StringIO = UnicodeIO
51
52basestring = str
53isclose = _math.isclose
54isfinite = _math.isfinite
55open = open
56range = range
57round = round3 = round
58unichr = chr
59unicode = str
60zip = zip
61
62tounicode = tostr
63
64
65def xrange(*args, **kwargs):
66    raise Py23Error("'xrange' is not defined. Use 'range' instead.")
67
68
69def round2(number, ndigits=None):
70    """
71    Implementation of Python 2 built-in round() function.
72    Rounds a number to a given precision in decimal digits (default
73    0 digits). The result is a floating point number. Values are rounded
74    to the closest multiple of 10 to the power minus ndigits; if two
75    multiples are equally close, rounding is done away from 0.
76    ndigits may be negative.
77    See Python 2 documentation:
78    https://docs.python.org/2/library/functions.html?highlight=round#round
79    """
80    if ndigits is None:
81        ndigits = 0
82
83    if ndigits < 0:
84        exponent = 10 ** (-ndigits)
85        quotient, remainder = divmod(number, exponent)
86        if remainder >= exponent // 2 and number >= 0:
87            quotient += 1
88        return float(quotient * exponent)
89    else:
90        exponent = _decimal.Decimal("10") ** (-ndigits)
91
92        d = _decimal.Decimal.from_float(number).quantize(
93            exponent, rounding=_decimal.ROUND_HALF_UP
94        )
95
96        return float(d)
97