ENH: adds optionally for preprocessors

This commit is contained in:
Joe Jevnik
2016-01-13 15:26:37 -05:00
parent 220cf1ae4e
commit 5351b60a4c
2 changed files with 61 additions and 1 deletions
+20
View File
@@ -17,6 +17,7 @@ from zipline.utils.input_validation import (
expect_dtypes,
expect_types,
optional,
optionally,
)
@@ -347,3 +348,22 @@ class PreprocessTestCase(TestCase):
# test invalid timezone strings
for tz in invalid:
self.assertRaises(pytz.UnknownTimeZoneError, f, tz)
def test_optionally(self):
error = TypeError('arg must be int')
def preprocessor(func, argname, arg):
if not isinstance(arg, int):
raise error
return arg
@preprocess(a=optionally(preprocessor))
def f(a):
return a
self.assertIs(f(1), 1)
self.assertIsNone(f(None))
with self.assertRaises(TypeError) as e:
f('a')
self.assertIs(e.exception, error)
+41 -1
View File
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from datetime import tzinfo
from functools import partial
from functools import partial, wraps
from operator import attrgetter
from numpy import dtype
@@ -24,6 +24,46 @@ import toolz.curried.operator as op
from zipline.utils.preprocess import preprocess
def optionally(preprocessor):
"""Modify a preprocessor to explicitly allow `None`.
Parameters
----------
preprocessor : callable[callable, str, any -> any]
A preprocessor to delegate to when `arg is not None`.
Returns
-------
optional_preprocessor : callable[callable, str, any -> any]
A preprocessor that delegates to `preprocessor` when `arg is not None`.
Usage
-----
>>> def preprocessor(func, argname, arg):
... if not isinstance(arg, int):
... raise TypeError('arg must be int')
... return arg
...
>>> @preprocess(a=optionally(preprocessor))
... def f(a):
... return a
...
>>> f(1) # call with int
1
>> f('a') # call with not int
Traceback (most recent call last):
...
TypeError: arg must be int
>>> f(None) # call with explicit None
None
"""
@wraps(preprocessor)
def wrapper(func, argname, arg):
return arg if arg is None else preprocessor(func, argname, arg)
return wrapper
def ensure_upper_case(func, argname, arg):
if isinstance(arg, string_types):
return arg.upper()