From 22a9b60f580550f777932ded803da42b4564be59 Mon Sep 17 00:00:00 2001 From: Drew Camron Date: Thu, 2 Nov 2023 15:20:04 -0600 Subject: [PATCH] Fix arg handling for arrays etc Update dewpoint_from_specific_humidity backwards compatibility layer to more completely handle mixed parameters in old function signature. Fixes array inputs and ordering of signature. --- src/metpy/calc/thermo.py | 20 +++++++++++++------- tests/calc/test_thermo.py | 15 ++++++++++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/metpy/calc/thermo.py b/src/metpy/calc/thermo.py index 6664f572a83..bfe43245b92 100644 --- a/src/metpy/calc/thermo.py +++ b/src/metpy/calc/thermo.py @@ -2,6 +2,8 @@ # Distributed under the terms of the BSD 3-Clause License. # SPDX-License-Identifier: BSD-3-Clause """Contains a collection of thermodynamic calculations.""" +from inspect import Parameter, Signature, signature + import numpy as np import scipy.integrate as si import scipy.optimize as so @@ -3924,17 +3926,21 @@ def dewpoint_from_specific_humidity(*args, **kwargs): to calculate vapor partial pressure :math:`e` for dewpoint calculation input. See :func:`~dewpoint` for additional information. """ - if (len(args) + len(kwargs)) > 2: + sig = Signature([Parameter('pressure', Parameter.POSITIONAL_OR_KEYWORD), + Parameter('temperature', Parameter.POSITIONAL_OR_KEYWORD), + Parameter('specific_humidity', Parameter.POSITIONAL_OR_KEYWORD)]) + + try: + bound_args = sig.bind(*args, **kwargs) _warnings.warn( 'Temperature argument is unused and will be deprecated in a future version.', PendingDeprecationWarning) + except TypeError: + sig = signature(_dewpoint_from_specific_humidity) + bound_args = sig.bind(*args, **kwargs) - pressure = kwargs.pop('pressure', None) - specific_humidity = kwargs.pop('specific_humidity', None) - - return _dewpoint_from_specific_humidity( - pressure if pressure else args[0], - specific_humidity if specific_humidity else args[-1]) + return _dewpoint_from_specific_humidity(bound_args.arguments['pressure'], + bound_args.arguments['specific_humidity']) @preprocess_and_wrap( diff --git a/tests/calc/test_thermo.py b/tests/calc/test_thermo.py index d7937dd4d8f..a79cc661864 100644 --- a/tests/calc/test_thermo.py +++ b/tests/calc/test_thermo.py @@ -1814,8 +1814,9 @@ def test_dewpoint_specific_humidity_old_signature(): p = 1013.25 * units.mbar temperature = 20. * units.degC q = 0.012 * units.dimensionless - with pytest.raises(ValueError, match='changed in version'): - dewpoint_from_specific_humidity(q, temperature, p) + with pytest.deprecated_call(match='Temperature argument'): + with pytest.raises(ValueError, match='changed in version'): + dewpoint_from_specific_humidity(q, temperature, p) def test_dewpoint_specific_humidity_kwargs(): @@ -1836,7 +1837,7 @@ def test_dewpoint_specific_humidity_three_mixed_args_kwargs(): q = 0.012 * units.dimensionless with pytest.deprecated_call(match='Temperature argument'): td = dewpoint_from_specific_humidity( - p, temperature=temperature, specific_humidity=q) + p, temperature, specific_humidity=q) assert_almost_equal(td, 17.036 * units.degC, 3) @@ -1857,6 +1858,14 @@ def test_dewpoint_specific_humidity_two_args(): assert_almost_equal(td, 17.036 * units.degC, 3) +def test_dewpoint_specific_humidity_arrays(): + """Test function arg handling can process arrays.""" + p = 1013.25 * units.mbar + q = np.tile(0.012 * units.dimensionless, (3, 2)) + td = dewpoint_from_specific_humidity(p, specific_humidity=q) + assert_almost_equal(td, np.tile(17.036 * units.degC, (3, 2)), 3) + + def test_lfc_not_below_lcl(): """Test sounding where LFC appears to be (but isn't) below LCL.""" levels = np.array([1002.5, 1001.7, 1001., 1000.3, 999.7, 999., 998.2, 977.9,