Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

29249e92-a69d-4fbe-9b45-6d7ba4ca1654 2.7 KB
Raw

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  1. import os
  2. import pathlib
  3. import tempfile
  4. import functools
  5. import contextlib
  6. import types
  7. import importlib
  8. from typing import Union, Optional
  9. from .abc import ResourceReader, Traversable
  10. from ._compat import wrap_spec
  11. Package = Union[types.ModuleType, str]
  12. def files(package):
  13. # type: (Package) -> Traversable
  14. """
  15. Get a Traversable resource from a package
  16. """
  17. return from_package(get_package(package))
  18. def get_resource_reader(package):
  19. # type: (types.ModuleType) -> Optional[ResourceReader]
  20. """
  21. Return the package's loader if it's a ResourceReader.
  22. """
  23. # We can't use
  24. # a issubclass() check here because apparently abc.'s __subclasscheck__()
  25. # hook wants to create a weak reference to the object, but
  26. # zipimport.zipimporter does not support weak references, resulting in a
  27. # TypeError. That seems terrible.
  28. spec = package.__spec__
  29. reader = getattr(spec.loader, 'get_resource_reader', None) # type: ignore
  30. if reader is None:
  31. return None
  32. return reader(spec.name) # type: ignore
  33. def resolve(cand):
  34. # type: (Package) -> types.ModuleType
  35. return cand if isinstance(cand, types.ModuleType) else importlib.import_module(cand)
  36. def get_package(package):
  37. # type: (Package) -> types.ModuleType
  38. """Take a package name or module object and return the module.
  39. Raise an exception if the resolved module is not a package.
  40. """
  41. resolved = resolve(package)
  42. if wrap_spec(resolved).submodule_search_locations is None:
  43. raise TypeError(f'{package!r} is not a package')
  44. return resolved
  45. def from_package(package):
  46. """
  47. Return a Traversable object for the given package.
  48. """
  49. spec = wrap_spec(package)
  50. reader = spec.loader.get_resource_reader(spec.name)
  51. return reader.files()
  52. @contextlib.contextmanager
  53. def _tempfile(reader, suffix=''):
  54. # Not using tempfile.NamedTemporaryFile as it leads to deeper 'try'
  55. # blocks due to the need to close the temporary file to work on Windows
  56. # properly.
  57. fd, raw_path = tempfile.mkstemp(suffix=suffix)
  58. try:
  59. try:
  60. os.write(fd, reader())
  61. finally:
  62. os.close(fd)
  63. del reader
  64. yield pathlib.Path(raw_path)
  65. finally:
  66. try:
  67. os.remove(raw_path)
  68. except FileNotFoundError:
  69. pass
  70. @functools.singledispatch
  71. def as_file(path):
  72. """
  73. Given a Traversable object, return that object as a
  74. path on the local file system in a context manager.
  75. """
  76. return _tempfile(path.read_bytes, suffix=path.name)
  77. @as_file.register(pathlib.Path)
  78. @contextlib.contextmanager
  79. def _(path):
  80. """
  81. Degenerate behavior for pathlib.Path objects.
  82. """
  83. yield path
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...