compat.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. """
  2. Utility functions and objects to ease Python 2/3 compatibility,
  3. and different versions of support libraries.
  4. """
  5. from __future__ import annotations
  6. import codecs
  7. import re
  8. import warnings
  9. from typing import Match
  10. def cast_bytes(s, enc="utf-8"):
  11. if isinstance(s, str):
  12. return s.encode(enc)
  13. return s
  14. def ascii(stream):
  15. return codecs.getreader("ascii")(stream)
  16. def bopen(*args, **kwargs):
  17. # type error: No overload variant of "open" matches argument types "Tuple[Any, ...]", "str", "Dict[str, Any]"
  18. return open(*args, mode="rb", **kwargs) # type: ignore[call-overload]
  19. long_type = int
  20. def sign(n):
  21. if n < 0:
  22. return -1
  23. if n > 0:
  24. return 1
  25. return 0
  26. r_unicodeEscape = re.compile(r"(\\u[0-9A-Fa-f]{4}|\\U[0-9A-Fa-f]{8})") # noqa: N816
  27. def _unicodeExpand(s): # noqa: N802
  28. return r_unicodeEscape.sub(lambda m: chr(int(m.group(0)[2:], 16)), s)
  29. def decodeStringEscape(s): # noqa: N802
  30. warnings.warn(
  31. DeprecationWarning(
  32. "rdflib.compat.decodeStringEscape() is deprecated, "
  33. "it will be removed in rdflib 7.0.0. "
  34. "This function is not used anywhere in rdflib anymore "
  35. "and the utility that it does provide is not implemented correctly."
  36. )
  37. )
  38. r"""
  39. s is byte-string - replace \ escapes in string
  40. """
  41. s = s.replace("\\t", "\t")
  42. s = s.replace("\\n", "\n")
  43. s = s.replace("\\r", "\r")
  44. s = s.replace("\\b", "\b")
  45. s = s.replace("\\f", "\f")
  46. s = s.replace('\\"', '"')
  47. s = s.replace("\\'", "'")
  48. s = s.replace("\\\\", "\\")
  49. return s
  50. # return _unicodeExpand(s) # hmm - string escape doesn't do unicode escaping
  51. _string_escape_map = {
  52. "t": "\t",
  53. "b": "\b",
  54. "n": "\n",
  55. "r": "\r",
  56. "f": "\f",
  57. '"': '"',
  58. "'": "'",
  59. "\\": "\\",
  60. }
  61. def _turtle_escape_subber(match: Match[str]) -> str:
  62. smatch, umatch = match.groups()
  63. if smatch is not None:
  64. return _string_escape_map[smatch]
  65. else:
  66. return chr(int(umatch[1:], 16))
  67. _turtle_escape_pattern = re.compile(
  68. r"""\\(?:([tbnrf"'\\])|(u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8}))""",
  69. )
  70. def decodeUnicodeEscape(escaped: str) -> str: # noqa: N802
  71. if "\\" not in escaped:
  72. # Most of times, there are no backslashes in strings.
  73. return escaped
  74. return _turtle_escape_pattern.sub(_turtle_escape_subber, escaped)