Skip to content

Commit 3c87ae9

Browse files
committed
Simplify AttrDict and create a separated Settings class
1 parent de1943f commit 3c87ae9

File tree

3 files changed

+32
-34
lines changed

3 files changed

+32
-34
lines changed

dill/_utils.py

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,8 @@
1111
import logging
1212
logger = logging.getLogger('dill._utils')
1313

14-
import inspect
15-
from functools import partialmethod
16-
1714
class AttrDict(dict):
1815
"""syntactic sugar for accessing dictionary items"""
19-
_CAST = object() # singleton
20-
def __init__(self, *args, **kwargs):
21-
data = args[0] if len(args) == 2 and args[1] is self._CAST else dict(*args, **kwargs)
22-
for key, val in tuple(data.items()):
23-
if isinstance(val, dict) and not isinstance(val, AttrDict):
24-
data[key] = AttrDict(val, self._CAST)
25-
super().__setattr__('_data', data)
2616
def _check_attr(self, name):
2717
try:
2818
super().__getattribute__(name)
@@ -33,33 +23,17 @@ def _check_attr(self, name):
3323
def __getattr__(self, key):
3424
# This is called only if dict.__getattribute__(key) fails.
3525
try:
36-
return self._data[key]
26+
return self[key]
3727
except KeyError:
3828
raise AttributeError("'AttrDict' object has no attribute %r" % key)
3929
def __setattr__(self, key, value):
4030
self._check_attr(key)
41-
if isinstance(value, dict):
42-
self._data[key] = AttrDict(value, self._CAST)
43-
else:
44-
self._data[key] = value
31+
self[key] = value
4532
def __delattr__(self, key):
4633
self._check_attr(key)
47-
del self._data[key]
48-
def __proxy__(self, method, *args, **kwargs):
49-
return getattr(self._data, method)(*args, **kwargs)
34+
del self[key]
5035
def __reduce__(self):
51-
return AttrDict, (self._data,)
52-
def copy(self):
53-
# Deep copy.
54-
copy = AttrDict(self._data)
55-
for key, val in tuple(copy.items()):
56-
if isinstance(val, AttrDict):
57-
copy[key] = val.copy()
58-
return copy
59-
60-
for method, _ in inspect.getmembers(dict, inspect.ismethoddescriptor):
61-
if method not in vars(AttrDict) and method not in {'__getattribute__', '__reduce_ex__'}:
62-
setattr(AttrDict, method, partialmethod(AttrDict.__proxy__, method))
36+
return type(self), (dict(self),)
6337

6438

6539
### Namespace filtering

dill/session.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,6 @@ def dump_session(filename: Union[PathLike, BytesIO] = '/tmp/session.pkl',
138138
#NOTE: *must* run before _filter_objects()
139139
main = _stash_modules(main)
140140
main = _filter_objects(main, exclude, include, obj=original_main)
141-
142-
print(list(vars(main)))
143-
144141
if hasattr(filename, 'write'):
145142
f = filename
146143
else:

dill/settings.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,34 @@
1515
from pickle import DEFAULT_PROTOCOL
1616
except ImportError:
1717
from pickle import HIGHEST_PROTOCOL as DEFAULT_PROTOCOL
18-
from ._utils import AttrDict as Settings, ExcludeRules
18+
from collections.abc import MutableMapping
19+
from ._utils import AttrDict, ExcludeRules
20+
21+
class Settings(AttrDict):
22+
"""allow multiple level attribute access"""
23+
def __init__(self, *args, **kwargs):
24+
super().__init__(*args, **kwargs)
25+
for key, value in tuple(self.items()):
26+
if isinstance(value, MutableMapping):
27+
self[key] = Settings(value)
28+
@staticmethod
29+
def _cast_dict(obj):
30+
return Settings(obj) if isinstance(obj, MutableMapping) else obj
31+
def __setitem__(self, key, value):
32+
super().__setitem__(key, self._cast_dict(value))
33+
def setdefault(self, key, default=None):
34+
super().setdefault(key, self._cast_dict(default))
35+
def update(self, *args, **kwargs):
36+
super().update(Settings(*args, **kwargs))
37+
def __setattr__(self, key, value):
38+
super().__setattr__(key, _cast_dict(value))
39+
def copy(self):
40+
# Deep copy.
41+
copy = Settings(self)
42+
for key, value in self.items():
43+
if isinstance(value, Settings):
44+
copy[key] = value.copy()
45+
return copy
1946

2047
settings = Settings({
2148
#'main' : None,

0 commit comments

Comments
 (0)