cdxcore 0.1.27__tar.gz → 0.1.28__tar.gz
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.
Potentially problematic release.
This version of cdxcore might be problematic. Click here for more details.
- {cdxcore-0.1.27 → cdxcore-0.1.28}/PKG-INFO +1 -1
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/__init__.py +1 -1
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/subdir.py +159 -47
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore.egg-info/PKG-INFO +1 -1
- {cdxcore-0.1.27 → cdxcore-0.1.28}/pyproject.toml +1 -1
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_subdir.py +62 -7
- {cdxcore-0.1.27 → cdxcore-0.1.28}/LICENSE +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/README.md +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/config.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/deferred.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/dynalimits.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/dynaplot.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/err.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/filelock.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/jcpool.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/npio.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/npshm.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/pretty.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/uniquehash.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/util.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/verbose.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore/version.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore.egg-info/SOURCES.txt +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore.egg-info/dependency_links.txt +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore.egg-info/requires.txt +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/cdxcore.egg-info/top_level.txt +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/docs/source/conf.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/setup.cfg +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_config.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_deferred.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_err.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_jcpool.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_npio.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_npshm.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_pretty.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_uniquehash.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_util.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_verbose.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tests/test_version.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tmp/filelock.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tmp/np.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tmp/npsh1.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/tmp/sharedarray.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/up/git_message.py +0 -0
- {cdxcore-0.1.27 → cdxcore-0.1.28}/up/pip_modify_setup.py +0 -0
|
@@ -2801,14 +2801,14 @@ class SubDir(object):
|
|
|
2801
2801
|
# caching
|
|
2802
2802
|
# -------
|
|
2803
2803
|
|
|
2804
|
-
def cache( self, version : str = None , *,
|
|
2805
|
-
dependencies : list = None,
|
|
2806
|
-
label : Callable = None,
|
|
2807
|
-
uid : Callable = None,
|
|
2808
|
-
name : str = None,
|
|
2809
|
-
exclude_args : list[str] = None,
|
|
2810
|
-
include_args : list[str] = None,
|
|
2811
|
-
exclude_arg_types : list[type] = None,
|
|
2804
|
+
def cache( self, version : str|None = None , *,
|
|
2805
|
+
dependencies : list|None = None,
|
|
2806
|
+
label : Callable|None = None,
|
|
2807
|
+
uid : Callable|None = None,
|
|
2808
|
+
name : str|None = None,
|
|
2809
|
+
exclude_args : list[str]|None = None,
|
|
2810
|
+
include_args : list[str]|None = None,
|
|
2811
|
+
exclude_arg_types : list[type]|None = None,
|
|
2812
2812
|
version_auto_class : bool = True):
|
|
2813
2813
|
"""
|
|
2814
2814
|
Advanced versioned caching for callables.
|
|
@@ -3178,9 +3178,13 @@ class SubDir(object):
|
|
|
3178
3178
|
:dec:`cdxcore.subdir.SubDir.cache`
|
|
3179
3179
|
to provide version information at class level. Only version information are provided here.
|
|
3180
3180
|
|
|
3181
|
+
You can use :dec:`cdxcore.subdir.SubDir.cache_class` as an alias.
|
|
3182
|
+
|
|
3181
3183
|
2) Secondly, decorate ``__init__``. You do not need to specify a version
|
|
3182
3184
|
for ``__init__`` as its version usually coincides with the version of the class. At ``__init__``
|
|
3183
3185
|
you define how unique IDs are generated from the parameters passed to object construction.
|
|
3186
|
+
|
|
3187
|
+
You can use :dec:`cdxcore.subdir.SubDir.cache_init` as an alias.
|
|
3184
3188
|
|
|
3185
3189
|
Simple example:
|
|
3186
3190
|
|
|
@@ -3190,10 +3194,10 @@ class SubDir(object):
|
|
|
3190
3194
|
cache = SubDir("!/.cache")
|
|
3191
3195
|
cache.delete_all_content() # for illustration
|
|
3192
3196
|
|
|
3193
|
-
@cache.
|
|
3197
|
+
@cache.cache_class("0.1")
|
|
3194
3198
|
class A(object):
|
|
3195
3199
|
|
|
3196
|
-
@cache.
|
|
3200
|
+
@cache.cache_init(exclude_args=['debug'])
|
|
3197
3201
|
def __init__(self, x, debug):
|
|
3198
3202
|
if debug:
|
|
3199
3203
|
print("__init__",x)
|
|
@@ -3216,10 +3220,10 @@ class SubDir(object):
|
|
|
3216
3220
|
|
|
3217
3221
|
.. code-block:: python
|
|
3218
3222
|
|
|
3219
|
-
@cache.
|
|
3223
|
+
@cache.cache_class("0.1")
|
|
3220
3224
|
class A(object):
|
|
3221
3225
|
|
|
3222
|
-
@cache.
|
|
3226
|
+
@cache.cache_init(id=lambda x, debug: f"A.__init__(x={x})") # <-- 'self' is not passed to the lambda function; no need to add **_
|
|
3223
3227
|
def __init__(self, x, debug):
|
|
3224
3228
|
if debug:
|
|
3225
3229
|
print("__init__",x)
|
|
@@ -3227,35 +3231,79 @@ class SubDir(object):
|
|
|
3227
3231
|
|
|
3228
3232
|
Decorating classes with ``__slots__`` does not yet work.
|
|
3229
3233
|
|
|
3230
|
-
|
|
3231
|
-
|
|
3234
|
+
Managing Caching Accross a Project
|
|
3235
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
3232
3236
|
|
|
3233
|
-
For project-wide use it is usually
|
|
3237
|
+
For project-wide use it is usually convenient to control caching at the level of a
|
|
3234
3238
|
project-wide cache root directory.
|
|
3235
|
-
|
|
3239
|
+
The classs :class:`cdxcore.subdir.VersionedCacheRoot` is a thin convenience wrapper around a :class:`cdxcore.subdir.SubDir`
|
|
3236
3240
|
with a :class:`cdxcore.subdir.CacheController`.
|
|
3237
3241
|
|
|
3242
|
+
The idea is to have a central file, ``cache.py`` which contains the central root for caching.
|
|
3243
|
+
We recommend using an environment variable to be able to control the location of this directory
|
|
3244
|
+
out side the code. Here is an example with an environment variable ``PROJECT_CACHE_DIR``::
|
|
3245
|
+
|
|
3246
|
+
# file cache.py
|
|
3247
|
+
|
|
3248
|
+
from cdxcore.subdir import VersionedCacheRoot
|
|
3249
|
+
import os as os
|
|
3250
|
+
|
|
3251
|
+
cache_root = VersionedCacheRoot(
|
|
3252
|
+
os.getenv("PROJECT_CACHE_DIR", "!/.cache")
|
|
3253
|
+
)
|
|
3254
|
+
|
|
3255
|
+
In a particular project file, say ``pipeline.py`` create a file-local cache directory
|
|
3256
|
+
and use it::
|
|
3257
|
+
|
|
3258
|
+
# file pipeline.py
|
|
3259
|
+
|
|
3260
|
+
from cache import cache_root
|
|
3261
|
+
|
|
3262
|
+
cache_dir = cache_root("pipeline")
|
|
3263
|
+
|
|
3264
|
+
@cache_dir.cache("0.1")
|
|
3265
|
+
def f(x):
|
|
3266
|
+
return x+2
|
|
3267
|
+
|
|
3268
|
+
@cache_dir.cache("0.1", dependencies=[f])
|
|
3269
|
+
def g(x)
|
|
3270
|
+
return f(x)**2
|
|
3271
|
+
|
|
3272
|
+
# ...
|
|
3273
|
+
|
|
3274
|
+
In case you have issues with caching you can use the central root directory to turn on tracing
|
|
3275
|
+
accross your project:
|
|
3276
|
+
|
|
3277
|
+
.. code-block:: python
|
|
3278
|
+
:emphasize-lines: 4
|
|
3279
|
+
|
|
3280
|
+
from cdxcore.verbose import Context
|
|
3281
|
+
cache_root = VersionedCacheRoot(
|
|
3282
|
+
os.getenv("PROJECT_CACHE_DIR", "!/.cache"),
|
|
3283
|
+
debug_verbose=Context.all # turn full traing on
|
|
3284
|
+
)
|
|
3285
|
+
|
|
3238
3286
|
Parameters
|
|
3239
3287
|
----------
|
|
3240
|
-
version : str,
|
|
3288
|
+
version : str | None, default ``None``
|
|
3241
3289
|
Version of the function.
|
|
3242
3290
|
|
|
3243
|
-
* If ``None`` then
|
|
3244
|
-
* If set, the function ``F`` is first decorated with :dec:`cdxcore.version.version
|
|
3291
|
+
* If ``None`` then a common `F`` must be decorated manually with :dec:`cdxcore.version.version`.
|
|
3292
|
+
* If set, the function ``F`` is automatically first decorated with :dec:`cdxcore.version.version` for you.
|
|
3245
3293
|
|
|
3246
|
-
dependencies : list[type],
|
|
3294
|
+
dependencies : list[type] | None, default ``None``
|
|
3247
3295
|
A list of version dependencies, either by reference or by name.
|
|
3248
3296
|
See :dec:`cdxcore.version.version` for details on name lookup if strings are used.
|
|
3249
3297
|
|
|
3250
|
-
label : str | Callable
|
|
3251
|
-
Specify a human-
|
|
3298
|
+
label : str | Callable | None, default ``None``
|
|
3299
|
+
Specify a human-readabl label for the function call given its parameters.
|
|
3252
3300
|
This label is used to generate the cache file name, and is also printed in when tracing
|
|
3253
3301
|
hashing operations. Labels are not assumed to be unique, hence a unique hash of
|
|
3254
3302
|
the label and the parameters to this function will be appended to generate
|
|
3255
3303
|
the actual cache file name.
|
|
3256
3304
|
|
|
3257
|
-
Use ``uid`` instead if ``label`` represents valid unique filenames.
|
|
3258
|
-
|
|
3305
|
+
Use ``uid`` instead if ``label`` represents valid unique filenames. You cannot specify both ``uid`` and ``label``.
|
|
3306
|
+
If neither ``uid`` and ``label`` are present, ``name`` will be used.
|
|
3259
3307
|
|
|
3260
3308
|
**Usage:**
|
|
3261
3309
|
|
|
@@ -3271,30 +3319,34 @@ class SubDir(object):
|
|
|
3271
3319
|
|
|
3272
3320
|
``label`` cannot be used alongside ``uid``.
|
|
3273
3321
|
|
|
3274
|
-
uid : str | Callable
|
|
3322
|
+
uid : str | Callable | None, default ``None``
|
|
3275
3323
|
Alternative to ``label`` which is assumed to generate a unique cache file name. It has the same
|
|
3276
|
-
semantics as ``label``. When used, parameters to the decorated function are not hashed
|
|
3324
|
+
semantics as ``label``. When used, parameters to the decorated function are not hashed
|
|
3325
|
+
as the ``uid`` is assumed to be already unique. The string must be a valid file name
|
|
3277
3326
|
|
|
3278
|
-
``
|
|
3327
|
+
Use ``label`` if the id is not unique. You cannot specify both ``uid`` and ``label``.
|
|
3328
|
+
If neither ``uid`` and ``label`` are present, ``name`` will be used (as non-unique ``label``).
|
|
3279
3329
|
|
|
3280
|
-
name : str,
|
|
3281
|
-
Name of this function which is used either on its own if neither ``label`` not ``uid`` are used
|
|
3282
|
-
|
|
3283
|
-
formatting operator.
|
|
3330
|
+
name : str | None, default ``None``
|
|
3331
|
+
Name of this function which is used either on its own if neither ``label`` not ``uid`` are used,
|
|
3332
|
+
or which passed as a parameter ``name`` to either the callable or the
|
|
3333
|
+
formatting operator. See above for more details.
|
|
3284
3334
|
|
|
3285
3335
|
If ``name`` is not specified it defaults to ``__qualname__`` expanded
|
|
3286
3336
|
by the module name the function is defined in.
|
|
3287
3337
|
|
|
3288
|
-
include_args : list[str]
|
|
3338
|
+
include_args : list[str] | None, default ``None``
|
|
3289
3339
|
List of arguments to include in generating an unqiue ID, or ``None`` for all.
|
|
3290
3340
|
|
|
3291
|
-
exclude_args : list[str]
|
|
3292
|
-
List of arguments to exclude from generating an unique ID.
|
|
3341
|
+
exclude_args : list[str] | None, default ``None``
|
|
3342
|
+
List of arguments to exclude from generating an unique ID. Examples of such non-functional arguments
|
|
3343
|
+
are workflow controls (debugging) and i/o elements.
|
|
3293
3344
|
|
|
3294
|
-
exclude_arg_types : list[type]
|
|
3295
|
-
List of parameter types to exclude from generating an unique ID.
|
|
3345
|
+
exclude_arg_types : list[type] | None, default ``None``
|
|
3346
|
+
List of parameter types to exclude from generating an unique ID. Examples of such non-functional arguments
|
|
3347
|
+
are workflow controls (debugging) and i/o elements.
|
|
3296
3348
|
|
|
3297
|
-
version_auto_class : bool
|
|
3349
|
+
version_auto_class : bool, default ``True``
|
|
3298
3350
|
Whether to automaticallty add version dependencies on base classes or, for member functions, on containing
|
|
3299
3351
|
classes. This is the ``auto_class`` parameter for :dec:`cdxcore.version.version`.
|
|
3300
3352
|
|
|
@@ -3326,12 +3378,39 @@ class SubDir(object):
|
|
|
3326
3378
|
|
|
3327
3379
|
The decorated ``F()`` has additional function parameters, namely:
|
|
3328
3380
|
|
|
3329
|
-
* ``override_cache_mode`` :
|
|
3330
|
-
|
|
3381
|
+
* ``override_cache_mode`` : ``CacheMode`` | None, default ``None``
|
|
3382
|
+
|
|
3383
|
+
Allows overriding the ``CacheMode`` temporarily, in particular you can set it to ``"off"``.
|
|
3384
|
+
|
|
3385
|
+
* ``track_cached_files`` : :class:`cdxcore.subdir.CacheTracker` | None, default ``None``
|
|
3386
|
+
|
|
3387
|
+
Allows passing a :class:`cdxcore.subdir.CacheTracker`
|
|
3331
3388
|
object to keep track of all
|
|
3332
3389
|
files used (loaded from or saved to).
|
|
3333
3390
|
The function :meth:`cdxcore.subdir.CacheTracker.delete_cache_files` can be used
|
|
3334
3391
|
to delete all files involved in caching.
|
|
3392
|
+
|
|
3393
|
+
* ``return_cache_uid`` : bool, default ``False``
|
|
3394
|
+
|
|
3395
|
+
If ``True``, then the decorated function will return a tuple ``uid, result``
|
|
3396
|
+
where ``uid`` is the unique filename generated for this function call,
|
|
3397
|
+
and where ``result`` is the actual result from the function, cached or not.
|
|
3398
|
+
|
|
3399
|
+
Usage::
|
|
3400
|
+
|
|
3401
|
+
from cdxcore.subdir import SubDir
|
|
3402
|
+
cache_dir = SubDir("!/.cache")
|
|
3403
|
+
|
|
3404
|
+
@cache_dir.cache()
|
|
3405
|
+
def f(x, y):
|
|
3406
|
+
return x*y
|
|
3407
|
+
|
|
3408
|
+
uid, xy = f( x=1, y=2, return_cache_uid=True )
|
|
3409
|
+
|
|
3410
|
+
This pattern is thread-safe when compared to using::
|
|
3411
|
+
|
|
3412
|
+
xy = f( x=1, y=2 )
|
|
3413
|
+
uid = f.cache_info.filename
|
|
3335
3414
|
"""
|
|
3336
3415
|
return CacheCallable(subdir = self,
|
|
3337
3416
|
version = version,
|
|
@@ -3361,17 +3440,41 @@ class SubDir(object):
|
|
|
3361
3440
|
@cache.cache_class("0.1")
|
|
3362
3441
|
class A(object):
|
|
3363
3442
|
|
|
3364
|
-
@cache.
|
|
3443
|
+
@cache.cache_init(exclude_args=['debug'])
|
|
3365
3444
|
def __init__(self, x, debug):
|
|
3366
3445
|
if debug:
|
|
3367
3446
|
print("__init__",x)
|
|
3368
3447
|
self.x = x
|
|
3369
3448
|
|
|
3370
3449
|
"""
|
|
3371
|
-
return self.cache( name=name,
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3450
|
+
return self.cache( name=name, version=version, dependencies=dependencies, version_auto_class=version_auto_class)
|
|
3451
|
+
|
|
3452
|
+
def cache_init( self,
|
|
3453
|
+
label : Callable = None,
|
|
3454
|
+
uid : Callable = None,
|
|
3455
|
+
exclude_args : list[str] = None,
|
|
3456
|
+
include_args : list[str] = None,
|
|
3457
|
+
exclude_arg_types : list[type] = None,
|
|
3458
|
+
):
|
|
3459
|
+
"""
|
|
3460
|
+
Short-cut for :dec:`cdxcore.subdir.SubDir.cache` applied to decorating ``__init__``
|
|
3461
|
+
with a reduced number of available parameters.
|
|
3462
|
+
|
|
3463
|
+
Example::
|
|
3464
|
+
|
|
3465
|
+
cache = SubDir("!/.cache")
|
|
3466
|
+
|
|
3467
|
+
@cache.cache_class("0.1")
|
|
3468
|
+
class A(object):
|
|
3469
|
+
|
|
3470
|
+
@cache.cache_init(exclude_args=['debug'])
|
|
3471
|
+
def __init__(self, x, debug):
|
|
3472
|
+
if debug:
|
|
3473
|
+
print("__init__",x)
|
|
3474
|
+
self.x = x
|
|
3475
|
+
|
|
3476
|
+
"""
|
|
3477
|
+
return self.cache( label=label, uid=uid, exclude_args=exclude_args, include_args=include_args, exclude_arg_types=exclude_arg_types )
|
|
3375
3478
|
|
|
3376
3479
|
# ========================================================================
|
|
3377
3480
|
# Caching, convenience
|
|
@@ -3444,6 +3547,9 @@ def VersionedCacheRoot( directory : str, *,
|
|
|
3444
3547
|
|
|
3445
3548
|
* ``hash_length``: length used for hashes, see :class:`cdxcore.uniquehash.UniqueHash`.
|
|
3446
3549
|
|
|
3550
|
+
* ``debug_verbose`` set to ``Context.all`` after importing ``from cdxcore.verbose import Context``
|
|
3551
|
+
will turn on tracing all caching operations.
|
|
3552
|
+
|
|
3447
3553
|
Returns
|
|
3448
3554
|
-------
|
|
3449
3555
|
Root : :class:`cdxcore.subdir.SubDir`
|
|
@@ -3768,8 +3874,9 @@ class CacheCallable(object):
|
|
|
3768
3874
|
exclude_types = ( self._exclude_arg_types if not self._exclude_arg_types is None else set() )\
|
|
3769
3875
|
| ( self.global_exclude_arg_types if not self.global_exclude_arg_types is None else set())
|
|
3770
3876
|
|
|
3771
|
-
def execute( *args, override_cache_mode : CacheMode = None,
|
|
3772
|
-
track_cached_files : CacheTracker = None,
|
|
3877
|
+
def execute( *args, override_cache_mode : CacheMode|None = None,
|
|
3878
|
+
track_cached_files : CacheTracker|None = None,
|
|
3879
|
+
return_cache_uid : bool = False,
|
|
3773
3880
|
**kwargs ):
|
|
3774
3881
|
"""
|
|
3775
3882
|
Cached execution of the wrapped function
|
|
@@ -3899,7 +4006,7 @@ class CacheCallable(object):
|
|
|
3899
4006
|
# -------------------------
|
|
3900
4007
|
|
|
3901
4008
|
execute.cache_info.label = str(label) if not label is None else None
|
|
3902
|
-
execute.cache_info.filename = filename
|
|
4009
|
+
execute.cache_info.filename = filename # that is the unique ID for this call
|
|
3903
4010
|
execute.cache_info.version = version_
|
|
3904
4011
|
|
|
3905
4012
|
if self.cache_controller.keep_last_arguments:
|
|
@@ -3937,6 +4044,8 @@ class CacheCallable(object):
|
|
|
3937
4044
|
assert r.__magic_cache_call_init__ is None, ("**** Internal error. __init__ should reset __magic_cache_call_init__", F.__qualname__, label)
|
|
3938
4045
|
r.__magic_cache_call_init__ = False # since we called __new__, __init__ will be called next
|
|
3939
4046
|
|
|
4047
|
+
if return_cache_uid:
|
|
4048
|
+
return filename, r
|
|
3940
4049
|
return r
|
|
3941
4050
|
|
|
3942
4051
|
r = F(*args, **kwargs)
|
|
@@ -3966,6 +4075,9 @@ class CacheCallable(object):
|
|
|
3966
4075
|
debug_verbose.write(f"cache({name}): called '{label}' version 'version {version_}' and wrote result into '{self._subdir.full_file_name(filename)}'.")
|
|
3967
4076
|
else:
|
|
3968
4077
|
debug_verbose.write(f"cache({name}): called '{label}' version 'version {version_}' but did *not* write into '{self._subdir.full_file_name(filename)}'.")
|
|
4078
|
+
|
|
4079
|
+
if return_cache_uid:
|
|
4080
|
+
return filename, r
|
|
3969
4081
|
return r
|
|
3970
4082
|
|
|
3971
4083
|
update_wrapper( wrapper=execute, wrapped=F )
|
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "cdxcore"
|
|
9
|
-
version = "0.1.
|
|
9
|
+
version = "0.1.28"
|
|
10
10
|
description = "Basic Python Tools; upgraded cdxbasics"
|
|
11
11
|
authors = [{ name = "Hans Buehler", email = "github@buehler.london" }]
|
|
12
12
|
readme = "README.md"
|
|
@@ -25,14 +25,14 @@ import_local()
|
|
|
25
25
|
"""
|
|
26
26
|
Imports
|
|
27
27
|
"""
|
|
28
|
-
from cdxcore.subdir import SubDir, CacheMode, VersionError, VersionPresentError
|
|
28
|
+
from cdxcore.subdir import SubDir, CacheMode, VersionError, VersionPresentError, VersionedCacheRoot
|
|
29
29
|
import numpy as np
|
|
30
30
|
|
|
31
31
|
class Test(unittest.TestCase):
|
|
32
32
|
|
|
33
33
|
def test_subdir(self):
|
|
34
34
|
|
|
35
|
-
sub = SubDir("
|
|
35
|
+
sub = SubDir("?/.tmp_test_for_cdxbasics.subdir", delete_everything=True )
|
|
36
36
|
sub['y'] = 2
|
|
37
37
|
sub.write('z',3)
|
|
38
38
|
sub.write_string('l',"hallo")
|
|
@@ -193,11 +193,8 @@ class Test(unittest.TestCase):
|
|
|
193
193
|
with self.assertRaises(VersionError):
|
|
194
194
|
r = sub.read("test", None, version="2", raise_on_error=True)
|
|
195
195
|
# wrong version
|
|
196
|
-
sub.delete_everything()
|
|
197
196
|
|
|
198
197
|
def test_new(self):
|
|
199
|
-
|
|
200
|
-
|
|
201
198
|
subdir = SubDir("my_directory") # relative to current working directory
|
|
202
199
|
subdir = SubDir("./my_directory") # relative to current working directory
|
|
203
200
|
subdir = SubDir("~/my_directory") # relative to home directory
|
|
@@ -248,8 +245,6 @@ class Test(unittest.TestCase):
|
|
|
248
245
|
test_format( SubDir.GZIP, True )
|
|
249
246
|
test_format( SubDir.JSON_PICKLE )
|
|
250
247
|
|
|
251
|
-
|
|
252
|
-
|
|
253
248
|
def test_cache_mode(self):
|
|
254
249
|
|
|
255
250
|
on = CacheMode("on")
|
|
@@ -275,6 +270,66 @@ class Test(unittest.TestCase):
|
|
|
275
270
|
self.assertEqual( [ x.write for x in allc ], [True, True, False, False, True, False] )
|
|
276
271
|
self.assertEqual( [ x.delete for x in allc ], [False, False, False, True, True, False ] )
|
|
277
272
|
self.assertEqual( [ x.del_incomp for x in allc ], [True, False, False, True, True, False ] )
|
|
273
|
+
|
|
274
|
+
class A(object):
|
|
275
|
+
def __init__(self, x):
|
|
276
|
+
self.x = x
|
|
277
|
+
class B(object):
|
|
278
|
+
def __init__(self, x):
|
|
279
|
+
self.x = x
|
|
280
|
+
|
|
281
|
+
class Test(unittest.TestCase):
|
|
282
|
+
|
|
283
|
+
def test_cache( self ):
|
|
284
|
+
|
|
285
|
+
sub = VersionedCacheRoot("?/subdir_cache_test", exclude_arg_types=[A] )
|
|
286
|
+
|
|
287
|
+
@sub.cache("1.0")
|
|
288
|
+
def f(x):
|
|
289
|
+
return x
|
|
290
|
+
|
|
291
|
+
_ = f(1)
|
|
292
|
+
_ = f(1)
|
|
293
|
+
self.assertTrue( f.cache_info.last_cached )
|
|
294
|
+
|
|
295
|
+
@sub.cache("1.0")
|
|
296
|
+
def g(x):
|
|
297
|
+
return x
|
|
298
|
+
|
|
299
|
+
# a new B object each time -> no caching
|
|
300
|
+
_ = f(B(1))
|
|
301
|
+
_ = f(B(2))
|
|
302
|
+
self.assertFalse( f.cache_info.last_cached )
|
|
303
|
+
|
|
304
|
+
# same B object each time -> no caching
|
|
305
|
+
_ = f(B(1))
|
|
306
|
+
_ = f(B(1))
|
|
307
|
+
self.assertTrue( f.cache_info.last_cached )
|
|
308
|
+
|
|
309
|
+
# a new A object each time -> caching, as we ignore 'A' types
|
|
310
|
+
_ = f(A(1))
|
|
311
|
+
_ = f(A(2))
|
|
312
|
+
self.assertTrue( f.cache_info.last_cached )
|
|
313
|
+
|
|
314
|
+
@sub.cache("1.0", label=lambda x, **_: f"f({x})")
|
|
315
|
+
def f(x):
|
|
316
|
+
return x
|
|
317
|
+
|
|
318
|
+
_ = f(1)
|
|
319
|
+
self.assertEqual( f.cache_info.filename[:5], "f(1) " )
|
|
320
|
+
uid, _ = f(1, return_cache_uid=True)
|
|
321
|
+
self.assertEqual( uid[:5], "f(1) " )
|
|
322
|
+
|
|
323
|
+
@sub.cache("1.0", uid=lambda x, **_: f"f({x})")
|
|
324
|
+
def f(x):
|
|
325
|
+
return x
|
|
326
|
+
|
|
327
|
+
_ = f(1)
|
|
328
|
+
self.assertEqual( f.cache_info.filename, "f(1)" )
|
|
329
|
+
uid, _ = f(1, return_cache_uid=True)
|
|
330
|
+
self.assertEqual( uid, "f(1)" )
|
|
331
|
+
|
|
332
|
+
|
|
278
333
|
if __name__ == '__main__':
|
|
279
334
|
unittest.main()
|
|
280
335
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|