Skip to content

Commit

Permalink
fix: tests
Browse files Browse the repository at this point in the history
  • Loading branch information
thorwhalen committed Nov 15, 2023
1 parent 356bab8 commit 34b4d78
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 21 deletions.
7 changes: 5 additions & 2 deletions dol/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ def ihead(store, n=1):

from dol.kv_codecs import ValueCodecs, KeyCodecs

from dol.filesys import (
PickleFiles, # CRUD access to pickled files
JsonFiles, # CRUD access to jsob files
)

from dol.base import (
Collection, # base class for collections (adds to collections.abc.Collection)
MappingViewMixin,
Expand Down Expand Up @@ -74,8 +79,6 @@ def ihead(store, n=1):
resolve_dir, # to get a full path (resolve ~ and .) and ensure it is a directory
DirReader, # recursive read-only access to directories,
temp_dir, # make a temporary directory
PickleFiles, # CRUD access to pickled files
JsonFiles, # CRUD access to jsob files
)

from dol.util import (
Expand Down
24 changes: 16 additions & 8 deletions dol/filesys.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,10 @@ def is_valid_key(self, k):
return bool(self._key_pattern.match(k))

def validate_key(
self, k, err_msg_format=_dflt_not_valid_error_msg, err_type=KeyValidationError,
self,
k,
err_msg_format=_dflt_not_valid_error_msg,
err_type=KeyValidationError,
):
if not self.is_valid_key(k):
raise err_type(err_msg_format.format(k))
Expand Down Expand Up @@ -424,20 +427,25 @@ class TextFiles(FileStringPersister):


# ------------------------------------ misc --------------------------------------------
from dol.kv_codecs import ValueCodecs
import pickle
import json

# TODO: Want to replace with use of ValueCodecs but need to resolve circular imports
pickle_bytes_wrap = wrap_kvs(obj_of_data=pickle.loads, data_of_obj=pickle.dumps)
json_bytes_wrap = wrap_kvs(obj_of_data=json.loads, data_of_obj=json.dumps)


@ValueCodecs.pickle
class PickleFiles(Files):
@pickle_bytes_wrap
class PickleFiles(TextFiles):
"""A store of pickles"""


@ValueCodecs.json
class JsonFiles(Files):
"""A store of json"""
@pickle_bytes_wrap
class JsonFiles(TextFiles):
"""A store of pickles"""


PickleStore = PickleFiles # backcompatibility alias
PickleStore = PickleFiles # back-compatibility alias


# @wrap_kvs(key_of_id=lambda x: x[:-1], id_of_key=lambda x: x + path_sep)
Expand Down
11 changes: 6 additions & 5 deletions dol/kv_codecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def csv_decode(string, *args, **kwargs):

@__csv_dict_sig
def csv_dict_encode(string, *args, **kwargs):
"""Encode a list of dicts into a csv string.
r"""Encode a list of dicts into a csv string.
>>> data = [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}]
>>> encoded = csv_dict_encode(data, fieldnames=['a', 'b'])
Expand Down Expand Up @@ -308,12 +308,13 @@ def is_value_codec(attr_val):
import quopri, plistlib

quopri: Codec[bytes, bytes] = value_wrap(quopri.encodestring, quopri.decodestring)
# plistlib: Codec[bytes, bytes] = value_wrap(plistlib.dumps, plistlib.loads)

