Skip to content

Commit

Permalink
Declare soma_type as a class var rather than a property. (#102)
Browse files Browse the repository at this point in the history
When using `@property` declarations, the type system would not realize
that in the implementation, `soma_type` could always be accessed as a
class variable. This change just makes `soma_type` a class var and
shuffles around some annotations to make that easier. The `is_sparse`
field on `NDArray` is similarly updated.
  • Loading branch information
thetorpedodog authored Jan 26, 2023
1 parent 357c903 commit 9a957ee
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 36 deletions.
15 changes: 9 additions & 6 deletions python-spec/src/somacore/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""

import abc
from typing import Any, MutableMapping, Optional, Type, TypeVar
from typing import Any, ClassVar, MutableMapping, Optional, Type, TypeVar

from typing_extensions import LiteralString

Expand Down Expand Up @@ -63,11 +63,14 @@ def metadata(self) -> MutableMapping[str, Any]:
"""
raise NotImplementedError()

@property
@abc.abstractmethod
def soma_type(self) -> LiteralString:
"""A string describing the SOMA type of this object."""
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.
# This is the equivalent, just without abc-based automatic verification.
#
# Overrides are marked Final with an ignore[misc] because mypy by default
# wants this to be mutable, and doesn't like overriding the mutable member
# with a Final member.

# Context management

Expand Down
8 changes: 1 addition & 7 deletions python-spec/src/somacore/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
)

import pyarrow as pa
from typing_extensions import LiteralString

from . import base
from . import data
Expand All @@ -33,6 +32,7 @@ class Collection(base.SOMAObject, MutableMapping[str, _ST], metaclass=abc.ABCMet
"""

__slots__ = ()
soma_type = "SOMACollection"

@classmethod
@abc.abstractmethod
Expand Down Expand Up @@ -182,12 +182,6 @@ def set(
"""
raise NotImplementedError()

# This is implemented as a property and not a literal so that it can be
# overridden with `Final` members in Collection specializations.
@property
def soma_type(self) -> LiteralString:
return "SOMACollection"


class SimpleCollection(Collection[_ST]):
"""A memory-backed SOMA Collection for ad-hoc collection building.
Expand Down
36 changes: 19 additions & 17 deletions python-spec/src/somacore/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,20 @@
"""

import abc
from typing import Any, Iterator, Optional, Sequence, Tuple, Type, TypeVar, Union
from typing import (
Any,
ClassVar,
Iterator,
Optional,
Sequence,
Tuple,
Type,
TypeVar,
Union,
)

import pyarrow as pa
from typing_extensions import Final
from typing_extensions import Final, Literal

from . import base
from . import options
Expand All @@ -25,6 +35,7 @@ class DataFrame(base.SOMAObject, metaclass=abc.ABCMeta):
"""A multi-column table with a user-defined schema."""

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

# Lifecycle

Expand Down Expand Up @@ -89,10 +100,6 @@ def index_column_names(self) -> Tuple[str, ...]:
"""The names of the index (dimension) columns."""
raise NotImplementedError()

# Basic operations

soma_type: Final = "SOMADataFrame"


_NDT = TypeVar("_NDT", bound="NDArray")
"""Any implementation of NDArray."""
Expand Down Expand Up @@ -138,17 +145,16 @@ def schema(self) -> pa.Schema:
"""The schema of the data in this array."""
raise NotImplementedError()

@property
@abc.abstractmethod
def is_sparse(self) -> bool:
"""True if this array is sparse. False if this array is dense."""
raise NotImplementedError()
is_sparse: ClassVar[Literal[True, False]]
"""True if the array is sparse. False if it is dense."""


class DenseNDArray(NDArray, metaclass=abc.ABCMeta):
"""A N-dimensional array stored densely."""

__slots__ = ()
soma_type: Final = "SOMADenseNDArray" # type: ignore[misc]
is_sparse: Final = False # type: ignore[misc]

@abc.abstractmethod
def read(
Expand Down Expand Up @@ -180,9 +186,6 @@ def write(
"""
raise NotImplementedError()

is_sparse: Final = False
soma_type: Final = "SOMADenseNDArray"


SparseArrowData = Union[
pa.SparseCSCMatrix,
Expand All @@ -197,6 +200,8 @@ class SparseNDArray(NDArray, metaclass=abc.ABCMeta):
"""A N-dimensional array stored sparsely."""

__slots__ = ()
soma_type: Final = "SparseNDArray" # type: ignore[misc]
is_sparse: Final = True # type: ignore[misc]

@abc.abstractmethod
def read(
Expand Down Expand Up @@ -242,9 +247,6 @@ def nnz(self) -> int:
"""
raise NotImplementedError()

is_sparse: Final = True
soma_type: Final = "SOMASparseNDArray"


#
# Read types
Expand Down
5 changes: 2 additions & 3 deletions python-spec/src/somacore/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Experiment(MutableMapping[str, _ST]):
# TypeError: multiple bases have instance lay-out conflict

__slots__ = ()
soma_type: Final = "SOMAExperiment"

obs = _mixin.item(data.DataFrame)
"""Primary observations on the observation axis.
Expand Down Expand Up @@ -63,8 +64,6 @@ def axis_query(
var_query=var_query or query.AxisQuery(),
)

soma_type: Final = "SOMAExperiment"


class SimpleExperiment(Experiment, collection.SimpleCollection):
class SimpleExperiment(Experiment, collection.SimpleCollection): # type: ignore[misc]
"""An in-memory Collection with Experiment semantics."""
5 changes: 2 additions & 3 deletions python-spec/src/somacore/measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Measurement(MutableMapping[str, _ST]):
# TypeError: multiple bases have instance lay-out conflict

__slots__ = ()
soma_type: Final = "SOMAMeasurement"

var = _mixin.item(data.DataFrame)
"""Primary annotations on the variable axis for vars on this meansurement.
Expand Down Expand Up @@ -68,8 +69,6 @@ class Measurement(MutableMapping[str, _ST]):
This is indexed by ``[varid_1, varid_2]``.
"""

soma_type: Final = "SOMAMeasurement"


class SimpleMeasurement(Measurement, collection.SimpleCollection):
class SimpleMeasurement(Measurement, collection.SimpleCollection): # type: ignore[misc]
"""An in-memory Collection with Measurement semantics."""

0 comments on commit 9a957ee

Please sign in to comment.