Skip to content

Commit 25a5d7c

Browse files
committed
Better repr of large_image classes
Before, the repr of a large_image tile source was something like `OpenslideFileTileSource ('/data/samplefile.svs', 'JPEG', 95, 0, 'raw', False, '__STYLESTART__', {'bands': [{'band': 1, 'palette': 'white'}]}, '__STYLEEND__')`. Now, this is `OpenslideFileTileSource('/data/samplefile.svs', style={'bands': [{'band': 1, 'palette': 'white'}]})`, which could actually be used to open the tile source again. If the class is unpickleable (for instance, a vips tile sink), the repr is surrounded by `<>` to indicate this. As an added feature, `__rich_repr__` has been added to make the results prettier for those using the rich text library.
1 parent 6a1be4d commit 25a5d7c

File tree

4 files changed

+26
-3
lines changed

4 files changed

+26
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- Automatically set the JUPYTER_PROXY value ([#1781](../../pull/1781))
1717
- Add a general channelNames property to tile sources ([#1783](../../pull/1783))
1818
- Speed up compositing styles ([#1784](../../pull/1784))
19+
- Better repr of large_image classes ([#1787](../../pull/1787))
1920

2021
### Changes
2122

large_image/tilesource/base.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,30 @@ def __reduce__(self) -> Tuple[functools.partial, Tuple[str]]:
200200
return functools.partial(type(self), **self._initValues[1]), self._initValues[0]
201201

202202
def __repr__(self) -> str:
203-
return self.getState()
203+
if hasattr(self, '_initValues') and not hasattr(self, '_unpickleable'):
204+
param = [
205+
f'{k}={v!r}' if k != 'style' or not isinstance(v, dict) or
206+
not getattr(self, '_jsonstyle', None) else
207+
f'style={json.loads(self._jsonstyle)}'
208+
for k, v in self._initValues[1].items()]
209+
return (
210+
f'{self.__class__.__name__}('
211+
f'{", ".join(repr(val) for val in self._initValues[0])}'
212+
f'{", " if len(self._initValues[1]) else ""}'
213+
f'{", ".join(param)}'
214+
')')
215+
return '<' + self.getState() + '>'
204216

205217
def _repr_png_(self) -> bytes:
206218
return self.getThumbnail(encoding='PNG')[0]
207219

220+
def __rich_repr__(self) -> Iterator[Any]:
221+
if not hasattr(self, '_initValues') or hasattr(self, '_unpickleable'):
222+
yield self.getState()
223+
else:
224+
yield from self._initValues[0]
225+
yield from self._initValues[1].items()
226+
208227
@property
209228
def geospatial(self) -> bool:
210229
return False

sources/pil/large_image_source_pil/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,11 @@ def _fromRawpy(self, largeImagePath):
224224
"""
225225
# if rawpy is present, try reading via that library first
226226
try:
227+
import builtins
228+
227229
import rawpy
228230

229-
with contextlib.redirect_stderr(open(os.devnull, 'w')):
231+
with contextlib.redirect_stderr(builtins.open(os.devnull, 'w')):
230232
rgb = rawpy.imread(largeImagePath).postprocess()
231233
rgb = large_image.tilesource.utilities._imageToNumpy(rgb)[0]
232234
if rgb.shape[2] == 2:

sources/pil/setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ def prerelease_local_scheme(version):
5858
'all': [
5959
'rawpy',
6060
'pillow-heif',
61-
'pillow-jxl-plugin',
61+
'pillow-jxl-plugin < 1.3 ; python_version < "3.8"',
62+
'pillow-jxl-plugin ; python_version >= "3.9"',
6263
'pillow-jpls',
6364
],
6465
'girder': f'girder-large-image{limit_version}',

0 commit comments

Comments
 (0)