xml_etree: Codec['xml.etree.ElementTree', bytes] = value_wrap(
_xml_tree_encode, _xml_tree_decode
plistlib: Codec[bytes, bytes] = value_wrap(
plistlib.dumps, plistlib.loads, exclude=('fmt',)
)

# Any is really xml.etree.ElementTree.Element, but didn't want to import
xml_etree: Codec[Any, bytes] = value_wrap(_xml_tree_encode, _xml_tree_decode)


class KeyCodecs:
"""
Expand Down
29 changes: 23 additions & 6 deletions dol/signatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
cached_property,
update_wrapper,
partial,
partialmethod,
WRAPPER_ASSIGNMENTS,
wraps as _wraps,
update_wrapper as _update_wrapper,
Expand Down Expand Up @@ -253,7 +254,9 @@ def name_of_obj(
caught_exceptions=caught_exceptions,
default_factory=default_factory,
)
if isinstance(o, (cached_property, partial)) and hasattr(o, 'func'):
if isinstance(o, (cached_property, partial, partialmethod)) and hasattr(
o, 'func'
):
return name_of_obj(o.func, **kwargs)
elif isinstance(o, property) and hasattr(o, 'fget'):
return name_of_obj(o.fget, **kwargs)
Expand Down Expand Up @@ -634,7 +637,10 @@ def extract_arguments(

if include_all_when_var_keywords_in_params:
if (
next((p.name for p in params if p.kind == Parameter.VAR_KEYWORD), None,)
next(
(p.name for p in params if p.kind == Parameter.VAR_KEYWORD),
None,
)
is not None
):
param_kwargs.update(remaining_kwargs)
Expand Down Expand Up @@ -3951,7 +3957,7 @@ def resolve_function(obj: T) -> Union[T, Callable]:
return obj.func
elif isinstance(obj, property):
return obj.fget
elif isinstance(obj, partial):
elif isinstance(obj, (partial, partialmethod)):
return obj.func
elif not callable(obj) and callable(wrapped := getattr(obj, '__wrapped__', None)):
# If obj is not callable, but has a __wrapped__ attribute that is, return that
Expand Down Expand Up @@ -4187,6 +4193,9 @@ def partial(func: Callable, *args, **keywords) -> Callable:
"""``partial(func, *args, **keywords)`` - new function with partial application
of the given arguments and keywords."""

def partialmethod(func: Callable, *args, **keywords) -> Callable:
"""``functools.partialmethod(func, *args, **keywords)``"""


# Merge sigs_for_builtin_modules and sigs_for_builtins
sigs_for_sigless_builtin_name = dict(sigs_for_builtin_modules, **sigs_for_builtins)
Expand Down Expand Up @@ -4253,7 +4262,9 @@ def param_for_kind(
lower_kind = kind.lower()
setattr(param_for_kind, lower_kind, partial(param_for_kind, kind=kind))
setattr(
param_for_kind, 'with_default', partial(param_for_kind, with_default=True),
param_for_kind,
'with_default',
partial(param_for_kind, with_default=True),
)
setattr(
getattr(param_for_kind, lower_kind),
Expand Down Expand Up @@ -4307,7 +4318,10 @@ def mk_func_comparator_based_on_signature_comparator(


def _keyed_comparator(
comparator: Comparator, key: KeyFunction, x: CT, y: CT,
comparator: Comparator,
key: KeyFunction,
x: CT,
y: CT,
) -> Comparison:
"""Apply a comparator after transforming inputs through a key function.
Expand All @@ -4321,7 +4335,10 @@ def _keyed_comparator(
return comparator(key(x), key(y))


def keyed_comparator(comparator: Comparator, key: KeyFunction,) -> Comparator:
def keyed_comparator(
comparator: Comparator,
key: KeyFunction,
) -> Comparator:
"""Create a key-function enabled binary operator.
In various places in python functionality is extended by allowing a key function.
Expand Down
2 changes: 2 additions & 0 deletions dol/tests/test_kv_codecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ def test_value_codecs():
)

_test_codec(ValueCodecs.codecs(), 'hello', b'hello')
# _test_codec(ValueCodecs.plistlib, {'a': 1, 'b': 2}, b'<?xml version="1.0" ...')


_test_codec(
ValueCodecs.csv(), [['a', 'b', 'c'], ['1', '2', '3']], 'a,b,c\r\n1,2,3\r\n'
Expand Down
2 changes: 2 additions & 0 deletions dol/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
from dol.base import Store
from dol.trans import store_decorator


NoSuchKey = type('NoSuchKey', (), {})


# ------------ useful trans functions to be used with wrap_kvs etc. ---------------------
# TODO: Consider typing or decorating functions to indicate their role (e.g. id_of_key,
# key_of_id, data_of_obj, obj_of_data, preset, postget...)
Expand Down

0 comments on commit 34b4d78

Please sign in to comment.