Skip to content

Commit 13b255f

Browse files
simonjayhawkinsjreback
authored andcommitted
CLN: more consistent error message for ExtensionDtype.construct_from_string (#30247)
1 parent 7256c27 commit 13b255f

File tree

9 files changed

+24
-15
lines changed

9 files changed

+24
-15
lines changed

pandas/core/arrays/numpy_.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,12 @@ def _is_boolean(self):
7272

7373
@classmethod
7474
def construct_from_string(cls, string):
75-
return cls(np.dtype(string))
75+
try:
76+
return cls(np.dtype(string))
77+
except TypeError as err:
78+
raise TypeError(
79+
f"Cannot construct a 'PandasDtype' from '{string}'"
80+
) from err
7681

7782
def construct_array_type(cls):
7883
return PandasArray

pandas/core/arrays/sparse/dtype.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def construct_from_string(cls, string):
199199
-------
200200
SparseDtype
201201
"""
202-
msg = f"Could not construct SparseDtype from '{string}'"
202+
msg = f"Cannot construct a 'SparseDtype' from '{string}'"
203203
if string.startswith("Sparse"):
204204
try:
205205
sub_type, has_fill_value = cls._parse_subtype(string)
@@ -208,7 +208,7 @@ def construct_from_string(cls, string):
208208
else:
209209
result = SparseDtype(sub_type)
210210
msg = (
211-
f"Could not construct SparseDtype from '{string}'.\n\nIt "
211+
f"Cannot construct a 'SparseDtype' from '{string}'.\n\nIt "
212212
"looks like the fill_value in the string is not "
213213
"the default for the dtype. Non-default fill_values "
214214
"are not supported. Use the 'SparseDtype()' "

pandas/core/dtypes/dtypes.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ def construct_from_string(cls, string: str_type):
732732
datetime64[ns, UTC]
733733
"""
734734
if isinstance(string, str):
735-
msg = "Could not construct DatetimeTZDtype from '{string}'"
735+
msg = f"Cannot construct a 'DatetimeTZDtype' from '{string}'"
736736
match = cls._match.match(string)
737737
if match:
738738
d = match.groupdict()
@@ -743,10 +743,10 @@ def construct_from_string(cls, string: str_type):
743743
# pytz timezone (actually pytz.UnknownTimeZoneError).
744744
# TypeError if we pass a nonsense tz;
745745
# ValueError if we pass a unit other than "ns"
746-
raise TypeError(msg.format(string=string)) from err
747-
raise TypeError(msg.format(string=string))
746+
raise TypeError(msg) from err
747+
raise TypeError(msg)
748748

749-
raise TypeError("Could not construct DatetimeTZDtype")
749+
raise TypeError("Cannot construct a 'DatetimeTZDtype'")
750750

751751
def __str__(self) -> str_type:
752752
return "datetime64[{unit}, {tz}]".format(unit=self.unit, tz=self.tz)
@@ -883,7 +883,7 @@ def construct_from_string(cls, string):
883883
return cls(freq=string)
884884
except ValueError:
885885
pass
886-
raise TypeError("could not construct PeriodDtype")
886+
raise TypeError(f"Cannot construct a 'PeriodDtype' from '{string}'")
887887

888888
def __str__(self) -> str_type:
889889
return self.name
@@ -1054,6 +1054,7 @@ def construct_from_string(cls, string):
10541054
return cls(string)
10551055

10561056
msg = (
1057+
f"Cannot construct a 'IntervalDtype' from '{string}'.\n\n"
10571058
"Incorrectly formatted string passed to constructor. "
10581059
"Valid formats include Interval or Interval[dtype] "
10591060
"where dtype is numeric, datetime, or timedelta"

pandas/tests/arrays/sparse/test_dtype.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def test_not_equal(a, b):
8383

8484
def test_construct_from_string_raises():
8585
with pytest.raises(
86-
TypeError, match="Could not construct SparseDtype from 'not a dtype'"
86+
TypeError, match="Cannot construct a 'SparseDtype' from 'not a dtype'"
8787
):
8888
SparseDtype.construct_from_string("not a dtype")
8989

pandas/tests/dtypes/test_dtypes.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -236,15 +236,15 @@ def test_compat(self):
236236
def test_construction_from_string(self):
237237
result = DatetimeTZDtype.construct_from_string("datetime64[ns, US/Eastern]")
238238
assert is_dtype_equal(self.dtype, result)
239-
msg = "Could not construct DatetimeTZDtype from 'foo'"
239+
msg = "Cannot construct a 'DatetimeTZDtype' from 'foo'"
240240
with pytest.raises(TypeError, match=msg):
241241
DatetimeTZDtype.construct_from_string("foo")
242242

243243
def test_construct_from_string_raises(self):
244244
with pytest.raises(TypeError, match="notatz"):
245245
DatetimeTZDtype.construct_from_string("datetime64[ns, notatz]")
246246

247-
msg = "^Could not construct DatetimeTZDtype"
247+
msg = "^Cannot construct a 'DatetimeTZDtype'"
248248
with pytest.raises(TypeError, match=msg):
249249
# list instead of string
250250
DatetimeTZDtype.construct_from_string(["datetime64[ns, notatz]"])

pandas/tests/extension/arrow/arrays.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def construct_from_string(cls, string):
3333
if string == cls.name:
3434
return cls()
3535
else:
36-
raise TypeError(f"Cannot construct a '{cls}' from '{string}'")
36+
raise TypeError(f"Cannot construct a '{cls.__name__}' from '{string}'")
3737

3838
@classmethod
3939
def construct_array_type(cls):

pandas/tests/extension/base/dtype.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,8 @@ def test_eq(self, dtype):
9898
def test_construct_from_string(self, dtype):
9999
dtype_instance = type(dtype).construct_from_string(dtype.name)
100100
assert isinstance(dtype_instance, type(dtype))
101-
with pytest.raises(TypeError):
101+
102+
def test_construct_from_string_another_type_raises(self, dtype):
103+
msg = f"Cannot construct a '{type(dtype).__name__}' from 'another_type'"
104+
with pytest.raises(TypeError, match=msg):
102105
type(dtype).construct_from_string("another_type")

pandas/tests/extension/decimal/array.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def construct_from_string(cls, string):
4040
if string == cls.name:
4141
return cls()
4242
else:
43-
raise TypeError(f"Cannot construct a '{cls}' from '{string}'")
43+
raise TypeError(f"Cannot construct a '{cls.__name__}' from '{string}'")
4444

4545
@property
4646
def _is_numeric(self):

pandas/tests/extension/json/array.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def construct_from_string(cls, string):
4444
if string == cls.name:
4545
return cls()
4646
else:
47-
raise TypeError("Cannot construct a '{}' from '{}'".format(cls, string))
47+
raise TypeError(f"Cannot construct a '{cls.__name__}' from '{string}'")
4848

4949

5050
class JSONArray(ExtensionArray):

0 commit comments

Comments
 (0)