Repository: glotzerlab/signac
Pull request #183 (2019-05-06 20:56:37)

Move repr from JSONDict to _SyncedDict.
## Description
We define `__repr__` for `JSONDict` but not its parent `SyncedAttrDict` or its parent `_SyncedDict`:
```python
def __repr__(self):
    return repr(self())
```

## Motivation and Context
When I am in the REPL, the statepoint representation is currently not helpful but the document representation is helpful:
```python
>>> job.sp  # is a SyncedAttrDict
<signac.core.attrdict.SyncedAttrDict object at 0x10b858cc0>
>>> job.doc  # is a JSONDict
{'IBZ_sphericity': 0.5235987755982993, ...}
```

## Types of Changes
- [x] Bug fix
- [x] Breaking change<sup>1</sup>

<sup>1</sup>The change breaks (or has the potential to break) existing functionality.

## Checklist:
<!-- Please select all items that apply either now or after creating the pull request. -->
<!-- If you are unsure about any of these items, do not hesitate to ask! -->
- [x] I am familiar with the [**Contributing Guidelines**](https://github.com/glotzerlab/signac/blob/master/CONTRIBUTING.md).
- [x] I agree with the terms of the [**Contributor Agreement**](https://github.com/glotzerlab/signac/blob/master/ContributorAgreement.md).
- [x] My name is on the [list of contributors](https://github.com/glotzerlab/signac/blob/master/contributors.txt).
- [x] My code follows the [code style guideline](https://github.com/glotzerlab/signac/blob/master/CONTRIBUTING.md#code-style) of this project.
- [x] The changes introduced by this pull request are covered by existing or newly introduced tests.

If necessary:
- [x] I have updated the [changelog](https://github.com/glotzerlab/signac/blob/master/changelog.txt).


codecov[bot]: # [Codecov](https://codecov.io/gh/glotzerlab/signac/pull/183?src=pr&el=h1) Report
> Merging [#183](https://codecov.io/gh/glotzerlab/signac/pull/183?src=pr&el=desc) into [master](https://codecov.io/gh/glotzerlab/signac/commit/ee29e4769fec61d04bfbf5ad34ce5ec6f549fd4d?src=pr&el=desc) will **increase** coverage by `0.03%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/glotzerlab/signac/pull/183/graphs/tree.svg?width=650&token=FghbjTyzgM&height=150&src=pr)](https://codecov.io/gh/glotzerlab/signac/pull/183?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #183      +/-   ##
==========================================
+ Coverage   64.99%   65.03%   +0.03%     
==========================================
  Files          37       37              
  Lines        5531     5531              
==========================================
+ Hits         3595     3597       +2     
+ Misses       1936     1934       -2
```


| [Impacted Files](https://codecov.io/gh/glotzerlab/signac/pull/183?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [signac/core/jsondict.py](https://codecov.io/gh/glotzerlab/signac/pull/183/diff?src=pr&el=tree#diff-c2lnbmFjL2NvcmUvanNvbmRpY3QucHk=) | `95.09% <ø> (+1.15%)` | :arrow_up: |
| [signac/core/synceddict.py](https://codecov.io/gh/glotzerlab/signac/pull/183/diff?src=pr&el=tree#diff-c2lnbmFjL2NvcmUvc3luY2VkZGljdC5weQ==) | `95.65% <100%> (+0.04%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/glotzerlab/signac/pull/183?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/glotzerlab/signac/pull/183?src=pr&el=footer). Last update [ee29e47...c263421](https://codecov.io/gh/glotzerlab/signac/pull/183?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/changelog.txt b/changelog.txt
index c7caa002..3b5d7f38 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -23,6 +23,7 @@ next
  - Fix: Searches for whole numbers will match all numerically matching integers regardless of whether they are stored as decimals or whole numbers (#169).
  - Fix: Passing an instance of dict to `H5Store.setdefault()` will return an instance of `H5Group` instead of a dict (#180).
  - Improve the representation (return value of `repr()`) of instances of `H5Group`.
+ - Improve the representation (return value of `repr()`) of instances of `SyncedAttrDict`.
 
 
 [1.0.0] -- 2019-02-28
diff --git a/signac/core/jsondict.py b/signac/core/jsondict.py
index 4381a39d..b2146692 100644
--- a/signac/core/jsondict.py
+++ b/signac/core/jsondict.py
@@ -297,9 +297,6 @@ class JSONDict(SyncedAttrDict):
                 with open(self._filename, 'wb') as file:
                     file.write(blob)
 
-    def __repr__(self):
-        return repr(self())
-
     @contextmanager
     def buffered(self):
         buffered_dict = BufferedSyncedAttrDict(self, parent=self)
diff --git a/signac/core/synceddict.py b/signac/core/synceddict.py
index 2546fe6a..6dad2f97 100644
--- a/signac/core/synceddict.py
+++ b/signac/core/synceddict.py
@@ -257,6 +257,9 @@ class _SyncedDict(MutableMapping):
         self._synced_load()
         return self._convert_to_dict(self._data).items()
 
+    def __repr__(self):
+        return repr(self())
+
     def __str__(self):
         return str(self())
 


Test patch:
diff --git a/tests/test_synced_attrdict.py b/tests/test_synced_attrdict.py
index 71956e4f..75d6d359 100644
--- a/tests/test_synced_attrdict.py
+++ b/tests/test_synced_attrdict.py
@@ -90,7 +90,11 @@ class SyncedAttrDictTest(unittest.TestCase):
 
     def test_repr(self):
         sad = self.get_sad()
-        repr(sad)
+        self.assertEqual(repr(sad), repr(dict(sad())))
+        sad['a'] = 0
+        self.assertEqual(repr(sad), repr(dict(sad())))
+        sad['a'] = {'b': 0}
+        self.assertEqual(repr(sad), repr(dict(sad())))
 
     def test_call(self):
         sad = self.get_sad()