Skip to content

Commit

Permalink
Merge pull request #76 from pepkit/dev
Browse files Browse the repository at this point in the history
v0.13.1
  • Loading branch information
nsheff authored Nov 5, 2021
2 parents c2360d1 + c4fc790 commit b2c80a6
Show file tree
Hide file tree
Showing 40 changed files with 916 additions and 518 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/black.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: Lint

on: [pull_request]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: psf/black@stable
21 changes: 21 additions & 0 deletions .github/workflows/run-codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Run codecov

on:
pull_request:
branches: [master]

jobs:
pytest:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: [3.9]
os: [ubuntu-latest]

steps:
- uses: actions/checkout@v2
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2
with:
file: ./coverage.xml
name: py-${{ matrix.python-version }}-${{ matrix.os }}
35 changes: 35 additions & 0 deletions .github/workflows/run-pytest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Run pytests

on:
push:
branches: [dev]
pull_request:
branches: [master]

jobs:
pytest:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: [3.6, 3.9]
os: [ubuntu-latest]

steps:
- uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Install dev dependencies
run: if [ -f requirements/requirements-dev.txt ]; then pip install -r requirements/requirements-dev.txt; fi

- name: Install test dependencies
run: if [ -f requirements/requirements-test.txt ]; then pip install -r requirements/requirements-test.txt; fi

- name: Install attmap
run: python -m pip install .

