5
5
import time
6
6
from collections import defaultdict
7
7
from contextlib import contextmanager
8
- from typing import TYPE_CHECKING , Self
8
+ from typing import TYPE_CHECKING , Any , Self
9
9
10
10
from zarr .abc .store import AccessMode , ByteRangeRequest , Store
11
11
from zarr .core .buffer import Buffer
@@ -75,22 +75,24 @@ def _default_handler(self) -> logging.Handler:
75
75
return handler
76
76
77
77
@contextmanager
78
- def log (self ) -> Generator [None , None , None ]:
78
+ def log (self , hint : Any = "" ) -> Generator [None , None , None ]:
79
79
"""Context manager to log method calls
80
80
81
81
Each call to the wrapped store is logged to the configured logger and added to
82
82
the counter dict.
83
83
"""
84
84
method = inspect .stack ()[2 ].function
85
85
op = f"{ type (self ._store ).__name__ } .{ method } "
86
+ if hint :
87
+ op += f"({ hint } )"
86
88
self .logger .info (f"Calling { op } " )
87
89
start_time = time .time ()
88
90
try :
89
91
self .counter [method ] += 1
90
92
yield
91
93
finally :
92
94
end_time = time .time ()
93
- self .logger .info (f"Finished { op } in { end_time - start_time :.2f} seconds " )
95
+ self .logger .info (f"Finished { op } [ { end_time - start_time :.2f} s] " )
94
96
95
97
@property
96
98
def supports_writes (self ) -> bool :
@@ -118,10 +120,15 @@ def _mode(self) -> AccessMode: # type: ignore[override]
118
120
return self ._store ._mode
119
121
120
122
@property
121
- def _is_open (self ) -> bool : # type: ignore[override]
123
+ def _is_open (self ) -> bool :
122
124
with self .log ():
123
125
return self ._store ._is_open
124
126
127
+ @_is_open .setter
128
+ def _is_open (self , value : bool ) -> None :
129
+ with self .log (value ):
130
+ self ._store ._is_open = value
131
+
125
132
async def _open (self ) -> None :
126
133
with self .log ():
127
134
return await self ._store ._open ()
@@ -147,7 +154,7 @@ def __repr__(self) -> str:
147
154
return f"LoggingStore({ repr (self ._store )!r} )"
148
155
149
156
def __eq__ (self , other : object ) -> bool :
150
- with self .log ():
157
+ with self .log (other ):
151
158
return self ._store == other
152
159
153
160
async def get (
@@ -157,7 +164,7 @@ async def get(
157
164
byte_range : tuple [int | None , int | None ] | None = None ,
158
165
) -> Buffer | None :
159
166
# docstring inherited
160
- with self .log ():
167
+ with self .log (key ):
161
168
return await self ._store .get (key = key , prototype = prototype , byte_range = byte_range )
162
169
163
170
async def get_partial_values (
@@ -166,34 +173,36 @@ async def get_partial_values(
166
173
key_ranges : Iterable [tuple [str , ByteRangeRequest ]],
167
174
) -> list [Buffer | None ]:
168
175
# docstring inherited
169
- with self .log ():
176
+ keys = "," .join ([k [0 ] for k in key_ranges ])
177
+ with self .log (keys ):
170
178
return await self ._store .get_partial_values (prototype = prototype , key_ranges = key_ranges )
171
179
172
180
async def exists (self , key : str ) -> bool :
173
181
# docstring inherited
174
- with self .log ():
182
+ with self .log (key ):
175
183
return await self ._store .exists (key )
176
184
177
185
async def set (self , key : str , value : Buffer ) -> None :
178
186
# docstring inherited
179
- with self .log ():
187
+ with self .log (key ):
180
188
return await self ._store .set (key = key , value = value )
181
189
182
190
async def set_if_not_exists (self , key : str , value : Buffer ) -> None :
183
191
# docstring inherited
184
- with self .log ():
192
+ with self .log (key ):
185
193
return await self ._store .set_if_not_exists (key = key , value = value )
186
194
187
195
async def delete (self , key : str ) -> None :
188
196
# docstring inherited
189
- with self .log ():
197
+ with self .log (key ):
190
198
return await self ._store .delete (key = key )
191
199
192
200
async def set_partial_values (
193
201
self , key_start_values : Iterable [tuple [str , int , bytes | bytearray | memoryview ]]
194
202
) -> None :
195
203
# docstring inherited
196
- with self .log ():
204
+ keys = "," .join ([k [0 ] for k in key_start_values ])
205
+ with self .log (keys ):
197
206
return await self ._store .set_partial_values (key_start_values = key_start_values )
198
207
199
208
async def list (self ) -> AsyncGenerator [str , None ]:
@@ -204,19 +213,19 @@ async def list(self) -> AsyncGenerator[str, None]:
204
213
205
214
async def list_prefix (self , prefix : str ) -> AsyncGenerator [str , None ]:
206
215
# docstring inherited
207
- with self .log ():
216
+ with self .log (prefix ):
208
217
async for key in self ._store .list_prefix (prefix = prefix ):
209
218
yield key
210
219
211
220
async def list_dir (self , prefix : str ) -> AsyncGenerator [str , None ]:
212
221
# docstring inherited
213
- with self .log ():
222
+ with self .log (prefix ):
214
223
async for key in self ._store .list_dir (prefix = prefix ):
215
224
yield key
216
225
217
226
def with_mode (self , mode : AccessModeLiteral ) -> Self :
218
227
# docstring inherited
219
- with self .log ():
228
+ with self .log (mode ):
220
229
return type (self )(
221
230
self ._store .with_mode (mode ),
222
231
log_level = self .log_level ,
0 commit comments