Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-oiffile for openSUSE:Factory checked in at 2025-12-29 15:16:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-oiffile (Old) and /work/SRC/openSUSE:Factory/.python-oiffile.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-oiffile" Mon Dec 29 15:16:43 2025 rev:9 rq:1324585 version:2025.12.12 Changes: -------- --- /work/SRC/openSUSE:Factory/python-oiffile/python-oiffile.changes 2025-07-06 17:19:11.990979361 +0200 +++ /work/SRC/openSUSE:Factory/.python-oiffile.new.1928/python-oiffile.changes 2025-12-29 15:17:25.960559761 +0100 @@ -1,0 +2,8 @@ +Sun Dec 28 19:29:40 UTC 2025 - Dirk Müller <[email protected]> + +- update to 2025.12.12: + * ## Read Olympus image files (OIF and OIB) + * Derive OifFileError from ValueError. + * Drop support for Python 3.10. + +------------------------------------------------------------------- Old: ---- oiffile-2025.5.10.tar.gz New: ---- oiffile-2025.12.12.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-oiffile.spec ++++++ --- /var/tmp/diff_new_pack.uzwCcz/_old 2025-12-29 15:17:27.000602479 +0100 +++ /var/tmp/diff_new_pack.uzwCcz/_new 2025-12-29 15:17:27.004602644 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-oiffile # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2025 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: python-oiffile -Version: 2025.5.10 +Version: 2025.12.12 Release: 0 Summary: Read Olympus(r) image files (OIF and OIB) License: BSD-3-Clause ++++++ oiffile-2025.5.10.tar.gz -> oiffile-2025.12.12.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oiffile-2025.5.10/MANIFEST.in new/oiffile-2025.12.12/MANIFEST.in --- old/oiffile-2025.5.10/MANIFEST.in 2025-05-10 21:22:30.000000000 +0200 +++ new/oiffile-2025.12.12/MANIFEST.in 2025-12-12 03:24:02.000000000 +0100 @@ -5,7 +5,11 @@ include oiffile/py.typed +exclude .env exclude *.cmd +exclude *.yaml +exclude mypy.ini +exclude ruff.toml recursive-exclude doc * recursive-exclude docs * recursive-exclude test * @@ -14,3 +18,10 @@ recursive-exclude * __pycache__ recursive-exclude * *.py[co] recursive-exclude * *Copy* + +# include docs/conf.py +# include docs/make.py +# include docs/_static/custom.css + +# include tests/conftest.py +# include tests/test_oiffile.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oiffile-2025.5.10/README.rst new/oiffile-2025.12.12/README.rst --- old/oiffile-2025.5.10/README.rst 2025-05-10 21:22:30.000000000 +0200 +++ new/oiffile-2025.12.12/README.rst 2025-12-12 03:24:02.000000000 +0100 @@ -19,7 +19,8 @@ :Author: `Christoph Gohlke <https://www.cgohlke.com>`_ :License: BSD-3-Clause -:Version: 2025.5.10 +:Version: 2025.12.12 +:DOI: `10.5281/zenodo.17905223 <https://doi.org/10.5281/zenodo.17905223>`_ Quickstart ---------- @@ -44,13 +45,18 @@ This revision was tested with the following requirements and dependencies (other versions may work): -- `CPython <https://www.python.org>`_ 3.10.11, 3.11.9, 3.12.10, 3.13.3 64-bit -- `NumPy <https://pypi.org/project/numpy/>`_ 2.2.5 -- `Tifffile <https://pypi.org/project/tifffile/>`_ 2025.5.10 +- `CPython <https://www.python.org>`_ 3.11.9, 3.12.10, 3.13.11 3.14.2 64-bit +- `NumPy <https://pypi.org/project/numpy>`_ 2.3.5 +- `Tifffile <https://pypi.org/project/tifffile/>`_ 2025.10.16 Revisions --------- +2025.12.12 + +- Derive OifFileError from ValueError. +- Drop support for Python 3.10. + 2025.5.10 - Remove doctest command line option. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oiffile-2025.5.10/oiffile/__init__.py new/oiffile-2025.12.12/oiffile/__init__.py --- old/oiffile-2025.5.10/oiffile/__init__.py 2025-05-10 21:22:30.000000000 +0200 +++ new/oiffile-2025.12.12/oiffile/__init__.py 2025-12-12 03:24:02.000000000 +0100 @@ -3,15 +3,7 @@ from .oiffile import * from .oiffile import __all__, __doc__, __version__ +# constants are repeated for documentation -def _set_module() -> None: - """Set __module__ attribute for all public objects.""" - globs = globals() - module = globs['__name__'] - for item in __all__: - obj = globs[item] - if hasattr(obj, '__module__'): - obj.__module__ = module - - -_set_module() +__version__ = __version__ +"""Oiffile version string.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oiffile-2025.5.10/oiffile/oiffile.py new/oiffile-2025.12.12/oiffile/oiffile.py --- old/oiffile-2025.5.10/oiffile/oiffile.py 2025-05-10 21:22:30.000000000 +0200 +++ new/oiffile-2025.12.12/oiffile/oiffile.py 2025-12-12 03:24:02.000000000 +0100 @@ -46,7 +46,8 @@ :Author: `Christoph Gohlke <https://www.cgohlke.com>`_ :License: BSD-3-Clause -:Version: 2025.5.10 +:Version: 2025.12.12 +:DOI: `10.5281/zenodo.17905223 <https://doi.org/10.5281/zenodo.17905223>`_ Quickstart ---------- @@ -71,13 +72,18 @@ This revision was tested with the following requirements and dependencies (other versions may work): -- `CPython <https://www.python.org>`_ 3.10.11, 3.11.9, 3.12.10, 3.13.3 64-bit -- `NumPy <https://pypi.org/project/numpy/>`_ 2.2.5 -- `Tifffile <https://pypi.org/project/tifffile/>`_ 2025.5.10 +- `CPython <https://www.python.org>`_ 3.11.9, 3.12.10, 3.13.11 3.14.2 64-bit +- `NumPy <https://pypi.org/project/numpy>`_ 2.3.5 +- `Tifffile <https://pypi.org/project/tifffile/>`_ 2025.10.16 Revisions --------- +2025.12.12 + +- Derive OifFileError from ValueError. +- Drop support for Python 3.10. + 2025.5.10 - Remove doctest command line option. @@ -204,20 +210,20 @@ from __future__ import annotations -__version__ = '2025.5.10' +__version__ = '2025.12.12' __all__ = [ - '__version__', - 'imread', - 'oib2oif', + 'CompoundFile', + 'FileSystemAbc', + 'OibFileSystem', 'OifFile', 'OifFileError', - 'OibFileSystem', 'OifFileSystem', - 'FileSystemAbc', 'SettingsFile', - 'CompoundFile', + '__version__', 'filetime', + 'imread', + 'oib2oif', ] import abc @@ -235,7 +241,8 @@ if TYPE_CHECKING: from collections.abc import Generator, Iterable, Iterator - from typing import IO, Any, BinaryIO, Literal + from types import TracebackType + from typing import IO, Any, BinaryIO, Literal, Self from numpy.typing import NDArray @@ -251,8 +258,7 @@ """ with OifFile(filename) as oif: - result = oif.asarray(**kwargs) - return result + return oif.asarray(**kwargs) def oib2oif( @@ -277,7 +283,7 @@ oib.saveas_oif(location=location, verbose=verbose) -class OifFileError(Exception): +class OifFileError(ValueError): """Exception to raise issues with OIF or OIB structure.""" @@ -379,7 +385,7 @@ bitcount = int( self.mainfile['Reference Image Parameter']['ValidBitCounts'] ) - return numpy.dtype('<u2' if bitcount > 8 else '<u2') + return numpy.dtype('<u2' if bitcount > 8 else 'u1') @property def series(self) -> tuple[TiffSequence, ...]: @@ -402,7 +408,7 @@ for files in tiffiles.values() ) if len(series) > 1: - series = tuple(reversed(sorted(series, key=lambda x: len(x)))) + series = tuple(sorted(series, key=lambda x: len(x), reverse=True)) self._series = series return series @@ -431,10 +437,15 @@ """Close file handle.""" self.filesystem.close() - def __enter__(self) -> OifFile: + def __enter__(self) -> Self: return self - def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: self.close() def __repr__(self) -> str: @@ -487,6 +498,7 @@ def files(self) -> Iterator[str]: """Return iterator over unsorted files in FileSystem.""" + @abc.abstractmethod def close(self) -> None: """Close file handle.""" @@ -517,7 +529,7 @@ def __init__( self, filename: str | os.PathLike[Any], /, storage_ext: str = '.files' - ): + ) -> None: self.filename = filename = os.fspath(filename) self._path, self.mainfile = os.path.split(os.path.abspath(filename)) self.settings = SettingsFile(filename, name=self.mainfile) @@ -553,10 +565,15 @@ def close(self) -> None: """Close file handle.""" - def __enter__(self) -> OifFileSystem: + def __enter__(self) -> Self: return self - def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: self.close() def __str__(self) -> str: @@ -647,34 +664,39 @@ mainfile = os.path.join(location, self.mainfile) if os.path.exists(mainfile): raise FileExistsError(mainfile + ' already exists') - for folder in self._folders.keys(): - folder = os.path.join(location, self._folders.get(folder, '')) - if os.path.exists(folder): - raise FileExistsError(folder + ' already exists') - os.makedirs(folder) + for folder in self._folders: + path = os.path.join(location, self._folders.get(folder, '')) + if os.path.exists(path): + raise FileExistsError(path + ' already exists') + os.makedirs(path) if verbose: - print('Saving', mainfile, end=' ') - for f in self._files.keys(): + print('Saving', mainfile, end=' ') # noqa: T201 + for f in self._files: folder, name = os.path.split(f) folder = os.path.join(location, self._folders.get(folder, '')) path = os.path.join(folder, name) if verbose == 1: - print(end='.') + print(end='.') # noqa: T201 elif verbose > 1: - print(path) + print(path) # noqa: T201 with open(path, 'w+b') as fh: fh.write(self.open_file(f).read()) if verbose == 1: - print(' done.') + print(' done.') # noqa: T201 def close(self) -> None: """Close file handle.""" self.com.close() - def __enter__(self) -> OibFileSystem: + def __enter__(self) -> Self: return self - def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: self.close() def __str__(self) -> str: @@ -722,7 +744,7 @@ dict.__init__(self) if isinstance(file, (str, os.PathLike)): self.name = os.path.split(file)[-1] - fh = open(file, 'rb') + fh = open(file, 'rb') # noqa: SIM115 else: self.name = str(name) fh = file @@ -740,19 +762,21 @@ 1, ) if len(content_list) > 1: - self['ColorLUTData'] = numpy.fromstring( - content_list[1], - dtype=numpy.uint8, # type: ignore[call-overload] - ).reshape(-1, 4) + self['ColorLUTData'] = ( + numpy.frombuffer(content_list[1], dtype=numpy.uint8) + .copy() + .reshape(-1, 4) + ) contents = content_list[0].decode('utf-16') elif content[:1] == b'[': # try UTF-8 content_list = content.rsplit(b'[ColorLUTData]\r\n', 1) if len(content_list) > 1: - self['ColorLUTData'] = numpy.fromstring( - content_list[1], - dtype=numpy.uint8, # type: ignore[call-overload] - ).reshape(-1, 4) + self['ColorLUTData'] = ( + numpy.frombuffer(content_list[1], dtype=numpy.uint8) + .copy() + .reshape(-1, 4) + ) try: contents = content_list[0].decode() except Exception as exc: @@ -761,7 +785,7 @@ raise ValueError('not a valid settings file') for line in contents.splitlines(): - line = line.strip() + line = line.strip() # noqa: PLW2901 if line.startswith(';'): continue if line.startswith('[') and line.endswith(']'): @@ -821,7 +845,7 @@ def __init__(self, filename: str | os.PathLike[Any], /) -> None: self.filename = filename = os.fspath(filename) - self._fh = open(filename, 'rb') + self._fh = open(filename, 'rb') # noqa: SIM115 try: self._fromfile() except Exception: @@ -889,7 +913,7 @@ struct.unpack('<' + ('I' * 109), self._fh.read(436)) ) nextsec = self.difat_start - for i in range(self.difat_len): + for _i in range(self.difat_len): if nextsec >= CompoundFile.MAXREGSID: raise OifFileError(f'{nextsec=} >= {CompoundFile.MAXREGSID=}') sec = struct.unpack(secfmt, self._sec_read(nextsec)) @@ -911,10 +935,9 @@ self._dirs = [] for sector in self._sec_chain(self.dir_start): for i in range(0, self.sec_size, 128): - direntry = DirectoryEntry( - sector[i : i + 128], self.version_major + self._dirs.append( + DirectoryEntry(sector[i : i + 128], self.version_major) ) - self._dirs.append(direntry) # read root storage if len(self._dirs) <= 0: raise OifFileError('no directories found') @@ -946,11 +969,11 @@ visited[dirid] = True de = dirs[dirid] if de.is_stream: - yield join(path + [de.name]), de + yield join([*path, de.name]), de yield from parse(de.left_sibling_id, path) yield from parse(de.right_sibling_id, path) if de.is_storage: - yield from parse(de.child_id, path + [de.name]) + yield from parse(de.child_id, [*path, de.name]) self._files = dict(parse(self._dirs[0].child_id, [])) @@ -1016,10 +1039,15 @@ """Close file handle.""" self._fh.close() - def __enter__(self) -> CompoundFile: + def __enter__(self) -> Self: return self - def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: self.close() def __repr__(self) -> str: @@ -1061,20 +1089,20 @@ """ __slots__ = ( - 'name', - 'entry_type', - 'color', - 'left_sibling_id', - 'right_sibling_id', 'child_id', 'clsid', - 'user_flags', + 'color', 'create_time', + 'entry_type', + 'is_storage', + 'is_stream', + 'left_sibling_id', 'modify_time', + 'name', + 'right_sibling_id', 'sector_start', 'stream_size', - 'is_stream', - 'is_storage', + 'user_flags', ) name: str @@ -1154,7 +1182,8 @@ ) -> str: """Return pretty-print of nested dictionary.""" result = [] - for k, v in sorted(adict.items(), key=lambda x: str(x[0]).lower()): + for item in sorted(adict.items(), key=lambda x: str(x[0]).lower()): + k, v = item if any(k.startswith(e) for e in excludes): continue if isinstance(v, dict): @@ -1216,15 +1245,15 @@ argv = sys.argv if len(argv) != 2: - print('Usage: python -m oiffile file_or_directory') + print('Usage: python -m oiffile file_or_directory') # noqa: T201 return 0 from matplotlib import pyplot from tifffile import imshow with OifFile(sys.argv[1]) as oif: - print(oif) - print(oif.mainfile) + print(oif) # noqa: T201 + print(oif.mainfile) # noqa: T201 for series in oif.series: # print(series) image = series.asarray() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oiffile-2025.5.10/pyproject.toml new/oiffile-2025.12.12/pyproject.toml --- old/oiffile-2025.5.10/pyproject.toml 2025-05-10 21:22:30.000000000 +0200 +++ new/oiffile-2025.12.12/pyproject.toml 2025-12-12 03:24:02.000000000 +0100 @@ -1,3 +1,13 @@ [build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" + +[tool.black] +line-length = 79 +target-version = ["py311", "py312", "py313", "py314"] +skip-string-normalization = true + +[tool.isort] +known_first_party = ["oiffile"] +profile = "black" +line_length = 79 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oiffile-2025.5.10/setup.py new/oiffile-2025.12.12/setup.py --- old/oiffile-2025.5.10/setup.py 2025-05-10 21:22:30.000000000 +0200 +++ new/oiffile-2025.12.12/setup.py 2025-12-12 03:24:02.000000000 +0100 @@ -47,7 +47,7 @@ re.MULTILINE | re.DOTALL, ) readme = '\n'.join( - [description, '=' * len(description)] + readme.splitlines()[1:] + [description, '=' * len(description), *readme.splitlines()[1:]] ) if 'sdist' in sys.argv: @@ -84,7 +84,7 @@ }, packages=['oiffile'], package_data={'oiffile': ['py.typed']}, - python_requires='>=3.10', + python_requires='>=3.11', install_requires=['numpy', 'tifffile'], extras_require={'all': ['matplotlib']}, platforms=['any'], @@ -94,7 +94,6 @@ 'Intended Audience :: Developers', 'Operating System :: OS Independent', 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: 3.13',
