Skip to content

Commit

Permalink
Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
akatrevorjay committed Dec 29, 2018
1 parent 14761d7 commit 8c7be0a
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
omit =
*/tests/*
*/test_*.py

pytutils/lazy/*.py
1 change: 1 addition & 0 deletions pytutils/lazy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
What's here is not mine, I have lost track of where it's from, but it would be a GPL'd library on github.
104 changes: 86 additions & 18 deletions pytutils/mappings.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import collections
import re
import os
import re

import six

from .props import classproperty


class AttrDict(dict):
"""
Expand All @@ -19,7 +21,30 @@ def __init__(self, *args, **kwargs):


class ProxyMutableMapping(collections.MutableMapping):
"""Proxies access to an existing dict-like object."""
"""
Proxies access to an existing dict-like object.
>>> a = dict(whoa=True, hello=[1,2,3], why='always')
>>> b = ProxyMutableAttrDict(a)
Nice reprs:
>>> b
<ProxyMutableAttrDict {'whoa': True, 'hello': [1, 2, 3], 'why': 'always'}>
Setting works as you'd expect:
>>> b['nice'] = False
>>> b['whoa'] = 'yeee'
>>> b
<ProxyMutableAttrDict {'whoa': 'yeee', 'hello': [1, 2, 3], 'why': 'always', 'nice': False}>
Checking that the changes are in fact being performed on the proxied object:
>>> a
{'whoa': 'yeee', 'hello': [1, 2, 3], 'why': 'always', 'nice': False}
"""

def __init__(self, mapping, fancy_repr=True, dictify_repr=False):
"""
Expand Down Expand Up @@ -65,6 +90,11 @@ def __len__(self):


class HookableProxyMutableMapping(ProxyMutableMapping):
def __init__(self, mapping, fancy_repr=True, dictify_repr=False):
self.__mapping = mapping

super(HookableProxyMutableMapping, self).__init__(mapping, fancy_repr=fancy_repr, dictify_repr=dictify_repr)

def __key_trans__(self, key, store=False, get=False, contains=False, delete=False):
return key

Expand Down Expand Up @@ -227,10 +257,58 @@ def format_dict_recursively(
return ret


class ProxyMutableAttrDict(dict):
@property
def _wrap_as(self):
return self.__class__
class ProxyMutableAttrDict(ProxyMutableMapping):
"""
Proxies mutable access to another mapping and allows for attribute-style access.
>>> a = dict(whoa=True, hello=[1,2,3], why='always')
>>> b = ProxyMutableAttrDict(a)
Nice reprs:
>>> b
<ProxyMutableAttrDict {'whoa': True, 'hello': [1, 2, 3], 'why': 'always'}>
Setting works as you'd expect:
>>> b['nice'] = False
>>> b['whoa'] = 'yeee'
>>> b
<ProxyMutableAttrDict {'whoa': 'yeee', 'hello': [1, 2, 3], 'why': 'always', 'nice': False}>
Checking that the changes are in fact being performed on the proxied object:
>>> a
{'whoa': 'yeee', 'hello': [1, 2, 3], 'why': 'always', 'nice': False}
Attribute style access:
>>> b.whoa
'yeee'
>>> b.state = 'new'
>>> b
<ProxyMutableAttrDict {'whoa': 'yeee', 'hello': [1, 2, 3], 'why': 'always', 'nice': False, 'state': 'new'}>
Recursion is handled:
>>> b.subdict = dict(test=True)
>>> b.subdict.test
True
>>> b
<ProxyMutableAttrDict {'whoa': 'yeee', 'hello': [1, 2, 3], 'why': 'always', 'nice': False, 'state': 'new',
'subdict': <ProxyMutableAttrDict {'test': True}>}>
"""

def __init__(self, mapping, fancy_repr=True, dictify_repr=False, recursion=True):
self.__recursion = recursion
self.__mapping = mapping

super(ProxyMutableAttrDict, self).__init__(mapping, fancy_repr=fancy_repr, dictify_repr=dictify_repr)

@classproperty
def _wrap_as(cls):
return cls

def __getattr__(self, key):
if not key.startswith('_'):
Expand All @@ -243,7 +321,7 @@ def __getattr__(self, key):

def __setattr__(self, key, value):
if not key.startswith('_'):
if isinstance(value, collections.Mapping) and not isinstance(value, self._wrap_as):
if self.__recursion and isinstance(value, collections.Mapping) and not isinstance(value, self._wrap_as):
value = self.__class__(value)

try:
Expand All @@ -255,17 +333,7 @@ def __setattr__(self, key, value):
return super(ProxyMutableAttrDict, self).__setattr__(key, value)


class RecursiveProxyAttrDict(ProxyMutableMapping):
__getattr__ = ProxyMutableMapping.__getitem__
__setattr__ = ProxyMutableMapping.__setitem__

def __getitem__(self, name):
val = self.__getitem__(name)

if isinstance(val, collections.Mapping) and not isinstance(val, self.__class__):
val = self.__class__(val)

raise AttributeError(name)
RecursiveProxyAttrDict = ProxyMutableAttrDict


class ProcessLocal(HookableProxyMutableMapping):
Expand Down

0 comments on commit 8c7be0a

Please sign in to comment.