py23.py 2.2 KB

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