From b26f672203d66d3f30091e4e175c195ffba7154f Mon Sep 17 00:00:00 2001 From: Avinash Pancham Date: Tue, 9 Feb 2021 23:34:06 +0100 Subject: [PATCH] BUG: Timedelta input string with only symbols and no digits raises an error (GH39710) --- doc/source/whatsnew/v1.3.0.rst | 2 +- pandas/_libs/tslibs/timedeltas.pyx | 4 ++++ .../scalar/timedelta/test_constructors.py | 20 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index a3a9a4c5eda08..0ef4361c5fb53 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -292,7 +292,7 @@ Timedelta ^^^^^^^^^ - Bug in constructing :class:`Timedelta` from ``np.timedelta64`` objects with non-nanosecond units that are out of bounds for ``timedelta64[ns]`` (:issue:`38965`) - Bug in constructing a :class:`TimedeltaIndex` incorrectly accepting ``np.datetime64("NaT")`` objects (:issue:`39462`) -- +- Bug in constructing :class:`Timedelta` from input string with only symbols and no digits failed to raise an error (:issue:`39710`) Timezones ^^^^^^^^^ diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 748a4c27e64ad..d661806a496d2 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -496,6 +496,10 @@ cdef inline int64_t parse_timedelta_string(str ts) except? -1: else: raise ValueError("unit abbreviation w/o a number") + # we only have symbols and no numbers + elif len(number) == 0: + raise ValueError("symbols w/o a number") + # treat as nanoseconds # but only if we don't have anything else else: diff --git a/pandas/tests/scalar/timedelta/test_constructors.py b/pandas/tests/scalar/timedelta/test_constructors.py index 64d5a5e9b3fff..3cc5bfaeb73e8 100644 --- a/pandas/tests/scalar/timedelta/test_constructors.py +++ b/pandas/tests/scalar/timedelta/test_constructors.py @@ -1,4 +1,5 @@ from datetime import timedelta +from itertools import product import numpy as np import pytest @@ -337,3 +338,22 @@ def test_string_with_unit(constructor, value, unit, expectation): exp, match = expectation with pytest.raises(exp, match=match): _ = constructor(value, unit=unit) + + +@pytest.mark.parametrize( + "value", + [ + "".join(elements) + for repetition in (1, 2) + for elements in product("+-, ", repeat=repetition) + ], +) +def test_string_without_numbers(value): + # GH39710 Timedelta input string with only symbols and no digits raises an error + msg = ( + "symbols w/o a number" + if value != "--" + else "only leading negative signs are allowed" + ) + with pytest.raises(ValueError, match=msg): + Timedelta(value)