diff --git a/.travis.yml b/.travis.yml index 6252b5654890f..087d7f1565707 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,14 +19,15 @@ git: matrix: fast_finish: true include: - - python: 2.6 + - python: 2.7 env: - - JOB_NAME: "26_nslow_nnet" + - JOB_NAME: "27_nslow_nnet_COMPAT" - NOSE_ARGS="not slow and not network and not disabled" - CLIPBOARD=xclip - LOCALE_OVERRIDE="it_IT.UTF-8" - BUILD_TYPE=conda - INSTALL_TEST=true + - JOB_TAG=_COMPAT - python: 2.7 env: - JOB_NAME: "27_slow_nnet_LOCALE" diff --git a/ci/requirements-2.6.build b/ci/requirements-2.7_COMPAT.build similarity index 100% rename from ci/requirements-2.6.build rename to ci/requirements-2.7_COMPAT.build diff --git a/ci/requirements-2.6.pip b/ci/requirements-2.7_COMPAT.pip similarity index 100% rename from ci/requirements-2.6.pip rename to ci/requirements-2.7_COMPAT.pip diff --git a/ci/requirements-2.6.run b/ci/requirements-2.7_COMPAT.run similarity index 100% rename from ci/requirements-2.6.run rename to ci/requirements-2.7_COMPAT.run diff --git a/doc/source/install.rst b/doc/source/install.rst index 0f2f7e6f83d78..049fc75184c96 100644 --- a/doc/source/install.rst +++ b/doc/source/install.rst @@ -18,7 +18,7 @@ Instructions for installing from source, Python version support ---------------------- -Officially Python 2.6, 2.7, 3.4, and 3.5 +Officially Python 2.7, 3.4, and 3.5 Installing pandas ----------------- diff --git a/doc/source/whatsnew/v0.18.0.txt b/doc/source/whatsnew/v0.18.0.txt index eaeabbf3f9245..83bd22db53ce0 100644 --- a/doc/source/whatsnew/v0.18.0.txt +++ b/doc/source/whatsnew/v0.18.0.txt @@ -7,6 +7,10 @@ This is a major release from 0.17.1 and includes a small number of API changes, enhancements, and performance improvements along with a large number of bug fixes. We recommend that all users upgrade to this version. +.. warning:: + + pandas >= 0.18.0 will no longer support compatibility with Python version 2.6 (:issue:`7718`) + .. warning:: pandas >= 0.18.0 will no longer support compatibility with Python version 3.3 (:issue:`11273`) diff --git a/pandas/compat/__init__.py b/pandas/compat/__init__.py index 639da4176cd61..2da4427af4cb6 100644 --- a/pandas/compat/__init__.py +++ b/pandas/compat/__init__.py @@ -20,10 +20,6 @@ * add_metaclass(metaclass) - class decorator that recreates class with with the given metaclass instead (and avoids intermediary class creation) -Python 2.6 compatibility: -* OrderedDict -* Counter - Other items: * OrderedDefaultDict * platform checker @@ -268,480 +264,7 @@ def wrapper(cls): return metaclass(cls.__name__, cls.__bases__, orig_vars) return wrapper - -# ---------------------------------------------------------------------------- -# Python 2.6 compatibility shims -# - -# OrderedDict Shim from Raymond Hettinger, python core dev -# http://code.activestate.com/recipes/576693-ordered-dictionary-for-py24/ -# here to support versions before 2.6 -if not PY3: - # don't need this except in 2.6 - try: - from thread import get_ident as _get_ident - except ImportError: - from dummy_thread import get_ident as _get_ident - -try: - from _abcoll import KeysView, ValuesView, ItemsView -except ImportError: - pass - - -class _OrderedDict(dict): - - """Dictionary that remembers insertion order""" - # An inherited dict maps keys to values. - # The inherited dict provides __getitem__, __len__, __contains__, and get. - # The remaining methods are order-aware. - # Big-O running times for all methods are the same as for regular - # dictionaries. - - # The internal self.__map dictionary maps keys to links in a doubly linked - # list. The circular doubly linked list starts and ends with a sentinel - # element. The sentinel element never gets deleted (this simplifies the - # algorithm). Each link is stored as a list of length three: [PREV, NEXT, - # KEY]. - - def __init__(self, *args, **kwds): - """Initialize an ordered dictionary. Signature is the same as for - regular dictionaries, but keyword arguments are not recommended - because their insertion order is arbitrary. - """ - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) - try: - self.__root - except AttributeError: - self.__root = root = [] # sentinel node - root[:] = [root, root, None] - self.__map = {} - self.__update(*args, **kwds) - - def __setitem__(self, key, value, dict_setitem=dict.__setitem__): - """od.__setitem__(i, y) <==> od[i]=y""" - # Setting a new item creates a new link which goes at the end of the - # linked list, and the inherited dictionary is updated with the new - # key/value pair. - if key not in self: - root = self.__root - last = root[0] - last[1] = root[0] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) - - def __delitem__(self, key, dict_delitem=dict.__delitem__): - """od.__delitem__(y) <==> del od[y]""" - # Deleting an existing item uses self.__map to find the link which is - # then removed by updating the links in the predecessor and successor - # nodes. - dict_delitem(self, key) - link_prev, link_next, key = self.__map.pop(key) - link_prev[1] = link_next - link_next[0] = link_prev - - def __iter__(self): - """od.__iter__() <==> iter(od)""" - root = self.__root - curr = root[1] - while curr is not root: - yield curr[2] - curr = curr[1] - - def __reversed__(self): - """od.__reversed__() <==> reversed(od)""" - root = self.__root - curr = root[0] - while curr is not root: - yield curr[2] - curr = curr[0] - - def clear(self): - """od.clear() -> None. Remove all items from od.""" - try: - for node in itervalues(self.__map): - del node[:] - root = self.__root - root[:] = [root, root, None] - self.__map.clear() - except AttributeError: - pass - dict.clear(self) - - def popitem(self, last=True): - """od.popitem() -> (k, v), return and remove a (key, value) pair. - - Pairs are returned in LIFO order if last is true or FIFO order if - false. - """ - if not self: - raise KeyError('dictionary is empty') - root = self.__root - if last: - link = root[0] - link_prev = link[0] - link_prev[1] = root - root[0] = link_prev - else: - link = root[1] - link_next = link[1] - root[1] = link_next - link_next[0] = root - key = link[2] - del self.__map[key] - value = dict.pop(self, key) - return key, value - - # -- the following methods do not depend on the internal structure -- - - def keys(self): - """od.keys() -> list of keys in od""" - return list(self) - - def values(self): - """od.values() -> list of values in od""" - return [self[key] for key in self] - - def items(self): - """od.items() -> list of (key, value) pairs in od""" - return [(key, self[key]) for key in self] - - def iterkeys(self): - """od.iterkeys() -> an iterator over the keys in od""" - return iter(self) - - def itervalues(self): - """od.itervalues -> an iterator over the values in od""" - for k in self: - yield self[k] - - def iteritems(self): - """od.iteritems -> an iterator over the (key, value) items in od""" - for k in self: - yield (k, self[k]) - - def update(*args, **kwds): - """od.update(E, **F) -> None. Update od from dict/iterable E and F. - - If E is a dict instance, does: for k in E: od[k] = E[k] - If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] - Or if E is an iterable of items, does:for k, v in E: od[k] = v - In either case, this is followed by: for k, v in F.items(): od[k] = v - """ - if len(args) > 2: - raise TypeError('update() takes at most 2 positional ' - 'arguments (%d given)' % (len(args),)) - elif not args: - raise TypeError('update() takes at least 1 argument (0 given)') - self = args[0] - # Make progressively weaker assumptions about "other" - other = () - if len(args) == 2: - other = args[1] - if isinstance(other, dict): - for key in other: - self[key] = other[key] - elif hasattr(other, 'keys'): - for key in other.keys(): - self[key] = other[key] - else: - for key, value in other: - self[key] = value - for key, value in kwds.items(): - self[key] = value - # let subclasses override update without breaking __init__ - __update = update - - __marker = object() - - def pop(self, key, default=__marker): - """od.pop(k[,d]) -> v, remove specified key and return the - corresponding value. If key is not found, d is returned if given, - otherwise KeyError is raised. - """ - if key in self: - result = self[key] - del self[key] - return result - if default is self.__marker: - raise KeyError(key) - return default - - def setdefault(self, key, default=None): - """od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od - """ - if key in self: - return self[key] - self[key] = default - return default - - def __repr__(self, _repr_running=None): - """od.__repr__() <==> repr(od)""" - if _repr_running is None: - _repr_running = {} - call_key = id(self), _get_ident() - if call_key in _repr_running: - return '...' - _repr_running[call_key] = 1 - try: - if not self: - return '%s()' % (self.__class__.__name__,) - return '%s(%r)' % (self.__class__.__name__, list(self.items())) - finally: - del _repr_running[call_key] - - def __reduce__(self): - """Return state information for pickling""" - items = [[k, self[k]] for k in self] - inst_dict = vars(self).copy() - for k in vars(OrderedDict()): - inst_dict.pop(k, None) - if inst_dict: - return (self.__class__, (items,), inst_dict) - return self.__class__, (items,) - - def copy(self): - """od.copy() -> a shallow copy of od""" - return self.__class__(self) - - @classmethod - def fromkeys(cls, iterable, value=None): - """OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S and - values equal to v (which defaults to None). - """ - d = cls() - for key in iterable: - d[key] = value - return d - - def __eq__(self, other): - """od.__eq__(y) <==> od==y. Comparison to another OD is - order-sensitive while comparison to a regular mapping is - order-insensitive. - """ - if isinstance(other, OrderedDict): - return (len(self) == len(other) and - list(self.items()) == list(other.items())) - return dict.__eq__(self, other) - - def __ne__(self, other): - return not self == other - - # -- the following methods are only used in Python 2.7 -- - - def viewkeys(self): - """od.viewkeys() -> a set-like object providing a view on od's keys""" - return KeysView(self) - - def viewvalues(self): - """od.viewvalues() -> an object providing a view on od's values""" - return ValuesView(self) - - def viewitems(self): - """od.viewitems() -> a set-like object providing a view on od's items - """ - return ItemsView(self) - - -# {{{ http://code.activestate.com/recipes/576611/ (r11) - -try: - from operator import itemgetter - from heapq import nlargest -except ImportError: - pass - - -class _Counter(dict): - - """Dict subclass for counting hashable objects. Sometimes called a bag - or multiset. Elements are stored as dictionary keys and their counts - are stored as dictionary values. - - >>> Counter('zyzygy') - Counter({'y': 3, 'z': 2, 'g': 1}) - - """ - - def __init__(self, iterable=None, **kwds): - """Create a new, empty Counter object. And if given, count elements - from an input iterable. Or, initialize the count from another mapping - of elements to their counts. - - >>> c = Counter() # a new, empty counter - >>> c = Counter('gallahad') # a new counter from an iterable - >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping - >>> c = Counter(a=4, b=2) # a new counter from keyword args - - """ - self.update(iterable, **kwds) - - def __missing__(self, key): - return 0 - - def most_common(self, n=None): - """List the n most common elements and their counts from the most - common to the least. If n is None, then list all element counts. - - >>> Counter('abracadabra').most_common(3) - [('a', 5), ('r', 2), ('b', 2)] - - """ - if n is None: - return sorted(iteritems(self), key=itemgetter(1), reverse=True) - return nlargest(n, iteritems(self), key=itemgetter(1)) - - def elements(self): - """Iterator over elements repeating each as many times as its count. - - >>> c = Counter('ABCABC') - >>> sorted(c.elements()) - ['A', 'A', 'B', 'B', 'C', 'C'] - - If an element's count has been set to zero or is a negative number, - elements() will ignore it. - - """ - for elem, count in iteritems(self): - for _ in range(count): - yield elem - - # Override dict methods where the meaning changes for Counter objects. - - @classmethod - def fromkeys(cls, iterable, v=None): - raise NotImplementedError( - 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') - - def update(self, iterable=None, **kwds): - """Like dict.update() but add counts instead of replacing them. - - Source can be an iterable, a dictionary, or another Counter instance. - - >>> c = Counter('which') - >>> c.update('witch') # add elements from another iterable - >>> d = Counter('watch') - >>> c.update(d) # add elements from another counter - >>> c['h'] # four 'h' in which, witch, and watch - 4 - - """ - if iterable is not None: - if hasattr(iterable, 'iteritems'): - if self: - self_get = self.get - for elem, count in iteritems(iterable): - self[elem] = self_get(elem, 0) + count - else: - dict.update( - self, iterable) # fast path when counter is empty - else: - self_get = self.get - for elem in iterable: - self[elem] = self_get(elem, 0) + 1 - if kwds: - self.update(kwds) - - def copy(self): - """Like dict.copy() but returns a Counter instance instead of a dict. - """ - return Counter(self) - - def __delitem__(self, elem): - """Like dict.__delitem__() but does not raise KeyError for missing - values. - """ - if elem in self: - dict.__delitem__(self, elem) - - def __repr__(self): - if not self: - return '%s()' % self.__class__.__name__ - items = ', '.join(map('%r: %r'.__mod__, self.most_common())) - return '%s({%s})' % (self.__class__.__name__, items) - - # Multiset-style mathematical operations discussed in: - # Knuth TAOCP Volume II section 4.6.3 exercise 19 - # and at http://en.wikipedia.org/wiki/Multiset - # - # Outputs guaranteed to only include positive counts. - # - # To strip negative and zero counts, add-in an empty counter: - # c += Counter() - - def __add__(self, other): - """Add counts from two counters. - - >>> Counter('abbb') + Counter('bcc') - Counter({'b': 4, 'c': 2, 'a': 1}) - - """ - if not isinstance(other, Counter): - return NotImplemented - result = Counter() - for elem in set(self) | set(other): - newcount = self[elem] + other[elem] - if newcount > 0: - result[elem] = newcount - return result - - def __sub__(self, other): - """Subtract count, but keep only results with positive counts. - - >>> Counter('abbbc') - Counter('bccd') - Counter({'b': 2, 'a': 1}) - - """ - if not isinstance(other, Counter): - return NotImplemented - result = Counter() - for elem in set(self) | set(other): - newcount = self[elem] - other[elem] - if newcount > 0: - result[elem] = newcount - return result - - def __or__(self, other): - """Union is the maximum of value in either of the input counters. - - >>> Counter('abbb') | Counter('bcc') - Counter({'b': 3, 'c': 2, 'a': 1}) - - """ - if not isinstance(other, Counter): - return NotImplemented - _max = max - result = Counter() - for elem in set(self) | set(other): - newcount = _max(self[elem], other[elem]) - if newcount > 0: - result[elem] = newcount - return result - - def __and__(self, other): - """Intersection is the minimum of corresponding counts. - - >>> Counter('abbb') & Counter('bcc') - Counter({'b': 1}) - - """ - if not isinstance(other, Counter): - return NotImplemented - _min = min - result = Counter() - if len(self) < len(other): - self, other = other, self - for elem in filter(self.__contains__, other): - newcount = _min(self[elem], other[elem]) - if newcount > 0: - result[elem] = newcount - return result - -if sys.version_info[:2] < (2, 7): - OrderedDict = _OrderedDict - Counter = _Counter -else: - from collections import OrderedDict, Counter +from collections import OrderedDict, Counter if PY3: def raise_with_traceback(exc, traceback=Ellipsis): diff --git a/pandas/io/tests/test_parsers.py b/pandas/io/tests/test_parsers.py index 87450ddde636e..e36fcdf34a707 100755 --- a/pandas/io/tests/test_parsers.py +++ b/pandas/io/tests/test_parsers.py @@ -2502,8 +2502,6 @@ def test_eof_states(self): self.assertRaises(Exception, self.read_csv, StringIO(data), escapechar='\\') # IN_QUOTED_FIELD - # Python 2.6 won't throw an exception for this case (see http://bugs.python.org/issue16013) - tm._skip_if_python26() data = 'a,b,c\n4,5,6\n"' self.assertRaises(Exception, self.read_csv, StringIO(data), escapechar='\\') diff --git a/pandas/tests/test_algos.py b/pandas/tests/test_algos.py index b18bd7b2b3978..252250c5a55b8 100644 --- a/pandas/tests/test_algos.py +++ b/pandas/tests/test_algos.py @@ -567,7 +567,7 @@ def test_group_var_constant(self): self.algo(out, counts, values, labels) self.assertEqual(counts[0], 3) - self.assertTrue(out[0, 0] >= 0) # Python 2.6 has no assertGreaterEqual + self.assertTrue(out[0, 0] >= 0) tm.assert_almost_equal(out[0, 0], 0.0) diff --git a/pandas/tests/test_config.py b/pandas/tests/test_config.py index 3a8fdd877f5a0..0e286e93160b8 100644 --- a/pandas/tests/test_config.py +++ b/pandas/tests/test_config.py @@ -134,7 +134,6 @@ def test_case_insensitive(self): self.assertRaises(KeyError, self.cf.get_option, 'no_such_option') self.cf.deprecate_option('KanBan') - # testing warning with catch_warning was only added in 2.6 self.assertTrue(self.cf._is_deprecated('kAnBaN')) def test_get_option(self): @@ -249,10 +248,6 @@ def test_deprecate_option(self): self.cf.deprecate_option( 'foo') # we can deprecate non-existent options - # testing warning with catch_warning was only added in 2.6 - if sys.version_info[:2] < (2, 6): - raise nose.SkipTest("Need py > 2.6") - self.assertTrue(self.cf._is_deprecated('foo')) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index 960e931383310..5bab0dcdc91fd 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -5053,8 +5053,6 @@ def test_from_records_empty_with_nonempty_fields_gh3682(self): self.assertEqual(df.index.name, 'id') def test_from_records_with_datetimes(self): - if sys.version < LooseVersion('2.7'): - raise nose.SkipTest('rec arrays dont work properly with py2.6') # this may fail on certain platforms because of a numpy issue # related GH6140 @@ -13487,13 +13485,8 @@ def test_round(self): # float input to `decimals` non_int_round_dict = {'col1': 1, 'col2': 0.5} - if sys.version < LooseVersion('2.7'): - # np.round([1.123, 2.123], 0.5) is only a warning in Python 2.6 - with self.assert_produces_warning(DeprecationWarning, check_stacklevel=False): - df.round(non_int_round_dict) - else: - with self.assertRaises(TypeError): - df.round(non_int_round_dict) + with self.assertRaises(TypeError): + df.round(non_int_round_dict) # String input non_int_round_dict = {'col1': 1, 'col2': 'foo'} diff --git a/pandas/tests/test_internals.py b/pandas/tests/test_internals.py index 0f46c1106ed08..23e8aad01bf52 100644 --- a/pandas/tests/test_internals.py +++ b/pandas/tests/test_internals.py @@ -1026,10 +1026,8 @@ def test_zero_step_raises(self): def test_unbounded_slice_raises(self): def assert_unbounded_slice_error(slc): - # assertRaisesRegexp is not available in py2.6 - # self.assertRaisesRegexp(ValueError, "unbounded slice", - # lambda: BlockPlacement(slc)) - self.assertRaises(ValueError, BlockPlacement, slc) + self.assertRaisesRegexp(ValueError, "unbounded slice", + lambda: BlockPlacement(slc)) assert_unbounded_slice_error(slice(None, None)) assert_unbounded_slice_error(slice(10, None)) diff --git a/pandas/tseries/index.py b/pandas/tseries/index.py index 254704f21387c..3e1ba006df5b7 100644 --- a/pandas/tseries/index.py +++ b/pandas/tseries/index.py @@ -1493,8 +1493,6 @@ def time(self): """ Returns numpy array of datetime.time. The time part of the Timestamps. """ - # can't call self.map() which tries to treat func as ufunc - # and causes recursion warnings on python 2.6 return self._maybe_mask_results(_algos.arrmap_object(self.asobject.values, lambda x: np.nan if x is tslib.NaT else x.time())) diff --git a/pandas/util/print_versions.py b/pandas/util/print_versions.py index 0bdcbedee0900..a4cb84d530336 100644 --- a/pandas/util/print_versions.py +++ b/pandas/util/print_versions.py @@ -106,7 +106,6 @@ def show_versions(as_json=False): deps_blob.append((modname, None)) if (as_json): - # 2.6-safe try: import json except: @@ -134,7 +133,6 @@ def show_versions(as_json=False): def main(): - # optparse is 2.6-safe from optparse import OptionParser parser = OptionParser() parser.add_option("-j", "--json", metavar="FILE", nargs=1, diff --git a/pandas/util/testing.py b/pandas/util/testing.py index d912e745788c8..1c21863415c62 100644 --- a/pandas/util/testing.py +++ b/pandas/util/testing.py @@ -249,12 +249,6 @@ def _skip_if_no_cday(): raise nose.SkipTest("CustomBusinessDay not available.") -def _skip_if_python26(): - if sys.version_info[:2] == (2, 6): - import nose - raise nose.SkipTest("skipping on python2.6") - - def _skip_if_no_pathlib(): try: from pathlib import Path diff --git a/scripts/test_py25.bat b/scripts/test_py25.bat deleted file mode 100644 index fbf00b0451e3d..0000000000000 --- a/scripts/test_py25.bat +++ /dev/null @@ -1,8 +0,0 @@ -SET PATH=C:\MinGW\bin;C:\Python25;C:\Python25\Scripts;%PATH% -del pandas\_tseries.pyd -del pandas\_sparse.pyd -del pandas\src\tseries.c -del pandas\src\sparse.c -python setup.py clean -python setup.py build_ext -c mingw32 --inplace -nosetests pandas \ No newline at end of file diff --git a/scripts/test_py26.bat b/scripts/test_py26.bat deleted file mode 100644 index e2502e87ad459..0000000000000 --- a/scripts/test_py26.bat +++ /dev/null @@ -1,8 +0,0 @@ -SET PATH=C:\MinGW\bin;E:\Python26;E:\Python26\Scripts;%PATH% -del pandas\_tseries.pyd -del pandas\_sparse.pyd -del pandas\src\tseries.c -del pandas\src\sparse.c -python setup.py clean -python setup.py build_ext -c mingw32 --inplace -nosetests pandas \ No newline at end of file diff --git a/scripts/test_py31.bat b/scripts/test_py31.bat deleted file mode 100644 index e146ef2826cff..0000000000000 --- a/scripts/test_py31.bat +++ /dev/null @@ -1,8 +0,0 @@ -set BASE=E:\python31 -set PYTHON=%BASE%\python.exe -set NOSETESTS=%BASE%\scripts\nosetests-script.py - -%PYTHON% setup.py install -cd bench -%PYTHON% %NOSETESTS% pandas -cd .. \ No newline at end of file diff --git a/scripts/test_py32.bat b/scripts/test_py32.bat deleted file mode 100644 index 31685ae40aee5..0000000000000 --- a/scripts/test_py32.bat +++ /dev/null @@ -1,8 +0,0 @@ -set BASE=E:\python32 -set PYTHON=%BASE%\python.exe -set NOSETESTS=%BASE%\scripts\nosetests-script.py - -%PYTHON% setup.py install -cd bench -%PYTHON% %NOSETESTS% pandas -cd .. \ No newline at end of file diff --git a/scripts/winbuild_py25.bat b/scripts/winbuild_py25.bat deleted file mode 100644 index 5ecebab71b851..0000000000000 --- a/scripts/winbuild_py25.bat +++ /dev/null @@ -1,2 +0,0 @@ -SET PATH=C:\MinGW\bin;C:\Python25;C:\Python25\Scripts;%PATH% -python setup.py build -c mingw32 bdist_wininst diff --git a/scripts/windows_builder/build_26-32.bat b/scripts/windows_builder/build_26-32.bat deleted file mode 100644 index 00cf016ff3bad..0000000000000 --- a/scripts/windows_builder/build_26-32.bat +++ /dev/null @@ -1,21 +0,0 @@ -@echo off -echo "starting 26-32" - - -title 26-32 build -echo "building" -cd "c:\users\Jeff Reback\documents\github\pandas" -C:\python26-32\python.exe setup.py build > build.26-32.log 2>&1 - -echo "installing" -C:\python26-32\python.exe setup.py bdist --formats=wininst > install.26-32.log 2>&1 - -echo "testing" -C:\python26-32\scripts\nosetests -A "not slow" build\lib.win32-2.6\pandas > test.26-32.log 2>&1 - -echo "versions" -cd build\lib.win32-2.6 -C:\python26-32\python.exe ../../ci/print_versions.py > ../../versions.26-32.log 2>&1 - - -exit diff --git a/scripts/windows_builder/build_26-64.bat b/scripts/windows_builder/build_26-64.bat deleted file mode 100644 index 55abf37c6c37a..0000000000000 --- a/scripts/windows_builder/build_26-64.bat +++ /dev/null @@ -1,25 +0,0 @@ -@echo off -echo "starting 26-64" - -setlocal EnableDelayedExpansion -set MSSdk=1 -CALL "C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\SetEnv.cmd" /x64 /release -set DISTUTILS_USE_SDK=1 - -title 26-64 build -echo "building" -cd "c:\users\Jeff Reback\documents\github\pandas" -C:\python26-64\python.exe setup.py build > build.26-64.log 2>&1 - -echo "installing" -C:\python26-64\python.exe setup.py bdist --formats=wininst > install.26-64.log 2>&1 - -echo "testing" -C:\python26-64\scripts\nosetests -A "not slow" build\lib.win-amd64-2.6\pandas > test.26-64.log 2>&1 - -echo "versions" -cd build\lib.win-amd64-2.6 -C:\python26-64\python.exe ../../ci/print_versions.py > ../../versions.26-64.log 2>&1 - - -exit diff --git a/scripts/windows_builder/build_33-32.bat b/scripts/windows_builder/build_33-32.bat deleted file mode 100644 index cf629bc71f34e..0000000000000 --- a/scripts/windows_builder/build_33-32.bat +++ /dev/null @@ -1,27 +0,0 @@ -@echo off -echo "starting 33-32" - -setlocal EnableDelayedExpansion -set MSSdk=1 -CALL "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x86 /release -set DISTUTILS_USE_SDK=1 - -title 33-32 build -echo "building" -cd "c:\users\Jeff Reback\documents\github\pandas" -C:\python33-32\python.exe setup.py build > build.33-32.log 2>&1 - -echo "installing" -C:\python33-32\python.exe setup.py bdist --formats=wininst > install.33-32.log 2>&1 - -echo "testing" -C:\python33-32\scripts\nosetests -A "not slow" build\lib.win32-3.3\pandas > test.33-32.log 2>&1 - -echo "versions" -cd build\lib.win32-3.3 -C:\python33-32\python.exe ../../ci/print_versions.py > ../../versions.33-32.log 2>&1 - -exit - - - diff --git a/scripts/windows_builder/build_33-64.bat b/scripts/windows_builder/build_33-64.bat deleted file mode 100644 index 8f037941868f9..0000000000000 --- a/scripts/windows_builder/build_33-64.bat +++ /dev/null @@ -1,27 +0,0 @@ -@echo off -echo "starting 33-64" - -setlocal EnableDelayedExpansion -set MSSdk=1 -CALL "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 /release -set DISTUTILS_USE_SDK=1 - -title 33-64 build -echo "building" -cd "c:\users\Jeff Reback\documents\github\pandas" -C:\python33-64\python.exe setup.py build > build.33-64.log 2>&1 - -echo "installing" -C:\python33-64\python.exe setup.py bdist --formats=wininst > install.33-64.log 2>&1 - -echo "testing" -C:\python33-64\scripts\nosetests -A "not slow" build\lib.win-amd64-3.3\pandas > test.33-64.log 2>&1 - -echo "versions" -cd build\lib.win-amd64-3.3 -C:\python33-64\python.exe ../../ci/print_versions.py > ../../versions.33-64.log 2>&1 - -exit - - - diff --git a/scripts/windows_builder/check_and_build.py b/scripts/windows_builder/check_and_build.py index 81669972b991d..2eb32fb4265d9 100644 --- a/scripts/windows_builder/check_and_build.py +++ b/scripts/windows_builder/check_and_build.py @@ -45,7 +45,7 @@ args = parser.parse_args() dry_run = args.dry -builds = ['26-32','26-64','27-32','27-64','33-32','33-64','34-32','34-64'] +builds = ['27-32','27-64','34-32','34-64'] base_dir = "C:\Users\Jeff Reback\Documents\GitHub\pandas" remote_host='pandas.pydata.org' username='pandas' @@ -140,7 +140,7 @@ def do_update(is_verbose=True): if is_verbose: logger.info("commits changed : {0} -> {1}".format(start_commit,master.commit)) return result - + def run_install(): # send the installation binaries diff --git a/scripts/windows_builder/readme.txt b/scripts/windows_builder/readme.txt index 85c011e515b74..789e2a9ee0c63 100644 --- a/scripts/windows_builder/readme.txt +++ b/scripts/windows_builder/readme.txt @@ -8,9 +8,9 @@ Full python installs for each version with the deps Currently supporting -26-32,26-64,27-32,27-64,33-32,33-64,34-32,34-64 +27-32,27-64,34-32,34-64 -Note that 33 and 34 use the 4.0 SDK, while the other suse 3.5 SDK +Note that 34 use the 4.0 SDK, while the other suse 3.5 SDK I installed these scripts in C:\Builds diff --git a/setup.py b/setup.py index e52c19167c65f..0f4492d9821ee 100755 --- a/setup.py +++ b/setup.py @@ -178,7 +178,6 @@ def build_extensions(self): 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', diff --git a/tox.ini b/tox.ini index 9fbb15087c4d5..5d6c8975307b6 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py26, py27, py32, py33, py34 +envlist = py27, py34, py35 [testenv] deps = @@ -41,13 +41,6 @@ commands = # tox should provide a preinstall-commands hook. pip uninstall pandas -qy -[testenv:py26] -deps = - numpy==1.6.1 - boto - bigquery - {[testenv]deps} - [testenv:py27] deps = numpy==1.8.1 @@ -55,19 +48,14 @@ deps = bigquery {[testenv]deps} -[testenv:py32] -deps = - numpy==1.7.1 - {[testenv]deps} - -[testenv:py33] +[testenv:py34] deps = numpy==1.8.0 {[testenv]deps} -[testenv:py34] +[testenv:py35] deps = - numpy==1.8.0 + numpy==1.10.0 {[testenv]deps} [testenv:openpyxl1]