From 16e78bbccdaaec8434f5c0e2eaff39ea4bfacc39 Mon Sep 17 00:00:00 2001 From: Scott Sanderson Date: Tue, 22 Nov 2016 16:34:53 -0500 Subject: [PATCH] BUG: sys.exc_clear is py2 only. --- zipline/algorithm.py | 13 ++++++++++--- zipline/utils/compat.py | 9 +++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/zipline/algorithm.py b/zipline/algorithm.py index 302366db..c74256ab 100644 --- a/zipline/algorithm.py +++ b/zipline/algorithm.py @@ -22,7 +22,6 @@ import pandas as pd from contextlib2 import ExitStack from pandas.tseries.tools import normalize_date import numpy as np -import sys from itertools import chain, repeat from numbers import Integral @@ -111,6 +110,7 @@ from zipline.utils.input_validation import ( from zipline.utils.calendars.trading_calendar import days_at_time from zipline.utils.cache import CachedObject, Expired from zipline.utils.calendars import get_calendar +from zipline.utils.compat import exc_clear import zipline.utils.events from zipline.utils.events import ( @@ -2343,9 +2343,16 @@ class TradingAlgorithm(object): Internal implementation of `pipeline_output`. """ today = normalize_date(self.get_datetime()) + data = NO_DATA = object() try: data = self._pipeline_cache.unwrap(today) except Expired: + # We can't handle the exception in this block because in Python 3 + # sys.exc_info isn't cleared until we leave the block. See note + # below for why we need to clear exc_info. + pass + + if data is NO_DATA: # Try to deterministically garbage collect the previous result by # removing any references to it. There are at least three sources # of references: @@ -2358,8 +2365,8 @@ class TradingAlgorithm(object): # We remove the above sources of references in reverse order: - # 3. Clear the traceback. - sys.exc_clear() + # 3. Clear the traceback. This is no-op in Python 3. + exc_clear() # 2. Clear the .loc/.iloc caches. clear_dataframe_indexer_caches( diff --git a/zipline/utils/compat.py b/zipline/utils/compat.py index cf82ba62..08693a11 100644 --- a/zipline/utils/compat.py +++ b/zipline/utils/compat.py @@ -1,4 +1,5 @@ from six import PY2 +import sys if PY2: @@ -8,9 +9,17 @@ if PY2: mappingproxy.argtypes = [py_object] mappingproxy.restype = py_object + def exc_clear(): + sys.exc_clear() + else: from types import MappingProxyType as mappingproxy + def exc_clear(): + # exc_clear was removed in Python 3. The except statement automatically + # clears the exception. + pass + unicode = type(u'')