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