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