From dd310692372dd48c10f9a1c263058a2f7ddf60d6 Mon Sep 17 00:00:00 2001 From: Sylwester Arabas Date: Sun, 10 Sep 2023 13:08:22 +0200 Subject: [PATCH] Ensuring all classes are accessible after importing only the main PySDM package. Closes #1124 (#1135) --- PySDM/__init__.py | 5 +-- PySDM/dynamics/collisions/__init__.py | 2 ++ PySDM/environments/__init__.py | 1 + PySDM/initialisation/__init__.py | 3 ++ tests/unit_tests/test_imports.py | 47 +++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 tests/unit_tests/test_imports.py diff --git a/PySDM/__init__.py b/PySDM/__init__.py index d7c096250..f04654dd8 100644 --- a/PySDM/__init__.py +++ b/PySDM/__init__.py @@ -2,7 +2,7 @@ """ PySDM offers a set of building blocks for development of atmospheric cloud simulation systems revolving around the particle-based microphysics modelling concept -and the Super-Droplet Method algorithm ([Shima et al. 2009](http://doi.org/10.1002/qj.441)) +and the Super-Droplet Method algorithm ([Shima et al. 2009](https://doi.org/10.1002/qj.441)) for numerically tackling the probabilistic representation of particle coagulation. For an overview of PySDM, see [Bartman, Arabas et al. 2021](https://arxiv.org/abs/2103.17238). @@ -14,7 +14,7 @@ [README.md file](https://github.com/open-atmos/PySDM/blob/master/README.md) which also includes basic usage examples in **Python**, **Julia** and **Matlab**. -A set of more elaborate examples engineered in Python and accompanied with Jupyter +A set of more elaborate examples engineered in Python and accompanied by Jupyter notebooks are maintained in the [PySDM-examples package](https://github.com/open-atmos/PySDM-examples). @@ -24,6 +24,7 @@ from pkg_resources import DistributionNotFound, VersionConflict, get_distribution +from . import environments, exporters, products from .builder import Builder from .formulae import Formulae from .particulator import Particulator diff --git a/PySDM/dynamics/collisions/__init__.py b/PySDM/dynamics/collisions/__init__.py index f71707274..f51953339 100644 --- a/PySDM/dynamics/collisions/__init__.py +++ b/PySDM/dynamics/collisions/__init__.py @@ -7,3 +7,5 @@ breakup fragmentations `PySDM.dynamics.collisions.breakup_fragmentations` """ from PySDM.dynamics.collisions.collision import Breakup, Coalescence, Collision + +from . import collision_kernels diff --git a/PySDM/environments/__init__.py b/PySDM/environments/__init__.py index b42112706..8b182ffe0 100644 --- a/PySDM/environments/__init__.py +++ b/PySDM/environments/__init__.py @@ -4,5 +4,6 @@ `PySDM.environments.parcel.Parcel`, ... """ from .box import Box +from .kinematic_1d import Kinematic1D from .kinematic_2d import Kinematic2D from .parcel import Parcel diff --git a/PySDM/initialisation/__init__.py b/PySDM/initialisation/__init__.py index cc5bb4a63..d7ca3dbb9 100644 --- a/PySDM/initialisation/__init__.py +++ b/PySDM/initialisation/__init__.py @@ -2,6 +2,9 @@ initialisation logic, particle size spectra, sampling methods and wet radii equilibration """ +from . import sampling, spectra from .discretise_multiplicities import discretise_multiplicities from .equilibrate_wet_radii import equilibrate_wet_radii from .init_fall_momenta import init_fall_momenta + +from . import aerosol_composition # isort:skip diff --git a/tests/unit_tests/test_imports.py b/tests/unit_tests/test_imports.py new file mode 100644 index 000000000..d1d5bfa59 --- /dev/null +++ b/tests/unit_tests/test_imports.py @@ -0,0 +1,47 @@ +""" test ensuring that all needed __init__.py entries are in place """ +import pytest + +import PySDM + +CLASSES = ( + "Builder", + "Formulae", + "Particulator", + "attributes.chemistry.Acidity", + "attributes.physics.DryVolume", + "backends.CPU", + "backends.GPU", + "dynamics.Condensation", + "dynamics.collisions.breakup_fragmentations.AlwaysN", + "dynamics.collisions.coalescence_efficiencies.LowList1982Ec", + "dynamics.collisions.collision_kernels.Golovin", + "dynamics.terminal_velocity.RogersYau", + "environments.Box", + "environments.Kinematic1D", + "environments.Kinematic2D", + "environments.Parcel", + "exporters.VTKExporter", + "initialisation.aerosol_composition.DryAerosolMixture", + "initialisation.init_fall_momenta", + "initialisation.sampling.spectral_sampling.DeterministicSpectralSampling", + "initialisation.spectra.Lognormal", + "physics.constants_defaults", + "physics.diffusion_thermics.LoweEtAl2019", + "physics.si", + "products.size_spectral.EffectiveRadius", +) + + +class TestImports: + @staticmethod + @pytest.mark.parametrize("obj_path", CLASSES) + def test_imports(obj_path): + """one can import PySDM and then access classes from submodules, + like PySDM.environments.Box, etc""" + obj = PySDM + for attr in obj_path.split("."): + obj = getattr(obj, attr) + + @staticmethod + def test_classes_sorted(): + assert tuple(sorted(CLASSES)) == CLASSES