Skip to content

Commit

Permalink
Merge pull request pepkit#3 from pepkit/dev
Browse files Browse the repository at this point in the history
Return instance on add_entries; test coverage
  • Loading branch information
vreuter committed Feb 5, 2019
2 parents 2e81333 + fc66a76 commit 257e929
Show file tree
Hide file tree
Showing 9 changed files with 512 additions and 31 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,10 @@
# Changelog

## [0.1.5] - 2019-02-05
### Changed
- `add_entries` method on an `AttMapLike` now returns the instance.
- Improve test coverage

## [0.1.4] - 2019-02-05
### Changed
- Removed support for Python 3.4
Expand Down
16 changes: 15 additions & 1 deletion attmap/_att_map_like.py
Expand Up @@ -77,7 +77,8 @@ def __len__(self):
return sum(1 for _ in iter(self))

def __repr__(self):
return repr({k: v for k, v in self.__dict__.items()})
return repr({k: v for k, v in self.__dict__.items()
if not self._omit_from_repr(k, cls=self.__class__)})

def __str__(self):
return "{}: {}".format(self.__class__.__name__, repr(self))
Expand All @@ -104,6 +105,7 @@ def add_entries(self, entries):
# Assume we now have pairs; allow corner cases to fail hard here.
for key, value in entries_iter:
self.__setitem__(key, value)
return self

def is_null(self, item):
"""
Expand All @@ -122,3 +124,15 @@ def non_null(self, item):
:return bool: True iff the item is present and has non-null value
"""
return item in self and self[item] is not None

@staticmethod
def _omit_from_repr(k, cls):
"""
Hook for exclusion of particular value from a representation
:param hashable k: key to consider for omission
:param type cls: data type on which to base the exclusion
:return bool: whether the given key k should be omitted from
text representation
"""
return False
2 changes: 1 addition & 1 deletion attmap/_version.py
@@ -1,2 +1,2 @@
__version__ = "0.1.4"
__version__ = "0.1.5"

32 changes: 3 additions & 29 deletions attmap/attmap.py
Expand Up @@ -69,10 +69,9 @@ def __setitem__(self, key, value):
# TODO: consider enforcement of type constraint, that value of different
# type may not overwrite existing.
if isinstance(value, Mapping) and not isinstance(value, self.__class__):
cls = self.__class__
val = cls.__new__(cls)
val.__init__(value)
self.__dict__[key] = val
v = self.__class__.__new__(self.__class__)
v.__init__(value)
self.__dict__[key] = v
else:
self.__dict__[key] = value

Expand All @@ -85,30 +84,5 @@ def __getitem__(self, item):
# __getitem__ syntax, not attribute-access syntax.
raise KeyError(item)

def __repr__(self):
return repr({k: v for k, v in self.__dict__.items()
if self._include_in_repr(k, klazz=self.__class__)})

def __str__(self):
return "{}: {}".format(self.__class__.__name__, repr(self))

@staticmethod
def _include_in_repr(attr, klazz):
"""
Determine whether to include attribute in an object's text representation.
:param str attr: attribute to include/exclude from object's representation
:param str | type klazz: name of type or type itself of which the object
to be represented is an instance
:return bool: whether to include attribute in an object's
text representation
"""
# TODO: localize to peppy and subclass AttMap there for Project.
exclusions_by_class = {
"Project": ["_samples", "sample_subannotation",
"sheet", "interfaces_by_protocol"],
"Subsample": ["sheet", "sample", "merged_cols"],
"Sample": ["sheet", "prj", "merged_cols"]
}
classname = klazz.__name__ if isinstance(klazz, type) else klazz
return attr not in exclusions_by_class.get(classname, [])
File renamed without changes.
2 changes: 2 additions & 0 deletions requirements/requirements-dev.txt
@@ -1,3 +1,5 @@
hypothesis
mock>=2.0.0
pytest>=3.0.7
pyyaml>=3.12

1 change: 1 addition & 0 deletions tests/conftest.py
@@ -1,3 +1,4 @@
""" Fixtures and values shared among project's various test suites """

from attmap import *
import pytest
Expand Down
11 changes: 11 additions & 0 deletions tests/helpers.py
@@ -1,5 +1,6 @@
""" Helper functions for tests """

import math
import random
import string
from attmap._att_map_like import AttMapLike
Expand All @@ -18,6 +19,16 @@
]


def assert_entirely_equal(observed, expected):
""" Accommodate equality assertion for varied data, including NaN. """
try:
assert observed == expected
except AssertionError:
assert math.isnan(observed) and math.isnan(expected)
except ValueError:
assert (observed == expected).all()


def get_att_map(cls, entries=None):
""" Create a fresh, empty data object. """
assert issubclass(cls, AttMapLike)
Expand Down

0 comments on commit 257e929

Please sign in to comment.