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