Skip to content

Commit

Permalink
[python] Add missing lifecycle methods and expand docstrings (#119)
Browse files Browse the repository at this point in the history
- Adds `mode`, `close`, and `closed` methods/properties.
- Fills in most of the docstrings with details about parameters and
  expected behavior.
- Makes `coords` no longer Optional
- Specifies that value filters are implementation-dependent.
- Add lifecycle tags to everything.
  • Loading branch information
thetorpedodog authored Feb 13, 2023
1 parent 02bb4e2 commit 8922de4
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 39 deletions.
34 changes: 30 additions & 4 deletions python-spec/src/somacore/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@


class SOMAObject(metaclass=abc.ABCMeta):
"""A sentinel interface indicating that this type is a SOMA object."""
"""The base type for all SOMA objects, containing common behaviors."""

__slots__ = ("__weakref__",)

Expand All @@ -27,18 +27,27 @@ def open(
context: Optional[Any] = None,
platform_config: Optional[options.PlatformConfig] = None,
) -> Self:
"""Opens the SOMA object at the given URL."""
"""Opens the SOMA object of this type at the given URI.
[lifecycle: experimental]
:param uri: The URI of the object to open.
:param mode: The mode to open this in, either `r` or `w`.
:param context: The Context value to use when opening the object.
:param platform_config: Platform configuration options specific to
this open operation.
"""
raise NotImplementedError()

@property
@abc.abstractmethod
def uri(self) -> str:
"""Returns the URI of this SOMA object."""
"""Returns the URI of this SOMA object. [lifecycle: experimental]"""
raise NotImplementedError()

@property
def context(self) -> Any:
"""A value storing implementation-specific configuration information.
[lifecycle: experimental]
This contains long-lived (i.e., not call-specific) information that is
used by the SOMA implementation to access storage. This may include
Expand All @@ -53,14 +62,30 @@ def context(self) -> Any:
@property
@abc.abstractmethod
def metadata(self) -> MutableMapping[str, Any]:
"""The metadata of this SOMA object.
"""The metadata of this SOMA object. [lifecycle: experimental]
The returned value directly references the stored metadata; reads from
and writes to it (provided the object is opened) are reflected in
storage.
"""
raise NotImplementedError()

@property
@abc.abstractmethod
def mode(self) -> options.OpenMode:
"""Returns the mode this object was opened in, either ``r`` or ``w``.
[lifecycle: experimental]
"""
raise NotImplementedError()

@property
@abc.abstractmethod
def closed(self) -> bool:
"""Returns True if this object has been closed; False if still open.
[lifecycle: experimental]
"""
raise NotImplementedError()

soma_type: ClassVar[LiteralString]
"""A string describing the SOMA type of this object. This is constant."""
# This uses ClassVar since you can't do abstract class properties.
Expand All @@ -74,6 +99,7 @@ def metadata(self) -> MutableMapping[str, Any]:

def close(self) -> None:
"""Releases any external resources held by this object.
[lifecycle: experimental]
An implementation of close must be idempotent.
"""
Expand Down
16 changes: 12 additions & 4 deletions python-spec/src/somacore/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class BaseCollection(
base.SOMAObject, MutableMapping[str, _Elem], metaclass=abc.ABCMeta
):
"""A generic string-keyed collection of :class:`SOMAObject`s.
[lifecycle: experimental]
The generic type specifies what type the Collection may contain. At its
most generic, a Collection may contain any SOMA object, but a subclass
Expand All @@ -35,9 +36,10 @@ def create(
platform_config: Optional[options.PlatformConfig] = None,
context: Optional[Any] = None,
) -> Self:
"""Creates a new Collection at the given URI and returns it.
"""Creates a new collection of this type at the given URI.
[lifecycle: experimental]
The collection will be returned in the opened state.
The collection will be returned opened for writing.
"""
raise NotImplementedError()

Expand Down Expand Up @@ -81,6 +83,7 @@ def add_new_collection(
platform_config: Optional[options.PlatformConfig] = None,
) -> "BaseCollection":
"""Creates a new sub-collection of this collection.
[lifecycle: experimental]
To add an existing collection as a sub-element of this collection,
use :meth:`set` or indexed access instead.
Expand Down Expand Up @@ -131,6 +134,7 @@ def add_new_dataframe(
platform_config: Optional[options.PlatformConfig] = None,
) -> data.DataFrame:
"""Creates a new DataFrame as a child of this collection.
[lifecycle: experimental]
Parameters are as in :meth:`data.DataFrame.create`.
See :meth:`add_new_collection` for details about child creation.
Expand All @@ -148,6 +152,7 @@ def add_new_dense_ndarray(
platform_config: Optional[options.PlatformConfig] = None,
) -> data.DenseNDArray:
"""Creates a new dense NDArray as a child of this collection.
[lifecycle: experimental]
Parameters are as in :meth:`data.DenseNDArray.create`.
See :meth:`add_new_collection` for details about child creation.
Expand All @@ -165,6 +170,7 @@ def add_new_sparse_ndarray(
platform_config: Optional[options.PlatformConfig] = None,
) -> data.SparseNDArray:
"""Creates a new sparse NDArray as a child of this collection.
[lifecycle: experimental]
Parameters are as in :meth:`data.SparseNDArray.create`.
See :meth:`add_new_collection` for details about child creation.
Expand All @@ -179,7 +185,7 @@ def __setitem__(self, key: str, value: _Elem) -> None:
def set(
self, key: str, value: _Elem, *, use_relative_uri: Optional[bool] = None
) -> None:
"""Sets an entry of this collection.
"""Sets an entry of this collection. [lifecycle: experimental]
Important note: Because parent objects may need to share
implementation-internal state with children, when you set an item in a
Expand All @@ -206,7 +212,9 @@ def set(


class Collection(BaseCollection[_Elem]):
"""SOMA Collection imposing no semantics on the contained values."""
"""SOMA Collection imposing no semantics on the contained values.
[lifecycle: experimental]
"""

soma_type: Final = "SOMACollection" # type: ignore[misc]
__slots__ = ()
Loading

0 comments on commit 8922de4

Please sign in to comment.