Skip to content

Commit

Permalink
Merge pull request #294 from bgilbert/fixes
Browse files Browse the repository at this point in the history
Small fixes
  • Loading branch information
bgilbert authored Oct 27, 2024
2 parents baf1c54 + 7d1be91 commit bbbc0eb
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 14 deletions.
31 changes: 18 additions & 13 deletions openslide/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

from __future__ import annotations

from abc import ABCMeta, abstractmethod
from io import BytesIO
from types import TracebackType
from typing import Iterator, Literal, Mapping, TypeVar
Expand Down Expand Up @@ -62,7 +63,7 @@
_T = TypeVar('_T')


class AbstractSlide:
class AbstractSlide(metaclass=ABCMeta):
"""The base class of a slide object."""

def __init__(self) -> None:
Expand All @@ -81,22 +82,26 @@ def __exit__(
return False

@classmethod
@abstractmethod
def detect_format(cls, filename: lowlevel.Filename) -> str | None:
"""Return a string describing the format of the specified file.
If the file format is not recognized, return None."""
raise NotImplementedError

@abstractmethod
def close(self) -> None:
"""Close the slide."""
raise NotImplementedError

@property
@abstractmethod
def level_count(self) -> int:
"""The number of levels in the image."""
raise NotImplementedError

@property
@abstractmethod
def level_dimensions(self) -> tuple[tuple[int, int], ...]:
"""A tuple of (width, height) tuples, one for each level of the image.
Expand All @@ -109,20 +114,23 @@ def dimensions(self) -> tuple[int, int]:
return self.level_dimensions[0]

@property
@abstractmethod
def level_downsamples(self) -> tuple[float, ...]:
"""A tuple of downsampling factors for each level of the image.
level_downsample[n] contains the downsample factor of level n."""
raise NotImplementedError

@property
@abstractmethod
def properties(self) -> Mapping[str, str]:
"""Metadata about the image.
This is a map: property name -> property value."""
raise NotImplementedError

@property
@abstractmethod
def associated_images(self) -> Mapping[str, Image.Image]:
"""Images associated with this whole-slide image.
Expand All @@ -136,10 +144,12 @@ def color_profile(self) -> ImageCms.ImageCmsProfile | None:
return None
return ImageCms.getOpenProfile(BytesIO(self._profile))

@abstractmethod
def get_best_level_for_downsample(self, downsample: float) -> int:
"""Return the best level for displaying the given downsample."""
raise NotImplementedError

@abstractmethod
def read_region(
self, location: tuple[int, int], level: int, size: tuple[int, int]
) -> Image.Image:
Expand All @@ -151,11 +161,13 @@ def read_region(
size: (width, height) tuple giving the region size."""
raise NotImplementedError

def set_cache(self, cache: OpenSlideCache) -> None:
def set_cache(self, cache: OpenSlideCache) -> None: # noqa: B027
"""Use the specified cache to store recently decoded slide tiles.
This class does not support caching, so this method does nothing.
cache: an OpenSlideCache object."""
raise NotImplementedError
pass

def get_thumbnail(self, size: tuple[int, int]) -> Image.Image:
"""Return a PIL.Image containing an RGB thumbnail of the image.
Expand Down Expand Up @@ -299,6 +311,7 @@ def __len__(self) -> int:
def __iter__(self) -> Iterator[str]:
return iter(self._keys())

@abstractmethod
def _keys(self) -> list[str]:
# Private method; always returns list.
raise NotImplementedError()
Expand Down Expand Up @@ -406,7 +419,7 @@ def level_dimensions(self) -> tuple[tuple[int, int]]:
level_dimensions[n] contains the dimensions of level n."""
if self._image is None:
raise ValueError('Passing closed slide object')
raise ValueError('Cannot read from a closed slide')
return (self._image.size,)

@property
Expand Down Expand Up @@ -444,7 +457,7 @@ def read_region(
level: the level number.
size: (width, height) tuple giving the region size."""
if self._image is None:
raise ValueError('Passing closed slide object')
raise ValueError('Cannot read from a closed slide')
if level != 0:
raise OpenSlideError("Invalid level")
if ['fail' for s in size if s < 0]:
Expand Down Expand Up @@ -474,14 +487,6 @@ def read_region(
tile.info['icc_profile'] = self._profile
return tile

def set_cache(self, cache: OpenSlideCache) -> None:
"""Use the specified cache to store recently decoded slide tiles.
ImageSlide does not support caching, so this method does nothing.
cache: an OpenSlideCache object."""
pass


def open_slide(filename: lowlevel.Filename) -> OpenSlide | ImageSlide:
"""Open a whole-slide or regular image.
Expand Down
1 change: 0 additions & 1 deletion openslide/lowlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,6 @@ def read_associated_image_icc_profile(
'openslide_set_cache',
None,
[_OpenSlide, _OpenSlideCache],
None,
minimum_version='4.0.0',
)

Expand Down

0 comments on commit bbbc0eb

Please sign in to comment.