Skip to content

Commit

Permalink
CLN: more consistent error message for ExtensionDtype.construct_from_…
Browse files Browse the repository at this point in the history
…string (pandas-dev#30247)
  • Loading branch information
simonjayhawkins authored and proost committed Dec 19, 2019
1 parent a4954e3 commit 9bf27fe
Show file tree
Hide file tree
Showing 9 changed files with 24 additions and 15 deletions.
7 changes: 6 additions & 1 deletion pandas/core/arrays/numpy_.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ def _is_boolean(self):

@classmethod
def construct_from_string(cls, string):
return cls(np.dtype(string))
try:
return cls(np.dtype(string))
except TypeError as err:
raise TypeError(
f"Cannot construct a 'PandasDtype' from '{string}'"
) from err

def construct_array_type(cls):
return PandasArray
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/arrays/sparse/dtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def construct_from_string(cls, string):
-------
SparseDtype
"""
msg = f"Could not construct SparseDtype from '{string}'"
msg = f"Cannot construct a 'SparseDtype' from '{string}'"
if string.startswith("Sparse"):
try:
sub_type, has_fill_value = cls._parse_subtype(string)
Expand All @@ -208,7 +208,7 @@ def construct_from_string(cls, string):
else:
result = SparseDtype(sub_type)
msg = (
f"Could not construct SparseDtype from '{string}'.\n\nIt "
f"Cannot construct a 'SparseDtype' from '{string}'.\n\nIt "
"looks like the fill_value in the string is not "
"the default for the dtype. Non-default fill_values "
"are not supported. Use the 'SparseDtype()' "
Expand Down
11 changes: 6 additions & 5 deletions pandas/core/dtypes/dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ def construct_from_string(cls, string: str_type):
datetime64[ns, UTC]
"""
if isinstance(string, str):
msg = "Could not construct DatetimeTZDtype from '{string}'"
msg = f"Cannot construct a 'DatetimeTZDtype' from '{string}'"
match = cls._match.match(string)
if match:
d = match.groupdict()
Expand All @@ -743,10 +743,10 @@ def construct_from_string(cls, string: str_type):
# pytz timezone (actually pytz.UnknownTimeZoneError).
# TypeError if we pass a nonsense tz;
# ValueError if we pass a unit other than "ns"
raise TypeError(msg.format(string=string)) from err
raise TypeError(msg.format(string=string))
raise TypeError(msg) from err
raise TypeError(msg)

raise TypeError("Could not construct DatetimeTZDtype")
raise TypeError("Cannot construct a 'DatetimeTZDtype'")

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

def __str__(self) -> str_type:
return self.name
Expand Down Expand Up @@ -1054,6 +1054,7 @@ def construct_from_string(cls, string):
return cls(string)

msg = (
f"Cannot construct a 'IntervalDtype' from '{string}'.\n\n"
"Incorrectly formatted string passed to constructor. "
"Valid formats include Interval or Interval[dtype] "
"where dtype is numeric, datetime, or timedelta"
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/arrays/sparse/test_dtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test_not_equal(a, b):

def test_construct_from_string_raises():
with pytest.raises(
TypeError, match="Could not construct SparseDtype from 'not a dtype'"
TypeError, match="Cannot construct a 'SparseDtype' from 'not a dtype'"
):
SparseDtype.construct_from_string("not a dtype")

Expand Down
4 changes: 2 additions & 2 deletions pandas/tests/dtypes/test_dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,15 @@ def test_compat(self):
def test_construction_from_string(self):
result = DatetimeTZDtype.construct_from_string("datetime64[ns, US/Eastern]")
assert is_dtype_equal(self.dtype, result)
msg = "Could not construct DatetimeTZDtype from 'foo'"
msg = "Cannot construct a 'DatetimeTZDtype' from 'foo'"
with pytest.raises(TypeError, match=msg):
DatetimeTZDtype.construct_from_string("foo")

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

msg = "^Could not construct DatetimeTZDtype"
msg = "^Cannot construct a 'DatetimeTZDtype'"
with pytest.raises(TypeError, match=msg):
# list instead of string
DatetimeTZDtype.construct_from_string(["datetime64[ns, notatz]"])
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/extension/arrow/arrays.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def construct_from_string(cls, string):
if string == cls.name:
return cls()
else:
raise TypeError(f"Cannot construct a '{cls}' from '{string}'")
raise TypeError(f"Cannot construct a '{cls.__name__}' from '{string}'")

@classmethod
def construct_array_type(cls):
Expand Down
5 changes: 4 additions & 1 deletion pandas/tests/extension/base/dtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,8 @@ def test_eq(self, dtype):
def test_construct_from_string(self, dtype):
dtype_instance = type(dtype).construct_from_string(dtype.name)
assert isinstance(dtype_instance, type(dtype))
with pytest.raises(TypeError):

def test_construct_from_string_another_type_raises(self, dtype):
msg = f"Cannot construct a '{type(dtype).__name__}' from 'another_type'"
with pytest.raises(TypeError, match=msg):
type(dtype).construct_from_string("another_type")
2 changes: 1 addition & 1 deletion pandas/tests/extension/decimal/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def construct_from_string(cls, string):
if string == cls.name:
return cls()
else:
raise TypeError(f"Cannot construct a '{cls}' from '{string}'")
raise TypeError(f"Cannot construct a '{cls.__name__}' from '{string}'")

@property
def _is_numeric(self):
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/extension/json/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def construct_from_string(cls, string):
if string == cls.name:
return cls()
else:
raise TypeError("Cannot construct a '{}' from '{}'".format(cls, string))
raise TypeError(f"Cannot construct a '{cls.__name__}' from '{string}'")


class JSONArray(ExtensionArray):
Expand Down

0 comments on commit 9bf27fe

Please sign in to comment.