From 7ef1011d56000433fc4963900d3458fcc2e6324b Mon Sep 17 00:00:00 2001 From: gaoflow Date: Tue, 9 Jun 2026 17:42:42 +0200 Subject: [PATCH] BUG: raise a clear error when cwt() is given a discrete wavelet (gh-776) Passing a discrete wavelet, e.g. cwt(data, scales, 'coif1'), crashed with a confusing `AttributeError: 'Wavelet' object has no attribute 'complex_cwt'`, because `complex_cwt` exists only on ContinuousWavelet. Validate that the resolved wavelet is continuous and otherwise raise a ValueError that names the offending wavelet and points to pywt.wavelist(kind='continuous'). --- pywt/_cwt.py | 6 ++++++ pywt/tests/test_cwt_wavelets.py | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/pywt/_cwt.py b/pywt/_cwt.py index 511582c7..0bea72c4 100644 --- a/pywt/_cwt.py +++ b/pywt/_cwt.py @@ -111,6 +111,12 @@ def cwt(data, scales, wavelet, sampling_period=1., method='conv', axis=-1, dt_cplx = np.result_type(dt, np.complex64) if not isinstance(wavelet, (ContinuousWavelet, Wavelet)): wavelet = DiscreteContinuousWavelet(wavelet) + if not isinstance(wavelet, ContinuousWavelet): + raise ValueError( + f"cwt() requires a continuous wavelet, but {wavelet.name!r} is a " + f"discrete wavelet. Use a continuous wavelet such as those returned " + f"by pywt.wavelist(kind='continuous') (e.g. 'morl', 'mexh', 'cmor')." + ) scales = np.atleast_1d(scales) if np.any(scales <= 0): diff --git a/pywt/tests/test_cwt_wavelets.py b/pywt/tests/test_cwt_wavelets.py index 9925a697..90652f37 100644 --- a/pywt/tests/test_cwt_wavelets.py +++ b/pywt/tests/test_cwt_wavelets.py @@ -480,3 +480,16 @@ def test_continuous_wavelet_pickle(tmpdir): wavelet2 = pickle.load(f) assert isinstance(wavelet2, pywt.ContinuousWavelet) assert wavelet2.name == wavelet.name + + +def test_cwt_discrete_wavelet_raises(): + # A discrete wavelet such as 'coif1' has no continuous form; cwt should + # raise a clear error rather than an opaque AttributeError (gh-776). + data = np.ones(100) + for bad in ['coif1', 'db2', pywt.Wavelet('coif1')]: + with pytest.raises(ValueError, match='continuous wavelet'): + pywt.cwt(data, [1, 2], bad) + + # a continuous wavelet still works + out, _ = pywt.cwt(data, [1, 2], 'morl') + assert out.shape == (2, 100)