From fc7e615a9e1331204a8f5ee87f80eb388a5ef977 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Wed, 17 Jun 2020 10:23:37 -0400 Subject: [PATCH] Make core submodule adhere to numpydoc conventions. (#339) --- setup.cfg | 2 +- signac/core/attrdict.py | 2 ++ signac/core/dict_manager.py | 7 ++-- signac/core/h5store.py | 70 +++++++++++++++++++++---------------- signac/core/json.py | 2 ++ signac/core/synceddict.py | 6 ++-- 6 files changed, 52 insertions(+), 37 deletions(-) diff --git a/setup.cfg b/setup.cfg index 63102f611..f68a4b2db 100644 --- a/setup.cfg +++ b/setup.cfg @@ -15,7 +15,7 @@ max-line-length = 100 exclude = configobj,passlib,cite.py,conf.py [pydocstyle] -match = (jsondict|project|schema|job|errors|filterparse|hashing|linked_view|utility|collection).py +match = (jsondict|project|schema|job|errors|filterparse|hashing|linked_view|utility|collection|attrdict|dict_manager|h5store|json|synceddict).py ignore = D105, D107, D203, D204, D213 [mypy] diff --git a/signac/core/attrdict.py b/signac/core/attrdict.py index 1623ce059..8de7cd421 100644 --- a/signac/core/attrdict.py +++ b/signac/core/attrdict.py @@ -1,6 +1,8 @@ # Copyright (c) 2017 The Regents of the University of Michigan # All rights reserved. # This software is licensed under the BSD 3-Clause License. +"""Defines attribute dictionaries, where values can be accessed as attributes.""" + from .synceddict import _SyncedDict diff --git a/signac/core/dict_manager.py b/signac/core/dict_manager.py index 9384ff4a6..ca170f954 100644 --- a/signac/core/dict_manager.py +++ b/signac/core/dict_manager.py @@ -1,7 +1,8 @@ # Copyright (c) 2019 The Regents of the University of Michigan # All rights reserved. # This software is licensed under the BSD 3-Clause License. -"Basic wrapper to access multiple different data stores." +"""Basic wrapper to access multiple different data stores.""" + import os import re import errno @@ -28,6 +29,7 @@ def __init__(self, prefix): @property def prefix(self): + """Return the prefix.""" return self._prefix def __eq__(self, other): @@ -46,7 +48,7 @@ def __getitem__(self, key): @staticmethod def _validate_key(key): - "Emit a warning or raise an exception if key is invalid. Returns key." + """Emit a warning or raise an exception if key is invalid. Returns key.""" return key def __setitem__(self, key, value): @@ -108,6 +110,7 @@ def __iter__(self): yield m.groups()[0] def keys(self): + """Return an iterable of keys.""" return iter(self) def __len__(self): diff --git a/signac/core/h5store.py b/signac/core/h5store.py index e41d02581..98a0a6f2a 100644 --- a/signac/core/h5store.py +++ b/signac/core/h5store.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 The Regents of the University of Michigan # All rights reserved. # This software is licensed under the BSD 3-Clause License. -"Data store implementation with backend HDF5 file." +"""Data store implementation with backend HDF5 file.""" import logging import os import errno @@ -59,7 +59,7 @@ def _requires_tables(): class H5StoreClosedError(RuntimeError): - "Raised when trying to access a closed store." + """Raised when trying to access a closed store.""" class H5StoreAlreadyOpenError(OSError): @@ -67,8 +67,11 @@ class H5StoreAlreadyOpenError(OSError): def _h5set(store, grp, key, value, path=None): - """Set a key in an h5py container, recursively converting Mappings to h5py - groups and transparently handling None.""" + """Set a key in an h5py container. + + This method recursively converts Mappings to h5py groups and transparently + handles None values. + """ import h5py import numpy # h5py depends on numpy, so this is safe. path = path + '/' + key if path else key @@ -223,6 +226,7 @@ def __setattr__(self, key, value): self.__setitem__(key, value) def setdefault(self, key, value): + """Set a value for a key if that key is not already set.""" super(H5Group, self).setdefault(key, value) return self.__getitem__(key) @@ -256,19 +260,20 @@ class H5Store(MutableMapping): * built-in types (int, float, str, bool, NoneType, array) * numpy arrays * pandas data frames (requires pandas and pytables) + * mappings with values that are supported types - as well as mappings of values of these types. Values can be accessed as - attributes (``h5s.foo``) or via key index (``h5s['foo']``). - - Example: - - .. code-block:: python + Values can be accessed as attributes (``h5s.foo``) or via key index + (``h5s['foo']``). - with H5Store('file.h5') as h5s: - h5s['foo'] = 'bar' - assert 'foo' in h5s - assert h5s.foo == 'bar' - assert h5s['foo'] == 'bar' + Examples + -------- + >>> from signac import H5Store + >>> with H5Store('file.h5') as h5s: + ... h5s['foo'] = 'bar' + ... assert 'foo' in h5s + ... assert h5s.foo == 'bar' + ... assert h5s['foo'] == 'bar' + >>> The H5Store can be used as a context manager to ensure that the underlying file is opened, however most built-in types (excluding arrays) can be read @@ -277,18 +282,20 @@ class H5Store(MutableMapping): To open a file in read-only mode, use the :py:meth:`.open` method with ``mode='r'``: - .. code-block:: python - - with H5Store('file.h5').open(mode='r') as h5s: - pass + >>> with H5Store('file.h5').open(mode='r') as h5s: + ... pass + >>> - :param filename: + Parameters + ---------- + filename : str The filename of the underlying HDF5 file. - :param \*\*kwargs: - Additional keyword arguments to be forwarded to the ``h5py.File`` constructor. - See the documentation for the - `h5py.File constructor `_ - for more information. + \*\*kwargs + Additional keyword arguments to be forwarded to the ``h5py.File`` + constructor. See the documentation for the `h5py.File constructor + `_ for more + information. + """ __slots__ = ['_filename', '_file', '_kwargs'] @@ -303,6 +310,7 @@ def __init__(self, filename, **kwargs): @property def filename(self): + """Return the H5Store filename.""" return self._filename def __repr__(self): @@ -397,7 +405,7 @@ def file(self): @property def mode(self): - """The default opening mode of this store.""" + """Return the default opening mode of this H5Store.""" return self._mode def flush(self): @@ -414,7 +422,7 @@ def __getitem__(self, key): @staticmethod def _validate_key(key): - "Emit a warning or raise an exception if key is invalid. Returns key." + """Emit a warning or raise an exception if key is invalid. Returns key.""" if '.' in key: raise InvalidKeyError("Keys for the H5Store may not contain dots ('.').") return key @@ -452,6 +460,7 @@ def __delattr__(self, key): self.__delitem__(key) def setdefault(self, key, value): + """Set a value for a key if that key is not already set.""" super(H5Store, self).setdefault(key, value) return self.__getitem__(key) @@ -482,9 +491,8 @@ def __contains__(self, key): def clear(self): """Remove all data from this store. - .. danger:: - - All data will be removed, this action cannot be reversed! + .. danger:: + All data will be removed, this action cannot be reversed! """ with _ensure_open(self): self._file.clear() @@ -512,7 +520,7 @@ class H5StoreManager(DictManager): @staticmethod def _validate_key(key): - "Emit a warning or raise an exception if key is invalid. Returns key." + """Emit a warning or raise an exception if key is invalid. Returns key.""" if '.' in key: raise InvalidKeyError("Keys for the H5StoreManager may not contain dots ('.').") return key diff --git a/signac/core/json.py b/signac/core/json.py index 7c3ff47b0..c615a4485 100644 --- a/signac/core/json.py +++ b/signac/core/json.py @@ -1,6 +1,7 @@ # Copyright (c) 2018 The Regents of the University of Michigan # All rights reserved. # This software is licensed under the BSD 3-Clause License. +"""Wrapper around json parsing library.""" import logging from json import load, loads, JSONEncoder from json.decoder import JSONDecodeError @@ -37,6 +38,7 @@ def default(self, o: Any) -> Dict[str, Any]: def dumps(o: Any, sort_keys: bool = False, indent: Optional[int] = None) -> str: + """Convert a JSON-compatible mapping into a string.""" return CustomJSONEncoder(sort_keys=sort_keys, indent=indent).encode(o) diff --git a/signac/core/synceddict.py b/signac/core/synceddict.py index 48c74555e..bb7bf2f16 100644 --- a/signac/core/synceddict.py +++ b/signac/core/synceddict.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 The Regents of the University of Michigan # All rights reserved. # This software is licensed under the BSD 3-Clause License. -"Synchronized dictionary." +"""Synchronized dictionary.""" import logging from contextlib import contextmanager from functools import wraps @@ -87,7 +87,7 @@ def __init__(self, initialdata=None, parent=None): @classmethod def _validate_key(cls, key): - "Emit a warning or raise an exception if key is invalid. Returns key." + """Emit a warning or raise an exception if key is invalid. Returns key.""" if isinstance(key, str): if '.' in key: from ..errors import InvalidKeyError @@ -125,7 +125,7 @@ def _dfs_convert(self, root): @classmethod def _convert_to_dict(cls, root): - "Convert (nested) values to dict." + """Convert (nested) values to dict.""" if type(root) == cls: ret = dict() with root._suspend_sync():