Skip to content

Commit c2d57bd

Browse files
committed
Squashed commit of the following:
commit 7714e79 Author: Tom Augspurger <[email protected]> Date: Wed Oct 3 10:13:06 2018 -0500 Always return ndarray commit 1921c6f Merge: 01f7366 fea27f0 Author: Tom Augspurger <[email protected]> Date: Wed Oct 3 09:50:30 2018 -0500 Merge remote-tracking branch 'upstream/master' into combine-exception commit fea27f0 Author: Tom Augspurger <[email protected]> Date: Wed Oct 3 08:49:44 2018 -0500 CI: pin moto to 1.3.4 (pandas-dev#22959) commit 15d32bb Author: jbrockmendel <[email protected]> Date: Wed Oct 3 04:32:35 2018 -0700 [CLN] Dispatch (some) Frame ops to Series, avoiding _data.eval (pandas-dev#22019) * avoid casting to object dtype in mixed-type frames * Dispatch to Series ops in _combine_match_columns * comment * docstring * flake8 fixup * dont bother with try_cast_result * revert non-central change * simplify * revert try_cast_results * revert non-central changes * Fixup typo syntaxerror * simplify assertion * use dispatch_to_series in combine_match_columns * Pass unwrapped op where appropriate * catch correct error * whatsnew note * comment * whatsnew section * remove unnecessary tester * doc fixup commit 3e3256b Author: alimcmaster1 <[email protected]> Date: Wed Oct 3 12:23:22 2018 +0100 Allow passing a mask to NanOps (pandas-dev#22865) commit e756e99 Author: jbrockmendel <[email protected]> Date: Wed Oct 3 02:19:27 2018 -0700 CLN: Use is_period_dtype instead of ABCPeriodIndex checks (pandas-dev#22958) commit 03181f0 Author: Wenhuan <[email protected]> Date: Wed Oct 3 15:28:07 2018 +0800 BUG: fix Series(extension array) + extension array values addition (pandas-dev#22479) commit 04ea51d Author: Joris Van den Bossche <[email protected]> Date: Wed Oct 3 09:24:36 2018 +0200 CLN: small clean-up of IntervalIndex (pandas-dev#22956) commit b0f9a10 Author: Tony Tao <[email protected]> Date: Tue Oct 2 19:01:08 2018 -0500 DOC GH22893 Fix docstring of groupby in pandas/core/generic.py (pandas-dev#22920) commit 08ecba8 Author: jbrockmendel <[email protected]> Date: Tue Oct 2 14:22:53 2018 -0700 BUG: fix DataFrame+DataFrame op with timedelta64 dtype (pandas-dev#22696) commit c44bad2 Author: Pamela Wu <[email protected]> Date: Tue Oct 2 17:16:25 2018 -0400 CLN GH22873 Replace base excepts in pandas/core (pandas-dev#22901) commit 8e749a3 Author: Pamela Wu <[email protected]> Date: Tue Oct 2 17:14:48 2018 -0400 CLN GH22874 replace bare excepts in pandas/io/pytables.py (pandas-dev#22919) commit 1102a33 Author: Joris Van den Bossche <[email protected]> Date: Tue Oct 2 22:31:36 2018 +0200 DOC/CLN: clean-up shared_docs in generic.py (pandas-dev#20074) commit 01f7366 Merge: 5372134 9caf048 Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 13:50:28 2018 -0500 Merge remote-tracking branch 'upstream/master' into combine-exception commit 9caf048 Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 13:25:22 2018 -0500 CI: change windows vm image (pandas-dev#22948) commit 5372134 Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 11:35:07 2018 -0500 fixed move commit ce1a3c6 Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 11:32:11 2018 -0500 fixed move commit b9c7e4b Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 11:28:57 2018 -0500 remove old note commit a4a2933 Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 11:24:48 2018 -0500 handle test commit be63feb Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 11:19:17 2018 -0500 move test commit 0eef0cf Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 11:18:18 2018 -0500 move back commit 2183f7b Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 11:17:28 2018 -0500 api commit 85fc5d8 Merge: 9059c0d 1d9f76c Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 11:15:52 2018 -0500 Merge remote-tracking branch 'upstream/master' into combine-exception commit 1d9f76c Author: Joris Van den Bossche <[email protected]> Date: Tue Oct 2 17:11:11 2018 +0200 CLN: remove Index._to_embed (pandas-dev#22879) * CLN: remove Index._to_embed * pep8 commit 6247da0 Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 08:50:41 2018 -0500 Provide default implementation for `data_repated` (pandas-dev#22935) commit 9059c0d Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 06:33:15 2018 -0500 Note commit 0c53f08 Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 06:30:54 2018 -0500 Imports commit ce94bf9 Author: Tom Augspurger <[email protected]> Date: Tue Oct 2 06:28:16 2018 -0500 Moves commit fdd43c4 Author: Tom Augspurger <[email protected]> Date: Mon Oct 1 21:26:09 2018 -0500 Closes pandas-dev#22850 commit 5ce06b5 Author: Matthew Roeschke <[email protected]> Date: Mon Oct 1 14:22:20 2018 -0700 BUG: to_datetime preserves name of Index argument in the result (pandas-dev#22918) * BUG: to_datetime preserves name of Index argument in the result * correct test
1 parent ff7c06c commit c2d57bd

File tree

10 files changed

+87
-38
lines changed

10 files changed

+87
-38
lines changed

pandas/core/arrays/base.py

+14-7
Original file line numberDiff line numberDiff line change
@@ -739,14 +739,22 @@ def _create_method(cls, op, coerce_to_dtype=True):
739739
----------
740740
op : function
741741
An operator that takes arguments op(a, b)
742-
coerce_to_dtype : bool
742+
coerce_to_dtype : bool, default True
743743
boolean indicating whether to attempt to convert
744-
the result to the underlying ExtensionArray dtype
745-
(default True)
744+
the result to the underlying ExtensionArray dtype.
745+
If it's not possible to create a new ExtensionArray with the
746+
values, an ndarray is returned instead.
746747
747748
Returns
748749
-------
749-
A method that can be bound to a method of a class
750+
Callable[[Any, Any], Union[ndarray, ExtensionArray]]
751+
A method that can be bound to a class. When used, the method
752+
receives the two arguments, one of which is the instance of
753+
this class, and should return an ExtensionArray or an ndarray.
754+
755+
Returning an ndarray may be necessary when the result of the
756+
`op` cannot be stored in the ExtensionArray. The dtype of the
757+
ndarray uses NumPy's normal inference rules.
750758
751759
Example
752760
-------
@@ -757,7 +765,6 @@ def _create_method(cls, op, coerce_to_dtype=True):
757765
in the class definition of MyExtensionArray to create the operator
758766
for addition, that will be based on the operator implementation
759767
of the underlying elements of the ExtensionArray
760-
761768
"""
762769

763770
def _binop(self, other):
@@ -780,12 +787,12 @@ def convert_values(param):
780787
a, b = zip(*res)
781788
res = (self._from_sequence(a),
782789
self._from_sequence(b))
783-
except TypeError:
790+
except Exception:
784791
pass
785792
else:
786793
try:
787794
res = self._from_sequence(res)
788-
except TypeError:
795+
except Exception:
789796
pass
790797

791798
return res

pandas/core/series.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -2323,10 +2323,14 @@ def combine(self, other, func, fill_value=None):
23232323
pass
23242324
elif is_extension_array_dtype(self.values):
23252325
# The function can return something of any type, so check
2326-
# if the type is compatible with the calling EA
2326+
# if the type is compatible with the calling EA.
23272327
try:
23282328
new_values = self._values._from_sequence(new_values)
23292329
except Exception:
2330+
# https://github.com/pandas-dev/pandas/issues/22850
2331+
# pandas has no control over what 3rd-party ExtensionArrays
2332+
# do in _values_from_sequence. We still want ops to work
2333+
# though, so we catch any regular Exception.
23302334
pass
23312335

23322336
return self._constructor(new_values, index=new_index, name=new_name)

pandas/tests/extension/base/ops.py

-4
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,6 @@ def test_divmod(self, data):
7878
self._check_divmod_op(s, divmod, 1, exc=TypeError)
7979
self._check_divmod_op(1, ops.rdivmod, s, exc=TypeError)
8080

81-
def test_divmod_series_array(self, data):
82-
s = pd.Series(data)
83-
self._check_divmod_op(s, divmod, data)
84-
8581
def test_add_series_with_extension_array(self, data):
8682
s = pd.Series(data)
8783
result = s + data
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from .array import DecimalArray, DecimalDtype, to_decimal, make_data
2+
3+
4+
__all__ = ['DecimalArray', 'DecimalDtype', 'to_decimal', 'make_data']

pandas/tests/extension/decimal/array.py

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import decimal
22
import numbers
3+
import random
34
import sys
45

56
import numpy as np
@@ -142,5 +143,9 @@ def to_decimal(values, context=None):
142143
return DecimalArray([decimal.Decimal(x) for x in values], context=context)
143144

144145

146+
def make_data():
147+
return [decimal.Decimal(random.random()) for _ in range(100)]
148+
149+
145150
DecimalArray._add_arithmetic_ops()
146151
DecimalArray._add_comparison_ops()

pandas/tests/extension/decimal/test_decimal.py

+46-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1+
import operator
12
import decimal
23

3-
import random
44
import numpy as np
55
import pandas as pd
66
import pandas.util.testing as tm
77
import pytest
88

99
from pandas.tests.extension import base
1010

11-
from .array import DecimalDtype, DecimalArray, to_decimal
12-
13-
14-
def make_data():
15-
return [decimal.Decimal(random.random()) for _ in range(100)]
11+
from .array import DecimalDtype, DecimalArray, make_data
1612

1713

1814
@pytest.fixture
@@ -294,3 +290,47 @@ def test_compare_array(self, data, all_compare_operators):
294290
other = pd.Series(data) * [decimal.Decimal(pow(2.0, i))
295291
for i in alter]
296292
self._compare_other(s, data, op_name, other)
293+
294+
295+
class DecimalArrayWithoutFromSequence(DecimalArray):
296+
"""Helper class for testing error handling in _from_sequence."""
297+
def _from_sequence(cls, scalars, dtype=None, copy=False):
298+
raise KeyError("For the test")
299+
300+
301+
class DecimalArrayWithoutCoercion(DecimalArrayWithoutFromSequence):
302+
@classmethod
303+
def _create_arithmetic_method(cls, op):
304+
return cls._create_method(op, coerce_to_dtype=False)
305+
306+
307+
DecimalArrayWithoutCoercion._add_arithmetic_ops()
308+
309+
310+
def test_combine_from_sequence_raises():
311+
# https://github.com/pandas-dev/pandas/issues/22850
312+
ser = pd.Series(DecimalArrayWithoutFromSequence([
313+
decimal.Decimal("1.0"),
314+
decimal.Decimal("2.0")
315+
]))
316+
result = ser.combine(ser, operator.add)
317+
318+
# note: object dtype
319+
expected = pd.Series([decimal.Decimal("2.0"),
320+
decimal.Decimal("4.0")], dtype="object")
321+
tm.assert_series_equal(result, expected)
322+
323+
324+
@pytest.mark.parametrize("class_", [DecimalArrayWithoutFromSequence,
325+
DecimalArrayWithoutCoercion])
326+
def test_scalar_ops_from_sequence_raises(class_):
327+
# op(EA, EA) should return an EA, or an ndarray if it's not possible
328+
# to return an EA with the return values.
329+
arr = class_([
330+
decimal.Decimal("1.0"),
331+
decimal.Decimal("2.0")
332+
])
333+
result = arr + arr
334+
expected = np.array([decimal.Decimal("2.0"), decimal.Decimal("4.0")],
335+
dtype="object")
336+
tm.assert_numpy_array_equal(result, expected)
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .array import JSONArray, JSONDtype, make_data
2+
3+
__all__ = ['JSONArray', 'JSONDtype', 'make_data']

pandas/tests/extension/json/array.py

+9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import collections
1414
import itertools
1515
import numbers
16+
import random
17+
import string
1618
import sys
1719

1820
import numpy as np
@@ -179,3 +181,10 @@ def _values_for_argsort(self):
179181
# cast them to an (N, P) array, instead of an (N,) array of tuples.
180182
frozen = [()] + [tuple(x.items()) for x in self]
181183
return np.array(frozen, dtype=object)[1:]
184+
185+
186+
def make_data():
187+
# TODO: Use a regular dict. See _NDFrameIndexer._setitem_with_indexer
188+
return [collections.UserDict([
189+
(random.choice(string.ascii_letters), random.randint(0, 100))
190+
for _ in range(random.randint(0, 10))]) for _ in range(100)]

pandas/tests/extension/json/test_json.py

+1-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import operator
22
import collections
3-
import random
4-
import string
53

64
import pytest
75

@@ -10,18 +8,11 @@
108
from pandas.compat import PY2, PY36
119
from pandas.tests.extension import base
1210

13-
from .array import JSONArray, JSONDtype
11+
from .array import JSONArray, JSONDtype, make_data
1412

1513
pytestmark = pytest.mark.skipif(PY2, reason="Py2 doesn't have a UserDict")
1614

1715

18-
def make_data():
19-
# TODO: Use a regular dict. See _NDFrameIndexer._setitem_with_indexer
20-
return [collections.UserDict([
21-
(random.choice(string.ascii_letters), random.randint(0, 100))
22-
for _ in range(random.randint(0, 10))]) for _ in range(100)]
23-
24-
2516
@pytest.fixture
2617
def dtype():
2718
return JSONDtype()
@@ -266,11 +257,6 @@ def test_add_series_with_extension_array(self, data):
266257
with tm.assert_raises_regex(TypeError, "unsupported"):
267258
ser + data
268259

269-
def _check_divmod_op(self, s, op, other, exc=NotImplementedError):
270-
return super(TestArithmeticOps, self)._check_divmod_op(
271-
s, op, other, exc=TypeError
272-
)
273-
274260

275261
class TestComparisonOps(BaseJSON, base.BaseComparisonOpsTests):
276262
pass

pandas/tests/extension/test_categorical.py

-5
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,6 @@ def test_add_series_with_extension_array(self, data):
208208
with tm.assert_raises_regex(TypeError, "cannot perform"):
209209
ser + data
210210

211-
def _check_divmod_op(self, s, op, other, exc=NotImplementedError):
212-
return super(TestArithmeticOps, self)._check_divmod_op(
213-
s, op, other, exc=TypeError
214-
)
215-
216211

217212
class TestComparisonOps(base.BaseComparisonOpsTests):
218213

0 commit comments

Comments
 (0)