MCPcopy Create free account
hub / github.com/psf/cachecontrol / CallbackFileWrapper

Class CallbackFileWrapper

cachecontrol/filewrapper.py:15–121  ·  view source on GitHub ↗

Small wrapper around a fp object which will tee everything read into a buffer, and when that file is closed it will execute a callback with the contents of that buffer. All attributes are proxied to the underlying file object. This class uses members with a double underscore (

Source from the content-addressed store, hash-verified

13
14
15class CallbackFileWrapper:
16 """
17 Small wrapper around a fp object which will tee everything read into a
18 buffer, and when that file is closed it will execute a callback with the
19 contents of that buffer.
20
21 All attributes are proxied to the underlying file object.
22
23 This class uses members with a double underscore (__) leading prefix so as
24 not to accidentally shadow an attribute.
25
26 The data is stored in a temporary file until it is all available. As long
27 as the temporary files directory is disk-based (sometimes it's a
28 memory-backed-``tmpfs`` on Linux), data will be unloaded to disk if memory
29 pressure is high. For small files the disk usually won't be used at all,
30 it'll all be in the filesystem memory cache, so there should be no
31 performance impact.
32 """
33
34 def __init__(
35 self, fp: HTTPResponse, callback: Callable[[Buffer], None] | None
36 ) -> None:
37 self.__buf = NamedTemporaryFile("rb+", delete=True)
38 self.__fp = fp
39 self.__callback = callback
40
41 def __getattr__(self, name: str) -> Any:
42 # The vagaries of garbage collection means that self.__fp is
43 # not always set. By using __getattribute__ and the private
44 # name[0] allows looking up the attribute value and raising an
45 # AttributeError when it doesn't exist. This stop things from
46 # infinitely recursing calls to getattr in the case where
47 # self.__fp hasn't been set.
48 #
49 # [0] https://docs.python.org/2/reference/expressions.html#atom-identifiers
50 fp = self.__getattribute__("_CallbackFileWrapper__fp")
51 return getattr(fp, name)
52
53 def __is_fp_closed(self) -> bool:
54 try:
55 return self.__fp.fp is None
56
57 except AttributeError:
58 pass
59
60 try:
61 closed: bool = self.__fp.closed
62 return closed
63
64 except AttributeError:
65 pass
66
67 # We just don't cache it then.
68 # TODO: Add some logging here...
69 return False
70
71 def _close(self) -> None:
72 result: Buffer

Callers 2

test_getattr_during_gcFunction · 0.90
build_responseMethod · 0.90

Calls

no outgoing calls

Tested by 1

test_getattr_during_gcFunction · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…