Skip to content

Commit

Permalink
Add version module that allows to compare versions in python
Browse files Browse the repository at this point in the history
  • Loading branch information
tmadlener committed Sep 18, 2024
1 parent 4615421 commit 3e8b383
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 15 deletions.
5 changes: 3 additions & 2 deletions python/podio/base_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@


from podio.frame_iterator import FrameCategoryIterator
from podio.version import Version


class BaseReaderMixin:
Expand Down Expand Up @@ -101,11 +102,11 @@ def current_file_version(self, edm_name=None):
version is requested
"""
if edm_name is None:
return self._reader.currentFileVersion()
return Version(self._reader.currentFileVersion())

if self._is_legacy:
raise RuntimeError("Legacy readers do not store any version info")
maybe_version = self._reader.currentFileVersion(edm_name)
if maybe_version.has_value():
return maybe_version.value()
return Version(maybe_version.value())
raise KeyError(f"No version information available for '{edm_name}'")
25 changes: 25 additions & 0 deletions python/podio/test_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env python3
"""Unittests for python version module"""

import unittest

from podio import version
from podio import __version__


class TestVersion(unittest.TestCase):
"""General unittests for the python bindings of Version"""

def test_build_version(self):
"""Make sure that the build version is set consistently (i.e. configured
correctly)"""
self.assertEqual(version.build_version, version.Version(__version__))

def test_version_comparison(self):
"""Make sure that version comparisons work"""
v1 = version.Version(1, 2, 3)
v2 = version.Version("0.4.2")
self.assertTrue(v1 > v2)

v3 = version.Version("1.2.3")
self.assertEqual(v3, v1)
63 changes: 53 additions & 10 deletions python/podio/version.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#!/usr/bin/env python3
"""Module that facilitates working with the podio::version::Version"""

from functools import total_ordering
from packaging import version

import ROOT

# NOTE: It is necessary that this can be found on the ROOT_INCLUDE_PATH
Expand All @@ -10,17 +13,57 @@
if ROOT.gInterpreter.LoadFile("podio/podioVersion.h") == 0: # noqa: E402
from ROOT import podio # noqa: E402 # pylint: disable=wrong-import-position

build_version = podio.version.build_version

@total_ordering
class Version:
"""A dedicated version class for podio versions, as they are returned by
the c++ interface.
def version_as_str(ver):
"""Stringify the version into the usual format
We make this so that version comparisons work as expected in python as well
"""

Args:
ver (podio.version.Version): A podio version
def __init__(self, *args):
"""Construct a python version from its c++ counterpart
Returns:
str: A stringified version of the version, in the format
MAJOR.MINOR.PATCH
"""
return f"{ver.major}.{ver.minor}.{ver.patch}"
Takes either a podio.version.Version, up to three numbers which are
interpreted as major, minor, patch or a valid (python) version string
"""
# We don't do a lot of validation here, we just convert everything into
# a string and then let the version parsing fail in case the inputs are
# wrong
ver = args[0]
if len(args) == 1:
if isinstance(ver, podio.version.Version):
ver = f"{ver.major}.{ver.minor}.{ver.patch}"
else:
ver = ".".join(str(v) for v in args)

self.version = version.Version(ver)

def __getattr__(self, attr):
"""Delegate attribute retrieval to the underlying version"""
return getattr(self.version, attr)

def __str__(self):
return str(self.version)

def __repr__(self):
return f"podio.Version({self.version!r})"

def __eq__(self, other):
if isinstance(other, Version):
return self.version == other.version
if isinstance(other, version.Version):
return self.version == other
return NotImplemented

def __lt__(self, other):
if isinstance(other, Version):
return self.version < other.version
if isinstance(other, version.Version):
return self.version < other
return NotImplemented


# The version with which podio has been built. Same as __version__
build_version = Version(podio.version.build_version)
5 changes: 2 additions & 3 deletions tools/podio-dump
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import yaml
from tabulate import tabulate

from podio_version import __version__
from podio.version import version_as_str


def print_general_info(reader, filename):
Expand All @@ -25,14 +24,14 @@ def print_general_info(reader, filename):
print(
f"input file: {filename}{legacy_text}\n"
" (written with podio version: "
f"{version_as_str(reader.current_file_version())})\n"
f"{reader.current_file_version()})\n"
)

print("datamodel model definitions stored in this file: ")
for edm_name in reader.datamodel_definitions:
try:
edm_version = reader.current_file_version(edm_name)
print(f" - {edm_name} ({version_as_str(edm_version)})")
print(f" - {edm_name} ({edm_version})")
except KeyError:
print(f" - {edm_name}")

Expand Down

0 comments on commit 3e8b383

Please sign in to comment.