You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

81 lines
2.5 KiB

  1. from __future__ import annotations
  2. import json
  3. import pickle
  4. import warnings
  5. from enum import Enum
  6. from pathlib import Path
  7. from typing import TYPE_CHECKING, Any, Callable
  8. from typing_extensions import deprecated
  9. from ..warnings import PydanticDeprecatedSince20
  10. if not TYPE_CHECKING:
  11. # See PyCharm issues https://youtrack.jetbrains.com/issue/PY-21915
  12. # and https://youtrack.jetbrains.com/issue/PY-51428
  13. DeprecationWarning = PydanticDeprecatedSince20
  14. class Protocol(str, Enum):
  15. json = 'json'
  16. pickle = 'pickle'
  17. @deprecated('`load_str_bytes` is deprecated.', category=None)
  18. def load_str_bytes(
  19. b: str | bytes,
  20. *,
  21. content_type: str | None = None,
  22. encoding: str = 'utf8',
  23. proto: Protocol | None = None,
  24. allow_pickle: bool = False,
  25. json_loads: Callable[[str], Any] = json.loads,
  26. ) -> Any:
  27. warnings.warn('`load_str_bytes` is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2)
  28. if proto is None and content_type:
  29. if content_type.endswith(('json', 'javascript')):
  30. pass
  31. elif allow_pickle and content_type.endswith('pickle'):
  32. proto = Protocol.pickle
  33. else:
  34. raise TypeError(f'Unknown content-type: {content_type}')
  35. proto = proto or Protocol.json
  36. if proto == Protocol.json:
  37. if isinstance(b, bytes):
  38. b = b.decode(encoding)
  39. return json_loads(b) # type: ignore
  40. elif proto == Protocol.pickle:
  41. if not allow_pickle:
  42. raise RuntimeError('Trying to decode with pickle with allow_pickle=False')
  43. bb = b if isinstance(b, bytes) else b.encode() # type: ignore
  44. return pickle.loads(bb)
  45. else:
  46. raise TypeError(f'Unknown protocol: {proto}')
  47. @deprecated('`load_file` is deprecated.', category=None)
  48. def load_file(
  49. path: str | Path,
  50. *,
  51. content_type: str | None = None,
  52. encoding: str = 'utf8',
  53. proto: Protocol | None = None,
  54. allow_pickle: bool = False,
  55. json_loads: Callable[[str], Any] = json.loads,
  56. ) -> Any:
  57. warnings.warn('`load_file` is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2)
  58. path = Path(path)
  59. b = path.read_bytes()
  60. if content_type is None:
  61. if path.suffix in ('.js', '.json'):
  62. proto = Protocol.json
  63. elif path.suffix == '.pkl':
  64. proto = Protocol.pickle
  65. return load_str_bytes(
  66. b, proto=proto, content_type=content_type, encoding=encoding, allow_pickle=allow_pickle, json_loads=json_loads
  67. )