zhmiscellany 6.3.6__py3-none-any.whl → 6.3.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zhmiscellany/fileio.py +69 -68
- {zhmiscellany-6.3.6.dist-info → zhmiscellany-6.3.7.dist-info}/METADATA +1 -1
- {zhmiscellany-6.3.6.dist-info → zhmiscellany-6.3.7.dist-info}/RECORD +5 -5
- {zhmiscellany-6.3.6.dist-info → zhmiscellany-6.3.7.dist-info}/WHEEL +0 -0
- {zhmiscellany-6.3.6.dist-info → zhmiscellany-6.3.7.dist-info}/top_level.txt +0 -0
zhmiscellany/fileio.py
CHANGED
|
@@ -231,77 +231,78 @@ def cache(function, *args, _cache_compressed=False, **kwargs):
|
|
|
231
231
|
|
|
232
232
|
cache_folder = 'zhmiscellany_cache'
|
|
233
233
|
|
|
234
|
-
def
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
234
|
+
def normalize_for_json(obj):
|
|
235
|
+
"""Recursively normalize objects to be JSON-serializable."""
|
|
236
|
+
if callable(obj):
|
|
237
|
+
try:
|
|
238
|
+
return ('__callable__', inspect.getsource(obj))
|
|
239
|
+
except (OSError, TypeError):
|
|
240
|
+
return ('__callable__', str(obj))
|
|
241
|
+
|
|
242
|
+
# Handle dict-like objects (including bidict, defaultdict, etc.)
|
|
243
|
+
if isinstance(obj, dict):
|
|
244
|
+
# Convert non-string keys to strings
|
|
245
|
+
return {str(k): normalize_for_json(v) for k, v in obj.items()}
|
|
246
|
+
|
|
247
|
+
# Handle lists and tuples
|
|
248
|
+
if isinstance(obj, (list, tuple)):
|
|
249
|
+
return type(obj)(normalize_for_json(item) for item in obj)
|
|
250
|
+
|
|
251
|
+
# Handle sets
|
|
252
|
+
if isinstance(obj, set):
|
|
253
|
+
return sorted([normalize_for_json(item) for item in obj])
|
|
254
|
+
|
|
255
|
+
# Handle pandas DataFrames
|
|
256
|
+
if hasattr(obj, '__class__') and obj.__class__.__name__ == 'DataFrame':
|
|
257
|
+
try:
|
|
258
|
+
import pandas as pd
|
|
259
|
+
if isinstance(obj, pd.DataFrame):
|
|
260
|
+
return {
|
|
261
|
+
'__type__': 'DataFrame',
|
|
262
|
+
'data': obj.to_dict(orient='split'),
|
|
263
|
+
'dtypes': {col: str(dtype) for col, dtype in obj.dtypes.items()},
|
|
264
|
+
'index_name': obj.index.name,
|
|
265
|
+
'columns': list(obj.columns)
|
|
266
|
+
}
|
|
267
|
+
except ImportError:
|
|
268
|
+
pass
|
|
269
|
+
|
|
270
|
+
# Handle pandas Series
|
|
271
|
+
if hasattr(obj, '__class__') and obj.__class__.__name__ == 'Series':
|
|
272
|
+
try:
|
|
273
|
+
import pandas as pd
|
|
274
|
+
if isinstance(obj, pd.Series):
|
|
275
|
+
return {
|
|
276
|
+
'__type__': 'Series',
|
|
277
|
+
'data': obj.to_dict(),
|
|
278
|
+
'dtype': str(obj.dtype),
|
|
279
|
+
'name': obj.name,
|
|
280
|
+
'index': list(obj.index)
|
|
281
|
+
}
|
|
282
|
+
except ImportError:
|
|
283
|
+
pass
|
|
284
|
+
|
|
285
|
+
# Handle bytes
|
|
286
|
+
if isinstance(obj, bytes):
|
|
287
|
+
return ('__bytes__', obj.hex())
|
|
288
|
+
|
|
289
|
+
# Handle datetime
|
|
290
|
+
if isinstance(obj, datetime):
|
|
291
|
+
return ('__datetime__', obj.isoformat())
|
|
292
|
+
|
|
293
|
+
# Handle custom objects with __dict__
|
|
294
|
+
if hasattr(obj, '__dict__') and not isinstance(obj, type):
|
|
295
|
+
return {f'__{obj.__class__.__name__}__': normalize_for_json(obj.__dict__)}
|
|
296
|
+
|
|
297
|
+
# Return primitives as-is
|
|
298
|
+
return obj
|
|
267
299
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
import pandas as pd
|
|
272
|
-
if isinstance(obj, pd.Series):
|
|
273
|
-
return {
|
|
274
|
-
'data': obj.to_dict(),
|
|
275
|
-
'dtype': str(obj.dtype),
|
|
276
|
-
'name': obj.name,
|
|
277
|
-
'index': list(obj.index)
|
|
278
|
-
}
|
|
279
|
-
except ImportError:
|
|
280
|
-
pass
|
|
281
|
-
|
|
282
|
-
# SETS: Must be sorted to ensure determinism!
|
|
283
|
-
# JSON doesn't support sets, so we turn them into sorted lists.
|
|
284
|
-
if isinstance(obj, set):
|
|
285
|
-
return sorted(list(obj))
|
|
286
|
-
|
|
287
|
-
# BYTES: Decode to string (if utf-8) or hex
|
|
288
|
-
if isinstance(obj, bytes):
|
|
289
|
-
return obj.hex()
|
|
290
|
-
|
|
291
|
-
# DATETIMES: Convert to ISO format string
|
|
292
|
-
if isinstance(obj, datetime):
|
|
293
|
-
return obj.isoformat()
|
|
294
|
-
|
|
295
|
-
# CUSTOM OBJECTS: Try to return their __dict__ or string rep
|
|
296
|
-
if hasattr(obj, '__dict__'):
|
|
297
|
-
return obj.__dict__
|
|
298
|
-
|
|
299
|
-
# Fallback: String representation (risky if str() format changes)
|
|
300
|
-
return str(obj)
|
|
300
|
+
def get_hash_orjson(data):
|
|
301
|
+
# Pre-process the data to handle non-string keys and other issues
|
|
302
|
+
normalized_data = normalize_for_json(data)
|
|
301
303
|
|
|
302
304
|
json_bytes = orjson.dumps(
|
|
303
|
-
|
|
304
|
-
default=default_converter,
|
|
305
|
+
normalized_data,
|
|
305
306
|
option=orjson.OPT_SORT_KEYS
|
|
306
307
|
)
|
|
307
308
|
return hashlib.md5(json_bytes).hexdigest()
|
|
@@ -8,7 +8,7 @@ zhmiscellany/_resource_files_lookup.py,sha256=hsgPW0dngokgqWrAVAv5rUo-eobzJPjvWH
|
|
|
8
8
|
zhmiscellany/cpp.py,sha256=XEUEoIKCDCdY5VgwNWE5oXrGjtsmGdz_MnaVwQmi2dk,179
|
|
9
9
|
zhmiscellany/dict.py,sha256=dNu3G9qiJeLgE7JY3QD31GJU7EfLsYPqxf8AOhBsYag,81
|
|
10
10
|
zhmiscellany/discord.py,sha256=yKoigWI3tONfYSoMEynGGEWW1VsXSRdkg8vPbIKwBNI,20312
|
|
11
|
-
zhmiscellany/fileio.py,sha256=
|
|
11
|
+
zhmiscellany/fileio.py,sha256=Muiktj_fzCBNBzVMktJzKBkT1_Ssx3EbKkaBGkm6NPA,22372
|
|
12
12
|
zhmiscellany/gui.py,sha256=OVwuZ_kWHJlgKPeYR7fAAyomNmU-OnxOgXZelVNPm1w,10409
|
|
13
13
|
zhmiscellany/image.py,sha256=6Hz5sfym_o7FHokGUKeXRsjl89VY_ZMSLnvuSam1icI,8265
|
|
14
14
|
zhmiscellany/list.py,sha256=BnbYG-lpHmi0C4v8jLfaeXqQdc3opmNgkvY6yz4pasg,1475
|
|
@@ -21,7 +21,7 @@ zhmiscellany/pipes.py,sha256=RlHxsW_M_R6UJUIDgYVS_zfqUwO8kXG8j-0YG5qByjo,4637
|
|
|
21
21
|
zhmiscellany/processing.py,sha256=ZhNAJ5OfCUHuaXj0z6XZ94ZGSK86-EdCyqW-9ILayLg,11524
|
|
22
22
|
zhmiscellany/rust.py,sha256=cHkSpdtq7QQW3yzBEAYL9lZxLW0h4wal2tsxIOnyTrA,494
|
|
23
23
|
zhmiscellany/string.py,sha256=A4ilBWSYlrJ0AJ0axvepSSjYCYwYk5X-vRrHNphi_ow,4809
|
|
24
|
-
zhmiscellany-6.3.
|
|
25
|
-
zhmiscellany-6.3.
|
|
26
|
-
zhmiscellany-6.3.
|
|
27
|
-
zhmiscellany-6.3.
|
|
24
|
+
zhmiscellany-6.3.7.dist-info/METADATA,sha256=wtzaVO-OHJfk0qnhUfzRKlZj9ZihD0BEL4zoP0ILFGY,43872
|
|
25
|
+
zhmiscellany-6.3.7.dist-info/WHEEL,sha256=hPN0AlP2dZM_3ZJZWP4WooepkmU9wzjGgCLCeFjkHLA,92
|
|
26
|
+
zhmiscellany-6.3.7.dist-info/top_level.txt,sha256=ioDtsrevCI52rTxZntMPljRIBsZs73tD0hI00HektiE,13
|
|
27
|
+
zhmiscellany-6.3.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|