cdxcore 0.1.23__py3-none-any.whl → 0.1.26__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.
Potentially problematic release.
This version of cdxcore might be problematic. Click here for more details.
- cdxcore/__init__.py +1 -1
- cdxcore/subdir.py +452 -396
- cdxcore/uniquehash.py +1 -1
- {cdxcore-0.1.23.dist-info → cdxcore-0.1.26.dist-info}/METADATA +1 -1
- {cdxcore-0.1.23.dist-info → cdxcore-0.1.26.dist-info}/RECORD +8 -8
- {cdxcore-0.1.23.dist-info → cdxcore-0.1.26.dist-info}/WHEEL +0 -0
- {cdxcore-0.1.23.dist-info → cdxcore-0.1.26.dist-info}/licenses/LICENSE +0 -0
- {cdxcore-0.1.23.dist-info → cdxcore-0.1.26.dist-info}/top_level.txt +0 -0
cdxcore/subdir.py
CHANGED
|
@@ -94,8 +94,7 @@ File Format
|
|
|
94
94
|
* "BLOSC" uses `blosc <https://github.com/blosc/python-blosc>`__
|
|
95
95
|
to read/write compressed binary data. The blosc compression algorithm is very fast,
|
|
96
96
|
hence using this mode will not usually lead to notably slower performance than using
|
|
97
|
-
"PICKLE" but will generate smaller files, depending on your data structure.
|
|
98
|
-
|
|
97
|
+
"PICKLE" but will generate smaller files, depending on your data structure.
|
|
99
98
|
The default extension for "BLOSC" is "zbsc".
|
|
100
99
|
|
|
101
100
|
* "GZIP": uses :mod:`gzip` to
|
|
@@ -324,19 +323,19 @@ Caching
|
|
|
324
323
|
A :class:`cdxcore.subdir.SubDir` object offers an advanced context for caching calls to :class:`collection.abc.Callable``
|
|
325
324
|
objects with :dec:`cdxcore.subdir.SubDir.cache`.
|
|
326
325
|
|
|
327
|
-
|
|
326
|
+
.. code-block:: python
|
|
328
327
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
328
|
+
from cdxcore.subdir import SubDir
|
|
329
|
+
cache = SubDir("!/.cache")
|
|
330
|
+
cache.delete_all_content() # for illustration
|
|
331
|
+
|
|
332
|
+
@cache.cache("0.1")
|
|
333
|
+
def f(x,y):
|
|
334
|
+
return x*y
|
|
335
|
+
|
|
336
|
+
_ = f(1,2) # function gets computed and the result cached
|
|
337
|
+
_ = f(1,2) # restore result from cache
|
|
338
|
+
_ = f(2,2) # different parameters: compute and store result
|
|
340
339
|
|
|
341
340
|
This involves keying the cache by the function name and its current parameters using :class:`cdxcore.uniquehash.UniqueHash`,
|
|
342
341
|
and monitoring the functions version using :dec:`cdxcore.version.version`. The caching behaviour itself can be controlled by
|
|
@@ -377,8 +376,7 @@ from .pretty import PrettyObject
|
|
|
377
376
|
from .verbose import Context
|
|
378
377
|
from .version import Version, version as version_decorator, VersionError
|
|
379
378
|
from .util import fmt_list, fmt_filename, DEF_FILE_NAME_MAP, plain, is_filename
|
|
380
|
-
from .uniquehash import unique_hash48, UniqueLabel, NamedUniqueHash
|
|
381
|
-
|
|
379
|
+
from .uniquehash import unique_hash48, UniqueLabel, NamedUniqueHash, named_unique_filename48_8
|
|
382
380
|
|
|
383
381
|
"""
|
|
384
382
|
:meta private:
|
|
@@ -637,41 +635,34 @@ class CacheController( object ):
|
|
|
637
635
|
|
|
638
636
|
Parameters
|
|
639
637
|
----------
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
Defaults to ``[Context]``.
|
|
644
|
-
|
|
645
|
-
cache_mode : CacheMode, optional
|
|
646
|
-
Top level cache control.
|
|
647
|
-
Set to "OFF" to turn off all caching.
|
|
648
|
-
Default is "ON".
|
|
649
|
-
|
|
650
|
-
max_filename_length : int, optional
|
|
651
|
-
Maximum filename length. If unique id's exceed the file name a hash of length
|
|
652
|
-
``hash_length`` will be intergated into the file name.
|
|
653
|
-
See :class:`cdxcore.uniquehash.NamedUniqueHash`.
|
|
654
|
-
Default is ``48``.
|
|
655
|
-
|
|
656
|
-
hash_length : int, optional
|
|
657
|
-
Length of the hash used to make sure each filename is unique
|
|
658
|
-
See :class:`cdxcore.uniquehash.NamedUniqueHash`.
|
|
659
|
-
Default is ``8``.
|
|
660
|
-
|
|
661
|
-
debug_verbose : :class:`cdxcore.verbose.Context`, optional
|
|
662
|
-
If not ``None`` print caching process messages to this object.
|
|
663
|
-
|
|
664
|
-
Default is ``None``.
|
|
665
|
-
|
|
666
|
-
keep_last_arguments : bool, optional
|
|
667
|
-
Keep a dictionary of all parameters as string representations after each function call.
|
|
668
|
-
If the function ``F`` was decorated using :meth:``cdxcore.subdir.SubDir.cache``,
|
|
669
|
-
you can access this information via ``F.cache_info.last_arguments``.
|
|
638
|
+
exclude_arg_types : list[type], optional
|
|
639
|
+
List of types to exclude from producing unique ids from function arguments.
|
|
670
640
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
641
|
+
Defaults to ``[Context]``.
|
|
642
|
+
|
|
643
|
+
cache_mode : CacheMode, default ``ON``
|
|
644
|
+
Top level cache control.
|
|
645
|
+
Set to "OFF" to turn off all caching.
|
|
646
|
+
|
|
647
|
+
max_filename_length : int, default ``48``
|
|
648
|
+
Maximum filename length. If unique id's exceed the file name a hash of length
|
|
649
|
+
``hash_length`` will be intergated into the file name.
|
|
650
|
+
See :class:`cdxcore.uniquehash.NamedUniqueHash`.
|
|
651
|
+
|
|
652
|
+
hash_length : int, default ``8``
|
|
653
|
+
Length of the hash used to make sure each filename is unique
|
|
654
|
+
See :class:`cdxcore.uniquehash.NamedUniqueHash`.
|
|
655
|
+
|
|
656
|
+
debug_verbose : :class:`cdxcore.verbose.Context` | None, default ``None``
|
|
657
|
+
If not ``None`` print caching process messages to this object.
|
|
658
|
+
|
|
659
|
+
keep_last_arguments : bool, default ``False``
|
|
660
|
+
Keep a dictionary of all parameters as string representations after each function call.
|
|
661
|
+
If the function ``F`` was decorated using :meth:``cdxcore.subdir.SubDir.cache``,
|
|
662
|
+
you can access this information via ``F.cache_info.last_arguments``.
|
|
663
|
+
|
|
664
|
+
Note that strings are limited to 100 characters per argument to avoid memory
|
|
665
|
+
overload when large objects are passed.
|
|
675
666
|
"""
|
|
676
667
|
|
|
677
668
|
def __init__(self, *,
|
|
@@ -790,84 +781,74 @@ class SubDir(object):
|
|
|
790
781
|
|
|
791
782
|
Parameters
|
|
792
783
|
----------
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
784
|
+
name : str:
|
|
785
|
+
Name of the directory.
|
|
786
|
+
|
|
787
|
+
The name may start with any of the following special characters:
|
|
797
788
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
789
|
+
* ``'.'`` for current directory.
|
|
790
|
+
* ``'~'`` for home directory.
|
|
791
|
+
* ``'!'`` for system default temp directory.
|
|
792
|
+
* ``'?'`` for a temporary temp directory. In this case ``delete_everything_upon_exit`` is always ``True``.
|
|
802
793
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
ext : str, optional
|
|
819
|
-
Extension for files managed by this ``SubDir``. All files will share the same extension.
|
|
794
|
+
The directory name may also contain a formatting string for defining ``ext`` on the fly:
|
|
795
|
+
for example use ``"!/test;*.bin"`` to specify a directory ``"test"`` in the user's
|
|
796
|
+
temp directory with extension ``"bin"``.
|
|
797
|
+
|
|
798
|
+
The directory name can be set to ``None`` in which case it is always empty
|
|
799
|
+
and attempts to write to it fail with :class:`EOFError`.
|
|
800
|
+
|
|
801
|
+
parent : str | SubDir | None, default ``None``
|
|
802
|
+
Parent directory.
|
|
803
|
+
|
|
804
|
+
If ``parent`` is a :class:`cdxcore.subdir.SubDir` then its parameters are used
|
|
805
|
+
as default values here.
|
|
806
|
+
|
|
807
|
+
ext : str | None, default ``None``
|
|
808
|
+
Extension for files managed by this ``SubDir``. All files will share the same extension.
|
|
820
809
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
* 'pck' for the default PICKLE format.
|
|
828
|
-
* 'json' for JSON_PLAIN.
|
|
829
|
-
* 'jpck' for JSON_PICKLE.
|
|
830
|
-
* 'zbsc' for BLOSC.
|
|
831
|
-
* 'pgz' for GZIP.
|
|
832
|
-
|
|
833
|
-
Default is ``None``.
|
|
810
|
+
If set to ``""`` no extension is assigned to this directory. That means, for example, that
|
|
811
|
+
:meth:`cdxcore.subdir.SubDir.files` returns all files contained in the directory, not
|
|
812
|
+
just files with a specific extension.
|
|
813
|
+
|
|
814
|
+
If ``None``, use an extension depending on ``fmt``:
|
|
834
815
|
|
|
835
|
-
|
|
816
|
+
* 'pck' for the default PICKLE format.
|
|
817
|
+
* 'json' for JSON_PLAIN.
|
|
818
|
+
* 'jpck' for JSON_PICKLE.
|
|
819
|
+
* 'zbsc' for BLOSC.
|
|
820
|
+
* 'pgz' for GZIP.
|
|
821
|
+
|
|
822
|
+
fmt : :class:`cdxcore.subdir.Format` | None, default ``Format.PICKLE``
|
|
836
823
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
Default is ``Format.PICKLE``.
|
|
824
|
+
One of the :class:`cdxcore.subdir.Format` codes.
|
|
825
|
+
If ``ext`` is left to ``None`` then setting the a format will also set the corrsponding ``ext``.
|
|
841
826
|
|
|
842
|
-
|
|
827
|
+
create_directory : bool | None, default ``False``
|
|
828
|
+
|
|
829
|
+
Whether to create the directory upon creation of the ``SubDir`` object; otherwise it will be created upon first
|
|
830
|
+
:meth:`cdxcore.subdir.SubDir.write`.
|
|
843
831
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
Set to ``None`` to use the setting of the parent directory, or ``False`` if no parent
|
|
848
|
-
is specified.
|
|
849
|
-
|
|
850
|
-
Default is ``False``.
|
|
832
|
+
Set to ``None`` to use the setting of the parent directory, or ``False`` if no parent
|
|
833
|
+
is specified.
|
|
851
834
|
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
835
|
+
cache_controller : :class:`cdxcore.subdir.CacheController` | None, default ``None``
|
|
836
|
+
|
|
837
|
+
An object which fine-tunes the behaviour of :meth:`cdxcore.subdir.SubDir.cache`.
|
|
838
|
+
See that function's documentation for further details. Default is ``None``.
|
|
856
839
|
|
|
857
|
-
|
|
840
|
+
delete_everything : bool, default ``False``
|
|
841
|
+
|
|
842
|
+
Delete all contents in the newly defined sub directory upon creation.
|
|
858
843
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
delete_everything_upon_exit : bool, optional
|
|
844
|
+
delete_everything_upon_exit : bool, default ``False``
|
|
845
|
+
|
|
846
|
+
Delete all contents of the current exist if ``self`` is deleted.
|
|
847
|
+
This is the always ``True`` if the ``"?/"`` pretext was used.
|
|
864
848
|
|
|
865
|
-
|
|
866
|
-
This is the always ``True`` if the ``"?/"`` pretext was used.
|
|
867
|
-
|
|
868
|
-
Note, however, that this will only be executed once the object is garbage collected.
|
|
849
|
+
Note, however, that this will only be executed once the object is garbage collected.
|
|
869
850
|
|
|
870
|
-
|
|
851
|
+
Default is, for some good reason, ``False``.
|
|
871
852
|
"""
|
|
872
853
|
|
|
873
854
|
class __RETURN_SUB_DIRECTORY(object):
|
|
@@ -997,8 +978,11 @@ class SubDir(object):
|
|
|
997
978
|
self._crt = bool(create_directory)
|
|
998
979
|
|
|
999
980
|
# cache controller
|
|
1000
|
-
|
|
1001
|
-
|
|
981
|
+
if cache_controller is None:
|
|
982
|
+
self._cctrl = parent._cctrl if not parent is None else None
|
|
983
|
+
else:
|
|
984
|
+
assert type(cache_controller).__name__ == CacheController.__name__, ("'cache_controller' should be of type 'CacheController'", type(cache_controller))
|
|
985
|
+
self._cctrl = cache_controller
|
|
1002
986
|
|
|
1003
987
|
# name
|
|
1004
988
|
self._tclean = delete_everything_upon_exit # delete directory upon completion
|
|
@@ -1170,13 +1154,13 @@ class SubDir(object):
|
|
|
1170
1154
|
|
|
1171
1155
|
Parameters
|
|
1172
1156
|
----------
|
|
1173
|
-
|
|
1174
|
-
|
|
1157
|
+
ext_or_fmt : str | :class:`cdxcore.subdir.Format` | None, default ``None``
|
|
1158
|
+
An extension or a format.
|
|
1175
1159
|
|
|
1176
1160
|
Returns
|
|
1177
1161
|
-------
|
|
1178
|
-
|
|
1179
|
-
|
|
1162
|
+
ext : str
|
|
1163
|
+
The extension with leading ``'.'``.
|
|
1180
1164
|
"""
|
|
1181
1165
|
if isinstance(ext_or_fmt, Format):
|
|
1182
1166
|
return self._auto_ext(ext_or_fmt)
|
|
@@ -1193,9 +1177,9 @@ class SubDir(object):
|
|
|
1193
1177
|
|
|
1194
1178
|
Returns
|
|
1195
1179
|
-------
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1180
|
+
(ext, fmt) : tuple
|
|
1181
|
+
Here ``ext`` contains the leading ``'.'`` and ``fmt`` is
|
|
1182
|
+
of type :class:`cdxcore.subdir.Format`.
|
|
1199
1183
|
"""
|
|
1200
1184
|
if isinstance(ext, Format):
|
|
1201
1185
|
verify( fmt is None or fmt == ext, "If 'ext' is a Format, then 'fmt' must match 'ext' or be None. Found '%s' and '%s', respectively.", ext, fmt, exception=ValueError )
|
|
@@ -1210,6 +1194,11 @@ class SubDir(object):
|
|
|
1210
1194
|
def cache_controller(self):
|
|
1211
1195
|
""" Returns an assigned :class:`cdxcore.subdir.CacheController`, or ``None`` """
|
|
1212
1196
|
return self._cctrl if not self._cctrl is None else default_cacheController
|
|
1197
|
+
|
|
1198
|
+
@property
|
|
1199
|
+
def cache_mode(self):
|
|
1200
|
+
""" Returns the :class:`cdxcore.subdir.CacheMode` associated with the underlying cache controller """
|
|
1201
|
+
return self.cache_controller.cache_mode
|
|
1213
1202
|
|
|
1214
1203
|
# -- static helpers --
|
|
1215
1204
|
|
|
@@ -1250,9 +1239,10 @@ class SubDir(object):
|
|
|
1250
1239
|
def _extract_ext( ext : str ) -> str:
|
|
1251
1240
|
"""
|
|
1252
1241
|
Checks that 'ext' is an extension, and returns .ext.
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1242
|
+
|
|
1243
|
+
* Accepts '.ext' and 'ext'
|
|
1244
|
+
* Detects use of directories
|
|
1245
|
+
* Returns '*' if ext='*'
|
|
1256
1246
|
"""
|
|
1257
1247
|
assert not ext is None, ("'ext' should not be None here")
|
|
1258
1248
|
verify( isinstance(ext,str), "Extension 'ext' must be a string. Found type %s", type(ext).__name__, exception=ValueError )
|
|
@@ -1284,16 +1274,16 @@ class SubDir(object):
|
|
|
1284
1274
|
|
|
1285
1275
|
Parameters
|
|
1286
1276
|
----------
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1277
|
+
file : str
|
|
1278
|
+
Core file name without path or extension.
|
|
1279
|
+
ext : str | None, default ``None``
|
|
1280
|
+
If not ``None``, use this extension rather than :attr:`cdxcore.subdir.SubDir.ext`.
|
|
1291
1281
|
|
|
1292
1282
|
Returns
|
|
1293
1283
|
-------
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1284
|
+
Filename : str | None
|
|
1285
|
+
Fully qualified system file name.
|
|
1286
|
+
If ``self`` is ``None``, then this function returns ``None``; if ``file`` is ``None`` then this function also returns ``None``.
|
|
1297
1287
|
"""
|
|
1298
1288
|
if self._path is None or file is None:
|
|
1299
1289
|
return None
|
|
@@ -1375,22 +1365,22 @@ class SubDir(object):
|
|
|
1375
1365
|
|
|
1376
1366
|
Parameters
|
|
1377
1367
|
----------
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1368
|
+
reader( file, full_file_name, default )
|
|
1369
|
+
A function which is called to read the file once the correct directory is identified
|
|
1370
|
+
file : file (for error messages, might include '/')
|
|
1371
|
+
full_file_name : full file name
|
|
1372
|
+
default value
|
|
1373
|
+
file : str or list
|
|
1374
|
+
str: fully qualified file
|
|
1375
|
+
list: list of fully qualified names
|
|
1376
|
+
default :
|
|
1377
|
+
default value. None is a valid default value
|
|
1378
|
+
list : list of defaults for a list of keys
|
|
1379
|
+
raise_on_error : bool
|
|
1380
|
+
If True, and the file does not exist, throw exception
|
|
1381
|
+
ext :
|
|
1382
|
+
Extension or None for current extension.
|
|
1383
|
+
list : list of extensions for a list of keys
|
|
1394
1384
|
"""
|
|
1395
1385
|
# vector version
|
|
1396
1386
|
if not isinstance(file,str):
|
|
@@ -1489,7 +1479,6 @@ class SubDir(object):
|
|
|
1489
1479
|
def handle_pickle_error(e):
|
|
1490
1480
|
err = "invalid load key, '\\x03'."
|
|
1491
1481
|
if not version is None or e.args[0] != err:
|
|
1492
|
-
print("####", e.args)
|
|
1493
1482
|
raise e
|
|
1494
1483
|
raise VersionPresentError(
|
|
1495
1484
|
f"Error reading '{full_file_name}': encountered an unpickling error '{err}' "+\
|
|
@@ -1627,10 +1616,10 @@ class SubDir(object):
|
|
|
1627
1616
|
default = None,
|
|
1628
1617
|
raise_on_error : bool = False,
|
|
1629
1618
|
*,
|
|
1630
|
-
version : str = None,
|
|
1619
|
+
version : str|None = None,
|
|
1631
1620
|
delete_wrong_version : bool = True,
|
|
1632
|
-
ext : str = None,
|
|
1633
|
-
fmt : Format = None
|
|
1621
|
+
ext : str|None = None,
|
|
1622
|
+
fmt : Format|None = None
|
|
1634
1623
|
):
|
|
1635
1624
|
"""
|
|
1636
1625
|
Read data from a file if the file exists, or return ``default``.
|
|
@@ -1657,58 +1646,64 @@ class SubDir(object):
|
|
|
1657
1646
|
|
|
1658
1647
|
Parameters
|
|
1659
1648
|
----------
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1649
|
+
file : str
|
|
1650
|
+
A file name or a list thereof. ``file`` may contain subdirectories.
|
|
1651
|
+
|
|
1652
|
+
default :
|
|
1653
|
+
Default value, or default values if ``file`` is a list.
|
|
1654
|
+
|
|
1655
|
+
raise_on_error : bool, default ``False``
|
|
1656
|
+
Whether to raise an exception if reading an existing file failed.
|
|
1657
|
+
By default this function fails silently and returns the default.
|
|
1658
|
+
|
|
1659
|
+
version : str | None, default ``None``
|
|
1660
|
+
If not ``None``, specifies the version of the current code base.
|
|
1661
|
+
|
|
1662
|
+
In this case, this version will be compared to the version of the file being read.
|
|
1663
|
+
If they do not match, read fails (either by returning default or throwing a :class:`cdxcore.version.VersionError` exception).
|
|
1675
1664
|
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1665
|
+
You can specify version ``"*"`` to accept any version.
|
|
1666
|
+
Note that this is distinct
|
|
1667
|
+
to using ``None`` which stipulates that the file should not
|
|
1668
|
+
have version information.
|
|
1669
|
+
|
|
1670
|
+
delete_wrong_version : bool, default ``True``
|
|
1671
|
+
If ``True``, and if a wrong version was found, delete the file.
|
|
1683
1672
|
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
* ``None`` to use directory's default.
|
|
1690
|
-
* ``'*'`` to use the extension implied by ``fmt``.
|
|
1691
|
-
* ``""`` to turn of extension management.
|
|
1673
|
+
ext : str | None, default ``None``
|
|
1674
|
+
Extension overwrite, or a list thereof if ``file`` is a list.
|
|
1675
|
+
|
|
1676
|
+
Use:
|
|
1692
1677
|
|
|
1693
|
-
|
|
1694
|
-
|
|
1678
|
+
* ``None`` to use directory's default.
|
|
1679
|
+
* ``'*'`` to use the extension implied by ``fmt``.
|
|
1680
|
+
* ``""`` to turn of extension management.
|
|
1681
|
+
|
|
1682
|
+
fmt : :class:`cdxcore.subdir.Format` | None, default ``None``
|
|
1683
|
+
File :class:`cdxcore.subdir.Format` or ``None`` to use the directory's default.
|
|
1684
|
+
|
|
1685
|
+
Note:
|
|
1695
1686
|
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
* ``fmt`` cannot be a list even if ``file`` is.
|
|
1699
|
-
* Unless ``ext`` or the SubDir's extension is ``'*'``, changing the format does not automatically change the extension.
|
|
1687
|
+
* ``fmt`` cannot be a list even if ``file`` is.
|
|
1688
|
+
* Unless ``ext`` or the SubDir's extension is ``'*'``, changing the format does not automatically change the extension.
|
|
1700
1689
|
|
|
1701
1690
|
Returns
|
|
1702
1691
|
-------
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1692
|
+
Content : type | list
|
|
1693
|
+
For a single ``file`` returns the content of the file if successfully read, or ``default`` otherwise.
|
|
1694
|
+
If ``file``` is a list, this function returns a list of contents.
|
|
1706
1695
|
|
|
1707
1696
|
Raises
|
|
1708
1697
|
------
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1698
|
+
Version error : :class:`cdxcore.version.VersionError`:
|
|
1699
|
+
If the file's version did not match the ``version`` provided.
|
|
1700
|
+
|
|
1701
|
+
Version present : :class:`cdxcore.subdir.VersionPresentError`:
|
|
1702
|
+
When attempting to read a file without ``version`` which has a version this exception is raised.
|
|
1703
|
+
|
|
1704
|
+
I/O errors : ``Exception``
|
|
1705
|
+
Various standard I/O errors are raisedas usual.
|
|
1706
|
+
|
|
1712
1707
|
"""
|
|
1713
1708
|
return self._read( file=file,
|
|
1714
1709
|
default=default,
|
|
@@ -1725,42 +1720,43 @@ class SubDir(object):
|
|
|
1725
1720
|
|
|
1726
1721
|
Parameters
|
|
1727
1722
|
----------
|
|
1728
|
-
|
|
1729
|
-
|
|
1723
|
+
file : str
|
|
1724
|
+
A filename, or a list thereof.
|
|
1725
|
+
|
|
1730
1726
|
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1727
|
+
version : str
|
|
1728
|
+
Specifies the version to compare the file's version with.
|
|
1729
|
+
|
|
1730
|
+
You can use ``"*"`` to match any version.
|
|
1735
1731
|
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1732
|
+
raise_on_error : bool
|
|
1733
|
+
Whether to raise an exception if accessing an existing file failed (e.g. if it is a directory).
|
|
1734
|
+
By default this function fails silently and returns the default.
|
|
1739
1735
|
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
* ``None`` to use directory's default.
|
|
1749
|
-
* ``"*"`` to use the extension implied by ``fmt``.
|
|
1750
|
-
* ``""`` for no extension.
|
|
1736
|
+
delete_wrong_version : bool, default ``True``
|
|
1737
|
+
If ``True``, and if a wrong version was found, delete ``file``.
|
|
1738
|
+
|
|
1739
|
+
ext : str | None, default ``None``
|
|
1740
|
+
Extension overwrite, or a list thereof if ``file`` is a list.
|
|
1741
|
+
|
|
1742
|
+
Set to:
|
|
1751
1743
|
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1744
|
+
* ``None`` to use directory's default.
|
|
1745
|
+
* ``"*"`` to use the extension implied by ``fmt``.
|
|
1746
|
+
* ``""`` for no extension.
|
|
1747
|
+
|
|
1748
|
+
fmt : :class:`cdxcore.subdir.Format` | None, default ``None``
|
|
1749
|
+
File format or ``None`` to use the directory's default.
|
|
1750
|
+
Note that ``fmt`` cannot be a list even if ``file`` is.
|
|
1755
1751
|
|
|
1756
1752
|
Returns
|
|
1757
1753
|
-------
|
|
1758
1754
|
Status : bool
|
|
1759
|
-
Returns
|
|
1755
|
+
Returns ``True`` only if the file exists, has version information, and its version is equal to ``version``.
|
|
1760
1756
|
"""
|
|
1761
1757
|
return self._read( file=file,default=False,raise_on_error=raise_on_error,version=version,ext=ext,fmt=fmt,delete_wrong_version=delete_wrong_version,handle_version=SubDir.VER_CHECK )
|
|
1762
1758
|
|
|
1763
|
-
def get_version( self, file : str, raise_on_error : bool = False, *, ext : str = None, fmt : Format = None ):
|
|
1759
|
+
def get_version( self, file : str, raise_on_error : bool = False, *, ext : str|None = None, fmt : Format|None = None ):
|
|
1764
1760
|
"""
|
|
1765
1761
|
Returns a version stored in a file.
|
|
1766
1762
|
|
|
@@ -1769,32 +1765,33 @@ class SubDir(object):
|
|
|
1769
1765
|
|
|
1770
1766
|
Parameters
|
|
1771
1767
|
----------
|
|
1772
|
-
|
|
1773
|
-
|
|
1768
|
+
file : str
|
|
1769
|
+
A filename, or a list thereof.
|
|
1774
1770
|
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1771
|
+
raise_on_error : bool
|
|
1772
|
+
Whether to raise an exception if accessing an existing file failed (e.g. if it is a directory).
|
|
1773
|
+
By default this function fails silently and returns the default.
|
|
1778
1774
|
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
* ``None`` to use directory's default.
|
|
1788
|
-
* ``"*"`` to use the extension implied by ``fmt``.
|
|
1789
|
-
* ``""`` for no extension.
|
|
1775
|
+
delete_wrong_version : bool, default ``True``
|
|
1776
|
+
If ``True``, and if a wrong version was found, delete ``file``.
|
|
1777
|
+
|
|
1778
|
+
ext : str | None, default ``None``
|
|
1779
|
+
Extension overwrite, or a list thereof if ``file`` is a list.
|
|
1780
|
+
|
|
1781
|
+
Set to:
|
|
1790
1782
|
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1783
|
+
* ``None`` to use directory's default.
|
|
1784
|
+
* ``"*"`` to use the extension implied by ``fmt``.
|
|
1785
|
+
* ``""`` for no extension.
|
|
1786
|
+
|
|
1787
|
+
fmt : :class:`cdxcore.subdir.Format` | None, default ``None``
|
|
1788
|
+
File format or ``None`` to use the directory's default.
|
|
1789
|
+
Note that ``fmt`` cannot be a list even if ``file`` is.
|
|
1794
1790
|
|
|
1795
1791
|
Returns
|
|
1796
1792
|
-------
|
|
1797
|
-
|
|
1793
|
+
version : str
|
|
1794
|
+
The version.
|
|
1798
1795
|
"""
|
|
1799
1796
|
return self._read( file=file,default=None,raise_on_error=raise_on_error,version="",ext=ext,fmt=fmt,delete_wrong_version=False,handle_version=SubDir.VER_RETURN )
|
|
1800
1797
|
|
|
@@ -1851,9 +1848,9 @@ class SubDir(object):
|
|
|
1851
1848
|
# write to temp file, then rename into target file
|
|
1852
1849
|
# this reduces collision when i/o operations are slow
|
|
1853
1850
|
full_file_name = self.full_file_name(file,ext=ext)
|
|
1854
|
-
tmp_file
|
|
1855
|
-
tmp_i
|
|
1856
|
-
fullTmpFile
|
|
1851
|
+
tmp_file = self.temp_file_name( file )
|
|
1852
|
+
tmp_i = 0
|
|
1853
|
+
fullTmpFile = self.full_file_name(tmp_file,ext="tmp" if not ext=="tmp" else "_tmp")
|
|
1857
1854
|
while os.path.exists(fullTmpFile):
|
|
1858
1855
|
fullTmpFile = self.full_file_name(tmp_file) + "." + str(tmp_i) + ".tmp"
|
|
1859
1856
|
tmp_i += 1
|
|
@@ -1879,9 +1876,9 @@ class SubDir(object):
|
|
|
1879
1876
|
obj,
|
|
1880
1877
|
raise_on_error : bool = True,
|
|
1881
1878
|
*,
|
|
1882
|
-
version : str = None,
|
|
1883
|
-
ext : str = None,
|
|
1884
|
-
fmt : Format = None ) -> bool:
|
|
1879
|
+
version : str|None = None,
|
|
1880
|
+
ext : str|None = None,
|
|
1881
|
+
fmt : Format|None = None ) -> bool:
|
|
1885
1882
|
"""
|
|
1886
1883
|
Writes an object to file.
|
|
1887
1884
|
|
|
@@ -1912,17 +1909,17 @@ class SubDir(object):
|
|
|
1912
1909
|
raise_on_error : bool
|
|
1913
1910
|
If ``False``, this function will return ``False`` upon failure.
|
|
1914
1911
|
|
|
1915
|
-
version : str
|
|
1912
|
+
version : str | None, default ``None``
|
|
1916
1913
|
If not ``None``, specifies the version of the code which generated ``obj``.
|
|
1917
1914
|
This version will be written to the beginning of the file.
|
|
1918
1915
|
|
|
1919
|
-
ext : str
|
|
1916
|
+
ext : str | None, default ``None``
|
|
1920
1917
|
Extension, or list thereof if ``file`` is a list.
|
|
1921
1918
|
|
|
1922
1919
|
* Use ``None`` to use directory's default extension.
|
|
1923
1920
|
* Use ``"*"`` to use the extension implied by ``fmt``.
|
|
1924
1921
|
|
|
1925
|
-
fmt : :class:`cdxcore.subdir.Format`
|
|
1922
|
+
fmt : :class:`cdxcore.subdir.Format` | None, default ``None``
|
|
1926
1923
|
File format or ``None`` to use the directory's default.
|
|
1927
1924
|
Note that ``fmt`` cannot be a list even if ``file`` is.
|
|
1928
1925
|
Note that unless ``ext`` or the SubDir's extension is '*',
|
|
@@ -2022,7 +2019,7 @@ class SubDir(object):
|
|
|
2022
2019
|
return True
|
|
2023
2020
|
return self._write( writer=writer, file=file, obj=obj, raise_on_error=raise_on_error, ext=ext )
|
|
2024
2021
|
|
|
2025
|
-
def write_string( self, file : str, line : str, raise_on_error : bool = True, *, ext : str = None ) -> bool:
|
|
2022
|
+
def write_string( self, file : str, line : str, raise_on_error : bool = True, *, ext : str|None = None ) -> bool:
|
|
2026
2023
|
"""
|
|
2027
2024
|
Writes a line of text into a file.
|
|
2028
2025
|
|
|
@@ -2051,7 +2048,7 @@ class SubDir(object):
|
|
|
2051
2048
|
|
|
2052
2049
|
# -- iterate --
|
|
2053
2050
|
|
|
2054
|
-
def files(self, *, ext : str = None) -> list:
|
|
2051
|
+
def files(self, *, ext : str|None = None) -> list:
|
|
2055
2052
|
"""
|
|
2056
2053
|
Returns a list of files in this subdirectory with the current extension, or the specified extension.
|
|
2057
2054
|
|
|
@@ -2100,9 +2097,10 @@ class SubDir(object):
|
|
|
2100
2097
|
subdirs.append( entry.name )
|
|
2101
2098
|
return subdirs
|
|
2102
2099
|
|
|
2103
|
-
#
|
|
2100
|
+
# delete
|
|
2101
|
+
# ------
|
|
2104
2102
|
|
|
2105
|
-
def delete( self, file : str, raise_on_error: bool = False, *, ext : str = None ):
|
|
2103
|
+
def delete( self, file : str, raise_on_error: bool = False, *, ext : str|None = None ):
|
|
2106
2104
|
"""
|
|
2107
2105
|
Deletes ``file``.
|
|
2108
2106
|
|
|
@@ -2111,21 +2109,21 @@ class SubDir(object):
|
|
|
2111
2109
|
|
|
2112
2110
|
Parameters
|
|
2113
2111
|
----------
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2112
|
+
file :
|
|
2113
|
+
filename, or list of filenames
|
|
2114
|
+
|
|
2115
|
+
raise_on_error : bool, default ``False``
|
|
2116
|
+
If ``False``, do not throw :class:`KeyError` if file does not exist
|
|
2117
|
+
or another error occurs.
|
|
2118
|
+
|
|
2119
|
+
ext : str | None, default ``None``
|
|
2120
|
+
Extension, or list thereof if ``file`` is a list.
|
|
2121
|
+
|
|
2122
|
+
Use
|
|
2123
|
+
|
|
2124
|
+
* ``None`` for the directory default.
|
|
2125
|
+
* ``""`` to not use an automatic extension.
|
|
2126
|
+
* ``"*"`` to use the extension associated with the format of the directory.
|
|
2129
2127
|
"""
|
|
2130
2128
|
# do not do anything if the object was deleted
|
|
2131
2129
|
if self._path is None:
|
|
@@ -2161,21 +2159,21 @@ class SubDir(object):
|
|
|
2161
2159
|
else:
|
|
2162
2160
|
os.remove(full_file_name)
|
|
2163
2161
|
|
|
2164
|
-
def delete_all_files( self, raise_on_error : bool = False, *, ext : str = None ):
|
|
2162
|
+
def delete_all_files( self, raise_on_error : bool = False, *, ext : str|None = None ):
|
|
2165
2163
|
"""
|
|
2166
2164
|
Deletes all valid keys in this sub directory with the correct extension.
|
|
2167
2165
|
|
|
2168
2166
|
Parameters
|
|
2169
2167
|
----------
|
|
2170
|
-
|
|
2171
|
-
|
|
2168
|
+
raise_on_error : bool
|
|
2169
|
+
Set to ``False`` to quietly ignore errors.
|
|
2170
|
+
|
|
2171
|
+
ext : str | None, default ``None``
|
|
2172
|
+
Extension to be used:
|
|
2172
2173
|
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
* ``None`` for the directory default.
|
|
2177
|
-
* ``""`` to not use an automatic extension.
|
|
2178
|
-
* ``"*"`` to use the extension associated with the format of the directory.
|
|
2174
|
+
* ``None`` for the directory default.
|
|
2175
|
+
* ``""`` to not use an automatic extension.
|
|
2176
|
+
* ``"*"`` to use the extension associated with the format of the directory.
|
|
2179
2177
|
"""
|
|
2180
2178
|
if self._path is None:
|
|
2181
2179
|
if raise_on_error: raise EOFError("Cannot delete all files: current directory not specified")
|
|
@@ -2184,7 +2182,7 @@ class SubDir(object):
|
|
|
2184
2182
|
return
|
|
2185
2183
|
self.delete( self.files(ext=ext), raise_on_error=raise_on_error, ext=ext )
|
|
2186
2184
|
|
|
2187
|
-
def delete_all_content( self, delete_self : bool = False, raise_on_error : bool = False, *, ext : str = None ):
|
|
2185
|
+
def delete_all_content( self, delete_self : bool = False, raise_on_error : bool = False, *, ext : str|None = None ):
|
|
2188
2186
|
"""
|
|
2189
2187
|
Deletes all valid keys and subdirectories in this sub directory.
|
|
2190
2188
|
|
|
@@ -2193,13 +2191,13 @@ class SubDir(object):
|
|
|
2193
2191
|
|
|
2194
2192
|
Parameters
|
|
2195
2193
|
----------
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2194
|
+
delete_self: bool
|
|
2195
|
+
Whether to delete the directory itself as well, or only its contents.
|
|
2196
|
+
raise_on_error: bool
|
|
2197
|
+
``False`` for silent failure
|
|
2198
|
+
ext : str | None, default ``None``
|
|
2199
|
+
Extension for keys, or ``None`` for the directory's default.
|
|
2200
|
+
Use ``""`` to match all files regardless of extension.
|
|
2203
2201
|
"""
|
|
2204
2202
|
# do not do anything if the object was deleted
|
|
2205
2203
|
if self._path is None:
|
|
@@ -2244,30 +2242,29 @@ class SubDir(object):
|
|
|
2244
2242
|
elif keep_directory and not os.path.exists(self._path[:-1]):
|
|
2245
2243
|
os.makedirs(self._path[:-1])
|
|
2246
2244
|
|
|
2247
|
-
#
|
|
2245
|
+
# file ops
|
|
2246
|
+
# --------
|
|
2248
2247
|
|
|
2249
|
-
def exists(self, file : str, *, ext : str = None ) -> bool:
|
|
2248
|
+
def exists(self, file : str, *, ext : str|None = None ) -> bool:
|
|
2250
2249
|
"""
|
|
2251
2250
|
Checks whether a file exists.
|
|
2252
2251
|
|
|
2253
2252
|
Parameters
|
|
2254
2253
|
----------
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
Use
|
|
2254
|
+
file :
|
|
2255
|
+
Filename, or list of filenames.
|
|
2256
|
+
|
|
2257
|
+
ext : str | None, default ``None``
|
|
2258
|
+
Extension to be used:
|
|
2262
2259
|
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2260
|
+
* ``None`` for the directory default.
|
|
2261
|
+
* ``""`` to not use an automatic extension.
|
|
2262
|
+
* ``"*"`` to use the extension associated with the format of the directory.
|
|
2266
2263
|
|
|
2267
2264
|
Returns
|
|
2268
2265
|
-------
|
|
2269
|
-
|
|
2270
|
-
|
|
2266
|
+
Status : bool
|
|
2267
|
+
If ``file`` is a string, returns ``True`` or ``False``, else it will return a list of ``bool`` values.
|
|
2271
2268
|
"""
|
|
2272
2269
|
# vector version
|
|
2273
2270
|
if not isinstance(file,str):
|
|
@@ -2325,7 +2322,7 @@ class SubDir(object):
|
|
|
2325
2322
|
return None
|
|
2326
2323
|
return func(full_file_name)
|
|
2327
2324
|
|
|
2328
|
-
def get_creation_time( self, file : str, *, ext : str = None ) -> datetime.datetime:
|
|
2325
|
+
def get_creation_time( self, file : str, *, ext : str|None = None ) -> datetime.datetime:
|
|
2329
2326
|
"""
|
|
2330
2327
|
Returns the creation time of a file.
|
|
2331
2328
|
|
|
@@ -2333,21 +2330,21 @@ class SubDir(object):
|
|
|
2333
2330
|
|
|
2334
2331
|
Parameters
|
|
2335
2332
|
----------
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2333
|
+
file :
|
|
2334
|
+
Filename, or list of filenames.
|
|
2335
|
+
|
|
2336
|
+
ext : str | None, default ``None``
|
|
2337
|
+
Extension to be used:
|
|
2338
|
+
|
|
2339
|
+
* ``None`` for the directory default.
|
|
2340
|
+
* ``""`` to not use an automatic extension.
|
|
2341
|
+
* ``"*"`` to use the extension associated with the format of the directory.
|
|
2345
2342
|
|
|
2346
2343
|
Returns
|
|
2347
2344
|
-------
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2345
|
+
Datetime : :class:`datetime.datetime`
|
|
2346
|
+
A single ``datetime`` if ``file`` is a string, otherwise a list of ``datetime``'s.
|
|
2347
|
+
Returns ``None`` if an error occured.
|
|
2351
2348
|
"""
|
|
2352
2349
|
return self._getFileProperty( file=file, ext=ext, func=lambda x : datetime.datetime.fromtimestamp(os.path.getctime(x)) )
|
|
2353
2350
|
|
|
@@ -2359,21 +2356,21 @@ class SubDir(object):
|
|
|
2359
2356
|
|
|
2360
2357
|
Parameters
|
|
2361
2358
|
----------
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2359
|
+
file :
|
|
2360
|
+
Filename, or list of filenames.
|
|
2361
|
+
|
|
2362
|
+
ext : str | None, default ``None``
|
|
2363
|
+
Extension to be used:
|
|
2364
|
+
|
|
2365
|
+
* ``None`` for the directory default.
|
|
2366
|
+
* ``""`` to not use an automatic extension.
|
|
2367
|
+
* ``"*"`` to use the extension associated with the format of the directory.
|
|
2371
2368
|
|
|
2372
2369
|
Returns
|
|
2373
2370
|
-------
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2371
|
+
Datetime : :class:`datetime.datetime`
|
|
2372
|
+
A single ``datetime`` if ``file`` is a string, otherwise a list of ``datetime``'s.
|
|
2373
|
+
Returns ``None`` if an error occured.
|
|
2377
2374
|
"""
|
|
2378
2375
|
return self._getFileProperty( file=file, ext=ext, func=lambda x : datetime.datetime.fromtimestamp(os.path.getmtime(x)) )
|
|
2379
2376
|
|
|
@@ -2385,20 +2382,21 @@ class SubDir(object):
|
|
|
2385
2382
|
|
|
2386
2383
|
Parameters
|
|
2387
2384
|
----------
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2385
|
+
file :
|
|
2386
|
+
Filename, or list of filenames.
|
|
2387
|
+
|
|
2388
|
+
ext : str | None, default ``None``
|
|
2389
|
+
Extension to be used:
|
|
2390
|
+
|
|
2391
|
+
* ``None`` for the directory default.
|
|
2392
|
+
* ``""`` to not use an automatic extension.
|
|
2393
|
+
* ``"*"`` to use the extension associated with the format of the directory.
|
|
2396
2394
|
|
|
2397
2395
|
Returns
|
|
2398
2396
|
-------
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2397
|
+
Datetime : :class:`datetime.datetime`
|
|
2398
|
+
A single ``datetime`` if ``file`` is a string, otherwise a list of ``datetime``'s.
|
|
2399
|
+
Returns ``None`` if an error occured.
|
|
2402
2400
|
"""
|
|
2403
2401
|
return self._getFileProperty( file=file, ext=ext, func=lambda x : datetime.datetime.fromtimestamp(os.path.getatime(x)) )
|
|
2404
2402
|
|
|
@@ -2470,6 +2468,75 @@ class SubDir(object):
|
|
|
2470
2468
|
os.rename(src_full, tar_full)
|
|
2471
2469
|
|
|
2472
2470
|
# utilities
|
|
2471
|
+
# ---------
|
|
2472
|
+
|
|
2473
|
+
def temp_file_name( self, file : str|None = None ):
|
|
2474
|
+
"""
|
|
2475
|
+
Returns a unique temporary file name.
|
|
2476
|
+
|
|
2477
|
+
The file name is generated by applying a unique hash
|
|
2478
|
+
to the current directory, ``file``, the current process and thread IDs, and
|
|
2479
|
+
:func:`datetime.datetime.now`.
|
|
2480
|
+
|
|
2481
|
+
If ``file`` is not ``None`` it will be used as a label.
|
|
2482
|
+
|
|
2483
|
+
This function returns just the file name. Use :meth:`cdxcore.subdir.SubDir.full_temp_file_name`
|
|
2484
|
+
to get a full temporary file name including path and extension.
|
|
2485
|
+
|
|
2486
|
+
Parameters
|
|
2487
|
+
----------
|
|
2488
|
+
file : str | None, default ``None``
|
|
2489
|
+
An optional file. If provided, :func:`cdxcore.uniquehash.named_unique_filename48_8`
|
|
2490
|
+
is used to generate the temporary file which means that a portion of ``file``
|
|
2491
|
+
will head the returned temporary name.
|
|
2492
|
+
|
|
2493
|
+
If ``file`` is ``None``, :func:`cdxcore.uniquehash.unique_hash48`
|
|
2494
|
+
is used to generate a 48 character hash.
|
|
2495
|
+
|
|
2496
|
+
Returns
|
|
2497
|
+
-------
|
|
2498
|
+
Temporary file name : str
|
|
2499
|
+
The file name.
|
|
2500
|
+
"""
|
|
2501
|
+
if file is None or file=="":
|
|
2502
|
+
return unique_hash48( str(self), file, uuid.getnode(), os.getpid(), threading.get_ident(), datetime.datetime.now() )
|
|
2503
|
+
else:
|
|
2504
|
+
return named_unique_filename48_8( file, str(self), uuid.getnode(), os.getpid(), threading.get_ident(), datetime.datetime.now() )
|
|
2505
|
+
|
|
2506
|
+
def full_temp_file_name(self, file : str|None = None, *, ext : str | None = None, create_directory : bool = False ):
|
|
2507
|
+
"""
|
|
2508
|
+
Returns a fully qualified unique temporary file name with path and extension
|
|
2509
|
+
|
|
2510
|
+
The file name is generated by applying a unique hash
|
|
2511
|
+
to the current directory, ``file``, the current process and thread IDs, and
|
|
2512
|
+
:func:`datetime.datetime.now`.
|
|
2513
|
+
|
|
2514
|
+
If ``file`` is not ``None`` it will be used as a label.
|
|
2515
|
+
|
|
2516
|
+
This function returns the fully qualified file name. Use :meth:`cdxcore.subdir.SubDir.temp_file_name`
|
|
2517
|
+
to only a file name.
|
|
2518
|
+
|
|
2519
|
+
Parameters
|
|
2520
|
+
----------
|
|
2521
|
+
file : str | None, default ``None``
|
|
2522
|
+
An optional file. If provided, :func:`cdxcore.uniquehash.named_unique_filename48_8`
|
|
2523
|
+
is used to generate the temporary file which means that a portion of ``file``
|
|
2524
|
+
will head the returned temporary name.
|
|
2525
|
+
|
|
2526
|
+
If ``file`` is ``None``, :func:`cdxcore.uniquehash.unique_hash48`
|
|
2527
|
+
is used to generate a 48 character hash.
|
|
2528
|
+
|
|
2529
|
+
ext : str | None, default ``None``
|
|
2530
|
+
Extension to use, or ``None`` for the extrension of ``self``.
|
|
2531
|
+
|
|
2532
|
+
Returns
|
|
2533
|
+
-------
|
|
2534
|
+
Temporary file name : str
|
|
2535
|
+
The fully qualified file name.
|
|
2536
|
+
"""
|
|
2537
|
+
if create_directory:
|
|
2538
|
+
self.create_directory()
|
|
2539
|
+
return self.full_file_name( self.temp_file_name(file), ext=ext )
|
|
2473
2540
|
|
|
2474
2541
|
@staticmethod
|
|
2475
2542
|
def remove_bad_file_characters( file : str, by : str="default" ) -> str:
|
|
@@ -2506,17 +2573,18 @@ class SubDir(object):
|
|
|
2506
2573
|
uqf = UniqueLabel( max_length=max_length-len_ext, id_length=id_length, separator=separator )
|
|
2507
2574
|
return uqf( unique_filename )
|
|
2508
2575
|
|
|
2509
|
-
#
|
|
2576
|
+
# object interface
|
|
2577
|
+
# ----------------
|
|
2510
2578
|
|
|
2511
2579
|
def __call__(self, element : str,
|
|
2512
2580
|
default = RETURN_SUB_DIRECTORY,
|
|
2513
2581
|
raise_on_error : bool = False,
|
|
2514
2582
|
*,
|
|
2515
|
-
version : str = None,
|
|
2516
|
-
ext : str = None,
|
|
2517
|
-
fmt : Format = None,
|
|
2583
|
+
version : str|None = None,
|
|
2584
|
+
ext : str|None = None,
|
|
2585
|
+
fmt : Format|None = None,
|
|
2518
2586
|
delete_wrong_version : bool = True,
|
|
2519
|
-
create_directory : bool = None ):
|
|
2587
|
+
create_directory : bool|None = None ):
|
|
2520
2588
|
"""
|
|
2521
2589
|
Read either data from a file, or return a new sub directory.
|
|
2522
2590
|
|
|
@@ -2556,20 +2624,18 @@ class SubDir(object):
|
|
|
2556
2624
|
If ``default`` is not specified, then this function returns a new sub-directory by calling
|
|
2557
2625
|
``SubDir(element,parent=self,ext=ext,fmt=fmt)``.
|
|
2558
2626
|
|
|
2559
|
-
create_directory : bool,
|
|
2627
|
+
create_directory : bool, default ``None``
|
|
2560
2628
|
*When creating sub-directories:*
|
|
2561
2629
|
|
|
2562
2630
|
Whether or not to instantly create the sub-directory. The default, ``None``, is to inherit the behaviour from ``self``.
|
|
2563
2631
|
|
|
2564
|
-
raise_on_error : bool,
|
|
2632
|
+
raise_on_error : bool, default ``False``
|
|
2565
2633
|
*When reading files:*
|
|
2566
2634
|
|
|
2567
2635
|
Whether to raise an exception if reading an existing file failed.
|
|
2568
2636
|
By default this function fails silently and returns ``default``.
|
|
2569
2637
|
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
version : str, optional
|
|
2638
|
+
version : str | None, default ``None``
|
|
2573
2639
|
*When reading files:*
|
|
2574
2640
|
|
|
2575
2641
|
If not ``None``, specifies the version of the current code base.
|
|
@@ -2581,17 +2647,13 @@ class SubDir(object):
|
|
|
2581
2647
|
Note that this is distinct
|
|
2582
2648
|
to using ``None`` which stipulates that the file should not
|
|
2583
2649
|
have version information.
|
|
2584
|
-
|
|
2585
|
-
Default is ``None``.
|
|
2586
2650
|
|
|
2587
|
-
delete_wrong_version : bool,
|
|
2651
|
+
delete_wrong_version : bool, default ``True``.
|
|
2588
2652
|
*When reading files:*
|
|
2589
2653
|
|
|
2590
2654
|
If ``True``, and if a wrong version was found, delete the file.
|
|
2591
2655
|
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
ext : str, optional
|
|
2656
|
+
ext : str | None, default is ``None``.
|
|
2595
2657
|
*When reading files:*
|
|
2596
2658
|
|
|
2597
2659
|
Extension to be used, or a list thereof if ``element`` is a list. Defaults
|
|
@@ -2606,11 +2668,8 @@ class SubDir(object):
|
|
|
2606
2668
|
*When creating sub-directories:*
|
|
2607
2669
|
|
|
2608
2670
|
Extension for the new subdirectory; set to ``None`` to inherit the parent's extension.
|
|
2609
|
-
|
|
2610
|
-
Default is ``None``.
|
|
2611
2671
|
|
|
2612
|
-
|
|
2613
|
-
fmt : :class:`cdxcore.subdir.Format`, optional
|
|
2672
|
+
fmt : :class:`cdxcore.subdir.Format` | None, default ``None``
|
|
2614
2673
|
*When reading files:*
|
|
2615
2674
|
|
|
2616
2675
|
File format or ``None`` to use the directory's default.
|
|
@@ -2622,12 +2681,10 @@ class SubDir(object):
|
|
|
2622
2681
|
*When creating sub-directories:*
|
|
2623
2682
|
|
|
2624
2683
|
Format for the new sub-directory; set to ``None`` to inherit the parent's format.
|
|
2625
|
-
|
|
2626
|
-
Default is ``None``.
|
|
2627
2684
|
|
|
2628
2685
|
Returns
|
|
2629
2686
|
-------
|
|
2630
|
-
Object : type|SubDir
|
|
2687
|
+
Object : type | SubDir
|
|
2631
2688
|
Either the value in the file, a new sub directory, or lists thereof.
|
|
2632
2689
|
"""
|
|
2633
2690
|
if default == SubDir.RETURN_SUB_DIRECTORY:
|
|
@@ -2671,7 +2728,7 @@ class SubDir(object):
|
|
|
2671
2728
|
""" Tests whether ``file`` :meth:`cdxcore.subdir.SubDir.exists`. """
|
|
2672
2729
|
return self.exists(file)
|
|
2673
2730
|
|
|
2674
|
-
def items(self, *, ext : str = None, raise_on_error : bool = False) -> Iterable:
|
|
2731
|
+
def items(self, *, ext : str|None = None, raise_on_error : bool = False) -> Iterable:
|
|
2675
2732
|
"""
|
|
2676
2733
|
Dictionary-style iterable of filenames and their content.
|
|
2677
2734
|
|
|
@@ -2683,7 +2740,7 @@ class SubDir(object):
|
|
|
2683
2740
|
|
|
2684
2741
|
Parameters
|
|
2685
2742
|
----------
|
|
2686
|
-
ext : str
|
|
2743
|
+
ext : str | None, default ``None``
|
|
2687
2744
|
Extension or ``None`` for the directory's current extension. Use ``""``
|
|
2688
2745
|
for all file extension.
|
|
2689
2746
|
|
|
@@ -2741,7 +2798,6 @@ class SubDir(object):
|
|
|
2741
2798
|
raise LookupError(f"Unknown format name '{format_name}'. Must be one of: {fmt_list(SubDir.FORMAT_NAMES)}")
|
|
2742
2799
|
return Format[format_name]
|
|
2743
2800
|
|
|
2744
|
-
|
|
2745
2801
|
# caching
|
|
2746
2802
|
# -------
|
|
2747
2803
|
|
|
@@ -3322,8 +3378,8 @@ class SubDir(object):
|
|
|
3322
3378
|
# ========================================================================
|
|
3323
3379
|
|
|
3324
3380
|
def VersionedCacheRoot( directory : str, *,
|
|
3325
|
-
ext : str = None,
|
|
3326
|
-
fmt : Format = None,
|
|
3381
|
+
ext : str|None = None,
|
|
3382
|
+
fmt : Format|None = None,
|
|
3327
3383
|
create_directory : bool = False,
|
|
3328
3384
|
**controller_kwargs
|
|
3329
3385
|
):
|
|
@@ -3355,43 +3411,43 @@ def VersionedCacheRoot( directory : str, *,
|
|
|
3355
3411
|
|
|
3356
3412
|
Parameters
|
|
3357
3413
|
----------
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
* ``"!/dir"`` creates ``dir`` in the temporary directory.
|
|
3364
|
-
* ``"~/dir"`` creates ``dir`` in the home directory.
|
|
3365
|
-
* ``"./dir"`` creates ``dir`` relative to the current directory.
|
|
3366
|
-
|
|
3367
|
-
ext : str
|
|
3368
|
-
Extension, which will automatically be appended to file names.
|
|
3369
|
-
The default value depends on ``fmt`; for ``Format.PICKLE`` it is "pck".
|
|
3414
|
+
directory : str
|
|
3415
|
+
Name of the root directory for caching.
|
|
3416
|
+
|
|
3417
|
+
Using SubDir the following Short-cuts are supported:
|
|
3370
3418
|
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3419
|
+
* ``"!/dir"`` creates ``dir`` in the temporary directory.
|
|
3420
|
+
* ``"~/dir"`` creates ``dir`` in the home directory.
|
|
3421
|
+
* ``"./dir"`` creates ``dir`` relative to the current directory.
|
|
3422
|
+
|
|
3423
|
+
ext : str | None, default ``None``
|
|
3424
|
+
Extension, which will automatically be appended to file names.
|
|
3425
|
+
The default value depends on ``fmt`; for ``Format.PICKLE`` it is "pck".
|
|
3426
|
+
|
|
3427
|
+
fmt : :class:`cdxcore.subdir.Format` | None, default ``None``
|
|
3428
|
+
File format; if ``ext`` is not specified, the format drives the extension, too.
|
|
3429
|
+
The default ``None`` becomes ``Format.PICKLE``.
|
|
3374
3430
|
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
* ``exclude_arg_types``: list of types or names of types to exclude when auto-generating function
|
|
3384
|
-
signatures from function arguments.
|
|
3385
|
-
An example is :class:`cdxcore.verbose.Context` which is used to print progress messages.
|
|
3386
|
-
|
|
3387
|
-
* ``max_filename_length``: maximum filename length.
|
|
3431
|
+
create_directory : bool, default ``False``
|
|
3432
|
+
Whether to create the directory upon creation.
|
|
3433
|
+
|
|
3434
|
+
controller_kwargs: dict
|
|
3435
|
+
Parameters passed to :class:`cdxcore.subdir.CacheController``.
|
|
3436
|
+
|
|
3437
|
+
Common parameters used:
|
|
3388
3438
|
|
|
3389
|
-
|
|
3439
|
+
* ``exclude_arg_types``: list of types or names of types to exclude when auto-generating function
|
|
3440
|
+
signatures from function arguments.
|
|
3441
|
+
An example is :class:`cdxcore.verbose.Context` which is used to print progress messages.
|
|
3442
|
+
|
|
3443
|
+
* ``max_filename_length``: maximum filename length.
|
|
3444
|
+
|
|
3445
|
+
* ``hash_length``: length used for hashes, see :class:`cdxcore.uniquehash.UniqueHash`.
|
|
3390
3446
|
|
|
3391
3447
|
Returns
|
|
3392
3448
|
-------
|
|
3393
|
-
|
|
3394
|
-
|
|
3449
|
+
Root : :class:`cdxcore.subdir.SubDir`
|
|
3450
|
+
A root directory suitable for caching.
|
|
3395
3451
|
"""
|
|
3396
3452
|
controller = CacheController(**controller_kwargs) if len(controller_kwargs) > 0 else None
|
|
3397
3453
|
return SubDir( directory, ext=ext, fmt=fmt, create_directory=create_directory, cache_controller=controller )
|