Skip to content

Commit

Permalink
Merge pull request #213 from kwmsmith/promote-refactor
Browse files Browse the repository at this point in the history
Refactor promote to correctly handle `string` and `?string`.
  • Loading branch information
kwmsmith committed Apr 11, 2016
2 parents f9461cd + a3281a0 commit dce9474
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 19 deletions.
35 changes: 22 additions & 13 deletions datashape/promote.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def promote(lhs, rhs, promote_option=True):
Examples
--------
>>> from datashape import int32, int64, Option
>>> from datashape import int32, int64, Option, string
>>> x = Option(int32)
>>> y = int64
>>> promote(x, y)
Expand All @@ -24,25 +24,34 @@ def promote(lhs, rhs, promote_option=True):
>>> promote(x, y, promote_option=False)
ctype("int64")
Strings are handled differently than NumPy, which promotes to ctype("object")
>>> x = string
>>> y = Option(string)
>>> promote(x, y) == promote(y, x) == Option(string)
True
>>> promote(x, y, promote_option=False)
ctype("string")
Notes
----
This uses ``numpy.result_type`` for type promotion logic. See the numpy
documentation at
Except for ``datashape.string`` types, this uses ``numpy.result_type`` for
type promotion logic. See the numpy documentation at:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.result_type.html
"""
if lhs == rhs:
return lhs
left, right = getattr(lhs, 'ty', lhs), getattr(rhs, 'ty', rhs)
if left == right == datashape.string:
# Special case string promotion, since numpy promotes to `object`.
dtype = datashape.string
else:
left, right = getattr(lhs, 'ty', lhs), getattr(rhs, 'ty', rhs)
dtype = datashape.CType.from_numpy_dtype(
np.result_type(
datashape.to_numpy_dtype(left),
datashape.to_numpy_dtype(right),
),
)
if promote_option:
dtype = optionify(lhs, rhs, dtype)
return dtype
np_res_type = np.result_type(datashape.to_numpy_dtype(left),
datashape.to_numpy_dtype(right))
dtype = datashape.CType.from_numpy_dtype(np_res_type)
if promote_option:
dtype = optionify(lhs, rhs, dtype)
return dtype


def optionify(lhs, rhs, dshape):
Expand Down
62 changes: 61 additions & 1 deletion datashape/tests/test_promote.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from datashape import promote, Option, float64, int64, float32, optionify
import pytest

from datashape import (promote, Option, float64, int64, float32, optionify,
string, datetime_ as datetime)

def test_simple():
x = int64
Expand Down Expand Up @@ -27,3 +29,61 @@ def test_option_in_parent():
y = Option(float32)
z = optionify(x, y, y)
assert z == y


@pytest.mark.parametrize('x,y,p,r',
[[string, string, True, string],
[string, string, False, string],
[Option(string),
Option(string),
True,
Option(string)],
[Option(string),
Option(string),
False,
Option(string)],
[Option(string),
string,
True,
Option(string)],
[Option(string),
string,
False,
string]])
def test_promote_string_with_option(x, y, p, r):
assert (promote(x, y, promote_option=p) ==
promote(y, x, promote_option=p) ==
r)


@pytest.mark.parametrize('x,y,p,r',
[[datetime, datetime, True, datetime],
[datetime, datetime, False, datetime],
[Option(datetime),
Option(datetime),
True,
Option(datetime)],
[Option(datetime),
Option(datetime),
False,
Option(datetime)],
[Option(datetime),
datetime,
True,
Option(datetime)],
[Option(datetime),
datetime,
False,
datetime]])
def test_promote_datetime_with_option(x, y, p, r):
assert (promote(x, y, promote_option=p) ==
promote(y, x, promote_option=p) ==
r)
6 changes: 1 addition & 5 deletions docs/source/whatsnew/0.5.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ Release |version|
New Features
------------

* Adds :func:`~datashape.discover` support for :class:`types.MappingProxyType`
objects in python 3 and :class:`types.DictProxyType` in python 2
(:issue:`212`).
* Adds :func:`~datashape.discover` support for :class:`collections.OrderedDict`
objects (:issue:`212`).
None

New Types
---------
Expand Down
44 changes: 44 additions & 0 deletions docs/source/whatsnew/0.5.2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
Release |version|
-----------------

:Release: |version|
:Date: TBD

New Features
------------

* Adds :func:`~datashape.discover` support for :class:`types.MappingProxyType`
objects in python 3 and :class:`types.DictProxyType` in python 2
(:issue:`212`).
* Adds :func:`~datashape.discover` support for :class:`collections.OrderedDict`
objects (:issue:`212`).

New Types
---------

None

Experimental Types
------------------

.. warning::

Experimental types are subject to change.

None

API Changes
-----------

None

Bug Fixes
---------

* Fixes :func:`~datashape.promote` to handle :class:`~datashape.string` types
correctly when mixing with :class:`~datashape.Option` types (:issue:`213`).

Miscellaneous
-------------

None

0 comments on commit dce9474

Please sign in to comment.