TST: fix doctests to actually run

This commit is contained in:
Joe Jevnik
2016-06-17 19:29:09 -04:00
parent c0d08f9c0d
commit 5925107052
18 changed files with 64 additions and 135 deletions
+1 -1
View File
@@ -43,7 +43,7 @@ before_script:
- pip freeze | sort
script:
- flake8 zipline tests
- nosetests --with-coverage tests/
- nosetests --with-coverage
# deactive env to get access to anaconda command
- source deactivate
- if [[ "$TRAVIS_SECURE_ENV_VARS" = "true" && "$TRAVIS_BRANCH" = "master" && "$TRAVIS_PULL_REQUEST" = "false" ]]; then DO_UPLOAD="true"; else DO_UPLOAD="false"; fi
+1 -1
View File
@@ -105,7 +105,7 @@ install:
- pip freeze | sort
test_script:
- nosetests tests/
- nosetests
- flake8 zipline tests
branches:
+2
View File
@@ -5,6 +5,8 @@ with-ignore-docstrings=1
with-timer=1
timer-top-n=15
cover-package=zipline
with-doctest=1
testmatch=(?:^|[\\b_\\.-])[Tt]est(?!ing)
[metadata]
description-file = README.rst
+1 -1
View File
@@ -125,7 +125,7 @@ def to_dict(l):
Example
-------
>>> to_dict([2, 3, 4])
>>> to_dict([2, 3, 4]) # doctest: +SKIP
{'0': 2, '1': 3, '2': 4}
"""
return dict(zip(map(str, range(len(l))), l))
@@ -1,3 +1,4 @@
#!/usr/bin/env python
#
# Copyright 2013 Quantopian, Inc.
#
-91
View File
@@ -1,91 +0,0 @@
from __future__ import print_function
import sys
import doctest
from unittest import TestCase
from zipline import testing
from zipline.lib import adjustment, normalize
from zipline.pipeline import (
engine,
expression,
)
from zipline.utils import (
cache,
data,
functional,
input_validation,
memoize,
numpy_utils,
preprocess,
)
class DoctestTestCase(TestCase):
@classmethod
def setUpClass(cls):
import pdb
# Workaround for the issue addressed by this (unmerged) PR to pdbpp:
# https://bitbucket.org/antocuni/pdb/pull-request/40/fix-ensure_file_can_write_unicode/diff # noqa
if '_pdbpp_path_hack' in pdb.__file__:
cls._skip = True
else:
cls._skip = False
cls.flags = doctest.REPORT_CDIFF | doctest.IGNORE_EXCEPTION_DETAIL
def _check_docs(self, module):
if self._skip:
# Printing this directly to __stdout__ so that it doesn't get
# captured by nose.
print("Warning: Skipping doctests for %s because "
"pdbpp is installed." % module.__name__, file=sys.__stdout__)
return
try:
doctest.testmod(
module,
verbose=True,
raise_on_error=True,
optionflags=self.flags,
)
except doctest.UnexpectedException as e:
raise e.exc_info[1]
except doctest.DocTestFailure as e:
print("Got:")
print(e.got)
raise
def test_adjustment_docs(self):
self._check_docs(adjustment)
def test_expression_docs(self):
self._check_docs(expression)
def test_engine_docs(self):
self._check_docs(engine)
def test_memoize_docs(self):
self._check_docs(memoize)
def test_testing_docs(self):
self._check_docs(testing)
def test_preprocess_docs(self):
self._check_docs(preprocess)
def test_input_validation_docs(self):
self._check_docs(input_validation)
def test_cache_docs(self):
self._check_docs(cache)
def test_numpy_utils_docs(self):
self._check_docs(numpy_utils)
def test_data_docs(self):
self._check_docs(data)
def test_functional_docs(self):
self._check_docs(functional)
def test_normalize_docs(self):
self._check_docs(normalize)
+1 -1
View File
@@ -122,7 +122,7 @@ def simplex_projection(v, b=1):
:Example:
>>> proj = simplex_projection([.4 ,.3, -.4, .5])
>>> print(proj)
>>> proj # doctest: +NORMALIZE_WHITESPACE
array([ 0.33333333, 0.23333333, 0. , 0.43333333])
>>> print(proj.sum())
1.0
+1 -1
View File
@@ -226,7 +226,7 @@ class LabelArray(ndarray):
1. Someone tries to directly construct a new array by doing::
>>> ndarray.__new__(LabelArray, ...)
>>> ndarray.__new__(LabelArray, ...) # doctest: +SKIP
In this case, obj will be None. We treat this as an error case and
fail.
+11 -7
View File
@@ -333,9 +333,9 @@ class Factor(RestrictedDTypeMixin, ComputableTerm):
Factors. For example, constructing a Factor that computes the average of
two other Factors is simply::
>>> f1 = SomeFactor(...)
>>> f2 = SomeOtherFactor(...)
>>> average = (f1 + f2) / 2.0
>>> f1 = SomeFactor(...) # doctest: +SKIP
>>> f2 = SomeOtherFactor(...) # doctest: +SKIP
>>> average = (f1 + f2) / 2.0 # doctest: +SKIP
Factors can also be converted into :class:`zipline.pipeline.Filter` objects
via comparison operators: (``<``, ``<=``, ``!=``, ``eq``, ``>``, ``>=``).
@@ -492,8 +492,10 @@ class Factor(RestrictedDTypeMixin, ComputableTerm):
to use the ``mask`` parameter to discard values at the extremes of the
distribution::
>>> base = MyFactor(...)
>>> normalized = base.demean(mask=base.percentile_between(1, 99))
>>> base = MyFactor(...) # doctest: +SKIP
>>> normalized = base.demean(
... mask=base.percentile_between(1, 99),
... ) # doctest: +SKIP
``demean()`` is only supported on Factors of dtype float64.
@@ -553,8 +555,10 @@ class Factor(RestrictedDTypeMixin, ComputableTerm):
outliers, it is often useful to use the ``mask`` parameter to discard
values at the extremes of the distribution::
>>> base = MyFactor(...)
>>> normalized = base.zscore(mask=base.percentile_between(1, 99))
>>> base = MyFactor(...) # doctest: +SKIP
>>> normalized = base.zscore(
... mask=base.percentile_between(1, 99),
... ) # doctest: +SKIP
``zscore()`` is only supported on Factors of dtype float64.
+3 -3
View File
@@ -26,9 +26,9 @@ def delimit(delimiters, content):
Surround `content` with the first and last characters of `delimiters`.
>>> delimit('[]', "foo")
[foo]
u'[foo]'
>>> delimit('""', "foo")
'"foo"'
u'"foo"'
"""
if len(delimiters) != 2:
raise ValueError(
@@ -220,7 +220,7 @@ def format_attrs(attrs):
Example
-------
>>> format_attrs({'key1': 'value1', 'key2': 'value2'})
>>> format_attrs({'key1': 'value1', 'key2': 'value2'}) # doctest: +SKIP
'[key1=value1, key2=value2]'
"""
if not attrs:
+1 -1
View File
@@ -210,7 +210,7 @@ def alias(attr_name):
>>> class C(object):
... attr = 1
...
>>> class D(object):
>>> class D(C):
... attr_alias = alias('attr')
...
>>> D.attr
+1 -1
View File
@@ -41,7 +41,7 @@ class CallbackManager(object):
>>> with manager('example'):
... print('inside example block')
entering example block
inside example
inside example block
exiting example block
These are reusable with different args:
+1 -1
View File
@@ -23,7 +23,7 @@ def invert(d):
"""
Invert a dictionary into a dictionary of sets.
>>> invert({'a': 1, 'b': 2, 'c': 1})
>>> invert({'a': 1, 'b': 2, 'c': 1}) # doctest: +SKIP
{1: {'a', 'c'}, 2: {'b'}}
"""
out = {}
+4 -2
View File
@@ -302,7 +302,8 @@ class AfterOpen(StatelessRule):
A rule that triggers for some offset after the market opens.
Example that triggers after 30 minutes of the market opening:
>>> AfterOpen(minutes=30)
>>> AfterOpen(minutes=30) # doctest: +ELLIPSIS
<zipline.utils.events.AfterOpen object at ...>
"""
def __init__(self, offset=None, **kwargs):
self.offset = _build_offset(
@@ -346,7 +347,8 @@ class BeforeClose(StatelessRule):
A rule that triggers for some offset time before the market closes.
Example that triggers for the last 30 minutes every day:
>>> BeforeClose(minutes=30)
>>> BeforeClose(minutes=30) # doctest: +ELLIPSIS
<zipline.utils.events.BeforeClose object at ...>
"""
def __init__(self, offset=None, **kwargs):
self.offset = _build_offset(
+1 -1
View File
@@ -69,7 +69,7 @@ class final(with_metaclass(ABCMeta)):
Example usage:
>>> from six import with_metaclass
>>> class C(with_metaclass(FinalMeta)):
>>> class C(with_metaclass(FinalMeta, object)):
... @final
... def f(self):
... return 'value'
+3 -1
View File
@@ -220,14 +220,16 @@ def unzip(seq, elem_len=None):
>>> seq = [('a', 1), ('b', 2), ('c', 3, 'extra')]
>>> cs, ns = unzip(seq)
Traceback (most recent call last):
...
...
ValueError: element at index 2 was length 3, expected 2
# allows an explicit element length instead of infering
>>> seq = [('a', 1, 'extra'), ('b', 2), ('c', 3)]
>>> cs, ns = unzip(seq, 2)
Traceback (most recent call last):
...
ValueError: element at index 0 was length 3, expected 2
# handles empty sequences when a length is given
>>> cs, ns = unzip([], elem_len=2)
>>> cs == ns == ()
+16 -11
View File
@@ -216,10 +216,11 @@ def expect_dtypes(**named):
...
>>> foo(arange(3), 'foo')
(array([0, 1, 2]), 'foo')
>>> foo(arange(3, dtype=float), 'foo')
>>> foo(arange(3, dtype=float), 'foo') # doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
TypeError: foo() expected an argument with dtype 'int64' for argument 'x', but got dtype 'float64' instead. # noqa
TypeError: zipline.utils.input_validation.foo() expected a value with
dtype 'int64' for argument 'x', but got 'float64' instead.
"""
for name, type_ in iteritems(named):
if not isinstance(type_, (dtype, tuple)):
@@ -278,10 +279,11 @@ def expect_kinds(**named):
2
>>> foo(int32(2))
2
>>> foo(float32(2))
>>> foo(float32(2)) # doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...n
TypeError: foo() expected a numpy object of kind 'i' for argument 'x', but got 'f' instead. # noqa
...
TypeError: zipline.utils.input_validation.foo() expected a numpy object of
kind 'i' for argument 'x', but got 'f' instead.
"""
for name, kind in iteritems(named):
if not isinstance(kind, (str, tuple)):
@@ -337,10 +339,11 @@ def expect_types(*_pos, **named):
...
>>> foo(2, '3')
(2, '3')
>>> foo(2.0, '3')
>>> foo(2.0, '3') # doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
TypeError: foo() expected an argument of type 'int' for argument 'x', but got float instead. # noqa
TypeError: zipline.utils.input_validation.foo() expected a value of type
int for argument 'x', but got float instead.
"""
if _pos:
raise TypeError("expect_types() only takes keyword arguments.")
@@ -463,10 +466,11 @@ def expect_element(*_pos, **named):
'A'
>>> foo('b')
'B'
>>> foo('c')
>>> foo('c') # doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
ValueError: foo() expected a value in ('a', 'b') for argument 'x', but got 'c' instead. # noqa
ValueError: zipline.utils.input_validation.foo() expected a value in
('a', 'b') for argument 'x', but got 'c' instead.
Notes
-----
@@ -505,10 +509,11 @@ def expect_dimensions(**dimensions):
...
>>> foo(array([1, 1]), array([[1, 1], [2, 2]]))
2
>>> foo(array([1, 1], array([1, 1])))
>>> foo(array([1, 1]), array([1, 1])) # doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
TypeError: foo() expected a 2-D array for argument 'y', but got a 1-D array instead. # noqa
ValueError: zipline.utils.input_validation.foo() expected a 2-D array for
argument 'y', but got a 1-D array instead.
"""
def _expect_dimension(expected_ndim):
def _check(func, argname, argvalue):
+15 -11
View File
@@ -24,14 +24,15 @@ def compose_types(a, *cs):
.. code-block:: python
class M(type):
def __new__(mcls, name, bases, dict_):
dict_['ayy'] = 'lmao'
return super().__new__(mcls, name, bases, dict_)
>>> class M(type):
... def __new__(mcls, name, bases, dict_):
... dict_['ayy'] = 'lmao'
... return super(M, mcls).__new__(mcls, name, bases, dict_)
class C(metaclass=M):
pass
>>> from six import with_metaclass
>>> class C(with_metaclass(M, object)):
... pass
We now want to create a sublclass of ``C`` that is also an abstract class.
@@ -43,10 +44,11 @@ def compose_types(a, *cs):
.. code-block:: python
class D(C, metaclass=compose_types(M, ABCMeta)):
@abstractmethod
def f(self):
raise NotImplementedError('f')
>>> from abc import ABCMeta, abstractmethod
>>> class D(with_metaclass(compose_types(M, ABCMeta), C)):
... @abstractmethod
... def f(self):
... raise NotImplementedError('f')
We can see that this class has both metaclasses applied to it:
@@ -54,8 +56,10 @@ def compose_types(a, *cs):
.. code-block:: python
>>> D.ayy
lmao
'lmao'
>>> D()
Traceback (most recent call last):
...
TypeError: Can't instantiate abstract class D with abstract methods f