NOAA-OWP / ngen-cal

Tools for calibrating and configuring NextGen
https://github.com/NOAA-OWP/ngen-cal/wiki
Other
9 stars 17 forks source link

`PathPair` is not printable in `3.12`; Explicitly call `__init__` after instance has been established #193

Closed aaraney closed 1 month ago

aaraney commented 1 month ago

https://github.com/NOAA-OWP/ngen-cal/blob/0f5843d713e76fb0a23eef6e25e4d75d789b2f7d/python/ngen_conf/src/ngen/config/path_pair/path_pair.py#L86

diff --git a/python/ngen_conf/src/ngen/config/path_pair/path_pair.py b/python/ngen_conf/src/ngen/config/path_pair/path_pair.py
index f829676..57275ab 100644
--- a/python/ngen_conf/src/ngen/config/path_pair/path_pair.py
+++ b/python/ngen_conf/src/ngen/config/path_pair/path_pair.py
@@ -84,6 +84,8 @@ class PathPair(AbstractPathPairMixin[T], Path, Generic[T]):
             inner = _MaybeInner[cls._parameters[0]](inner=inner).inner  # type: ignore
         cls = WindowsPathPair[T] if os.name == "nt" else PosixPathPair[T]
         self: WindowsPathPair[T] | PosixPathPair[T] = Path.__new__(cls, *args, **kwargs)
+        # explicitly call __init__ to setup instance
+        self.__init__(*args, **kwargs)
         self._inner = inner  # type: ignore
         self._serializer = serializer  # type: ignore
         self._deserializer = deserializer  # type: ignore

A change in pathlib.PurePath introduced in python 3.12 seems to cause an issue when trying to call __str__ (or __repr__) on a PathPair instance. The face value solution is to explicitly "setup" the PosixPathPath or WindowsPathPair instance by calling it's __init__ method. I need to investigate why this is the case document any repercussions of this solution.

aaraney commented 1 month ago

Digging a bit more into this, python 3.12's pathlib added a __init__ implementation to pathlib.PurePath (this is what all pathlib types inherit from). pahtlib.PurePath.__init__ sets a few instance variables that previous versions of python didnt as they did not explicitly implement __init__.

This explains why we are seeing this issue in 3.12 b.c. __init__ is not being called after __new__.