diff --git a/docs/community/policies.md b/docs/community/policies.md index aa806bc02..07e3e64a9 100644 --- a/docs/community/policies.md +++ b/docs/community/policies.md @@ -24,4 +24,4 @@ Deprecations in the Parcels codebase between minor releases will be handled usin These changes will be communicated in release notes. -Note that objects and modules won't be deprecated between minor releases, and that deprecations between major releases can be done at will as API changes are already expected. +Deprecations of classes or modules between minor releases will be avoided, except in the instance where it is deemed to have little to no impact on the end user (e.g., if the class/module was mistakenly included in the Public API to begin with, and isn't used in any user scripts or tutorial notebooks). diff --git a/parcels/grid.py b/parcels/grid.py index 02763fdf9..0fefe5153 100644 --- a/parcels/grid.py +++ b/parcels/grid.py @@ -92,6 +92,14 @@ def __init__( self._add_last_periodic_data_timestep = False self.depth_field = None + def __repr__(self): + with np.printoptions(precision=50): + return ( + f"{type(self).__name__}(" + f"lon={self.lon!r}, lat={self.lat!r}, time={self.time!r}, " + f"time_origin={self.time_origin!r}, mesh={self.mesh!r})" + ) + @staticmethod def create_grid( lon: npt.ArrayLike, diff --git a/parcels/particle.py b/parcels/particle.py index cd524275b..dc8489363 100644 --- a/parcels/particle.py +++ b/parcels/particle.py @@ -48,7 +48,13 @@ def __set__(self, instance, value): setattr(instance, "_%s" % self.name, value) def __repr__(self): - return f"PVar<{self.name}|{self.dtype}>" + return ( + f"{type(self).__name__}(" + f"name={self.name!r}, " + f"dtype={self.dtype.__name__}, " + f"initial={self.initial!r}, " + f"to_write={self.to_write!r})" + ) def is64bit(self): """Check whether variable is 64-bit.""" diff --git a/tests/test_reprs.py b/tests/test_reprs.py new file mode 100644 index 000000000..c3d8f6f5a --- /dev/null +++ b/tests/test_reprs.py @@ -0,0 +1,43 @@ +from typing import Any, Type + +import numpy as np + +from parcels import Grid, TimeConverter +from parcels.grid import RectilinearGrid + + +def validate_simple_repr(class_: Type, kwargs: dict[str, Any]): + """Test that the repr of an object contains all the arguments. This only works for simple objects.""" + obj = class_(**kwargs) + obj_repr = repr(obj) + + for param in kwargs.keys(): + assert param in obj_repr + # skip `assert repr(value) in obj_repr` as this is not always true if init does processing on the value + assert class_.__name__ in obj_repr + + +# def test_variable_repr(): +# """Test arguments are in the repr of a Variable object""" +# kwargs = dict(name='test', dtype='float32', initial=0, to_write=True) +# validate_repr(Variable, kwargs) + + +def test_grid_repr(): + """Test arguments are in the repr of a Grid object""" + kwargs = dict( + lon=np.array([1, 2, 3]), lat=np.array([4, 5, 6]), time=None, time_origin=TimeConverter(), mesh="spherical" + ) + validate_simple_repr(Grid, kwargs) + + +def test_rectilineargrid_repr(): + """ + Test arguments are in the repr of a RectilinearGrid object. + + Mainly to test inherited repr is correct. + """ + kwargs = dict( + lon=np.array([1, 2, 3]), lat=np.array([4, 5, 6]), time=None, time_origin=TimeConverter(), mesh="spherical" + ) + validate_simple_repr(RectilinearGrid, kwargs)