- name: Run pytest tests
run: pytest tests --cov=./ --cov-report=xml
16 changes: 8 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ doc/build/*
# generic ignore list:
*.lst

# Compiled source
# Compiled source
*.com
*.class
*.dll
*.exe
*.o
*.so
*.pyc
# Packages

# Packages
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
Expand All @@ -36,13 +36,13 @@ doc/build/*
*.rar
*.tar
*.zip
# Logs and databases

# Logs and databases
*.log
*.sql
*.sqlite
# OS generated files

# OS generated files
.DS_Store
.DS_Store?
._*
Expand All @@ -51,7 +51,7 @@ doc/build/*
ehthumbs.db
Thumbs.db

# Gedit temporary files
# Gedit temporary files
*~

# libreoffice lock files:
Expand Down
21 changes: 21 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
hooks:
- id: trailing-whitespace
- id: check-yaml
- id: end-of-file-fixer
- id: requirements-txt-fixer
- id: trailing-whitespace
- id: check-ast

- repo: https://github.com/PyCQA/isort
rev: 5.8.0
hooks:
- id: isort
args: ["--profile", "black"]

- repo: https://github.com/psf/black
rev: 21.5b2
hooks:
- id: black
20 changes: 0 additions & 20 deletions .travis.yml

This file was deleted.

2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
include requirements/*
include README.md
include LICENSE.txt
include LICENSE.txt
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@
Key-value Mapping supporting nesting and attribute-style access

Originally motivated by and designed for the [pepkit family projects](https://pepkit.github.io/).

24 changes: 17 additions & 7 deletions attmap/__init__.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
""" Package-scope definitions """

from ._att_map_like import AttMapLike
from ._version import __version__
from .attmap import AttMap
from .attmap_echo import *
from .helpers import *
from .ordattmap import OrdAttMap
from .pathex_attmap import PathExAttMap
from ._version import __version__

AttributeDict = AttMap
AttributeDictEcho = AttMapEcho

__all__ = ["AttMapLike", "AttMap", "AttMapEcho", "AttributeDict",
"AttributeDictEcho", "EchoAttMap", "OrdAttMap", "PathExAttMap",
"get_data_lines"]
__aliases__ = {"AttMap": ["AttributeDict"],
"AttMapEcho": ["AttributeDictEcho"],
"EchoAttMap": ["AttMapEcho"]}
__all__ = [
"AttMapLike",
"AttMap",
"AttMapEcho",
"AttributeDict",
"AttributeDictEcho",
"EchoAttMap",
"OrdAttMap",
"PathExAttMap",
"get_data_lines",
]
__aliases__ = {
"AttMap": ["AttributeDict"],
"AttMapEcho": ["AttributeDictEcho"],
"EchoAttMap": ["AttMapEcho"],
}
79 changes: 51 additions & 28 deletions attmap/_att_map_like.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import abc
import sys

if sys.version_info < (3, 3):
from collections import Mapping, MutableMapping
else:
from collections.abc import Mapping, MutableMapping
from .helpers import is_custom_map, get_data_lines, get_logger

from .helpers import get_data_lines, get_logger, is_custom_map

__author__ = "Vince Reuter"
__email__ = "[email protected]"
Expand All @@ -18,7 +20,7 @@


class AttMapLike(MutableMapping):
""" Base class for multi-access-mode data objects. """
"""Base class for multi-access-mode data objects."""

__metaclass__ = abc.ABCMeta

Expand Down Expand Up @@ -61,8 +63,9 @@ def __len__(self):
return sum(1 for _ in iter(self))

def __repr__(self):
return self._render(self._simplify_keyvalue(
self._data_for_repr(), self._new_empty_basic_map))
return self._render(
self._simplify_keyvalue(self._data_for_repr(), self._new_empty_basic_map)
)

def _render(self, data, exclude_class_list=[]):
def _custom_repr(obj, prefix=""):
Expand All @@ -75,14 +78,13 @@ def _custom_repr(obj, prefix=""):
:return str: custom object representation
"""
if isinstance(obj, list) and len(obj) > 0:
return "\n{} - ".format(prefix) + \
"\n{} - ".format(prefix).join([str(i) for i in obj])
return repr(obj).strip("'")
return f"\n{prefix} - " + f"\n{prefix} - ".join([str(i) for i in obj])
return obj.strip("'") if hasattr(obj, "strip") else str(obj)

class_name = self.__class__.__name__
if class_name in exclude_class_list:
base = ""
else:
else:
base = class_name + "\n"

if data:
Expand All @@ -109,13 +111,21 @@ def add_entries(self, entries):
except AttributeError:
entries_iter = entries
for k, v in entries_iter:
self[k] = v if (k not in self or not isinstance(v, Mapping)
or not isinstance(self[k], Mapping)) \
self[k] = (
v
if (
k not in self
or not isinstance(v, Mapping)
or not isinstance(self[k], Mapping)
)
else self[k].add_entries(v)
)
return self

def get_yaml_lines(self, conversions=(
(lambda obj: isinstance(obj, Mapping) and 0 == len(obj), None), )):
def get_yaml_lines(
self,
conversions=((lambda obj: isinstance(obj, Mapping) and 0 == len(obj), None),),
):
"""
Get collection of lines that define YAML text rep. of this instance.
Expand All @@ -127,8 +137,8 @@ def get_yaml_lines(self, conversions=(
if 0 == len(self):
return ["{}"]
data = self._simplify_keyvalue(
self._data_for_repr(), self._new_empty_basic_map,
conversions=conversions)
self._data_for_repr(), self._new_empty_basic_map, conversions=conversions
)
return self._render(data).split("\n")[1:]

def is_null(self, item):
Expand Down Expand Up @@ -181,8 +191,9 @@ def _data_for_repr(self):
:return Iterable[(hashable, object)]: collection of key-value pairs
to include in object's text representation
"""
return filter(lambda kv: not self._excl_from_repr(kv[0], self.__class__),
self.items())
return filter(
lambda kv: not self._excl_from_repr(kv[0], self.__class__), self.items()
)

def _excl_from_eq(self, k):
"""
Expand All @@ -204,17 +215,29 @@ def _excl_from_repr(self, k, cls):
"""
return False

def _excl_classes_from_todict(self):
"""
Hook for exclusion of particular class from a dict conversion
"""
return

@abc.abstractproperty
def _lower_type_bound(self):
""" Most specific type to which stored Mapping should be transformed """
"""Most specific type to which stored Mapping should be transformed"""
pass

@abc.abstractmethod
def _new_empty_basic_map(self):
""" Return the empty collection builder for Mapping type simplification. """
"""Return the empty collection builder for Mapping type simplification."""
pass

def _simplify_keyvalue(self, kvs, build, acc=None, conversions=None):
def _simplify_keyvalue(
self,
kvs,
build,
acc=None,
conversions=None,
):
"""
Simplify a collection of key-value pairs, "reducing" to simpler types.
Expand All @@ -223,19 +246,19 @@ def _simplify_keyvalue(self, kvs, build, acc=None, conversions=None):
:param Iterable acc: accumulating collection of simplified data
:return Iterable: collection of simplified data
"""

acc = acc or build()
kvs = iter(kvs)
try:
k, v = next(kvs)
except StopIteration:
return acc
if is_custom_map(v):
v = self._simplify_keyvalue(v.items(), build, build())
if isinstance(v, Mapping):
for pred, proxy in (conversions or []):
if pred(v):
v = proxy
break
acc[k] = v
if not isinstance(v, self._excl_classes_from_todict() or tuple()):
if is_custom_map(v):
v = self._simplify_keyvalue(v.items(), build, build())
if isinstance(v, Mapping):
for pred, proxy in conversions or []:
if pred(v):
v = proxy
break
acc[k] = v
return self._simplify_keyvalue(kvs, build, acc, conversions)
2 changes: 1 addition & 1 deletion attmap/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.13.0"
__version__ = "0.13.1"
Loading

0 comments on commit b2c80a6

Please sign in to comment.