diff -Nru patsy-0.4.1/CODE_OF_CONDUCT.md patsy-0.4.1+git34-ga5b54c2/CODE_OF_CONDUCT.md --- patsy-0.4.1/CODE_OF_CONDUCT.md 1970-01-01 00:00:00.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/CODE_OF_CONDUCT.md 2016-11-03 15:09:01.000000000 +0000 @@ -0,0 +1,50 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of +fostering an open and welcoming community, we pledge to respect all people who +contribute through reporting issues, posting feature requests, updating +documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free +experience for everyone, regardless of level of experience, gender, gender +identity and expression, sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic + addresses, without explicit permission +* Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +By adopting this Code of Conduct, project maintainers commit themselves to +fairly and consistently applying these principles to every aspect of managing +this project. Project maintainers who do not follow or enforce the Code of +Conduct may be permanently removed from the project team. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting a project maintainer at njs@pobox.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. Maintainers are +obligated to maintain confidentiality with regard to the reporter of an +incident. + + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.3.0, available at +[http://contributor-covenant.org/version/1/3/0/][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/3/0/ diff -Nru patsy-0.4.1/debian/changelog patsy-0.4.1+git34-ga5b54c2/debian/changelog --- patsy-0.4.1/debian/changelog 2015-11-24 01:43:23.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/debian/changelog 2016-11-03 15:08:07.000000000 +0000 @@ -1,3 +1,9 @@ +patsy (0.4.1+git34-ga5b54c2-1) unstable; urgency=medium + + * New upstream snapshot from v0.4.1-34-ga5b54c2 + + -- Yaroslav Halchenko Thu, 03 Nov 2016 11:08:07 -0400 + patsy (0.4.1-2) unstable; urgency=medium * debian/tests - refactored into reusable across packages/versions of python diff -Nru patsy-0.4.1/debian/patches/up_six_PY patsy-0.4.1+git34-ga5b54c2/debian/patches/up_six_PY --- patsy-0.4.1/debian/patches/up_six_PY 2015-11-24 01:43:23.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/debian/patches/up_six_PY 2016-11-03 15:08:07.000000000 +0000 @@ -1,6 +1,6 @@ --- a/patsy/compat.py +++ b/patsy/compat.py -@@ -129,3 +129,11 @@ def call_and_wrap_exc(msg, origin, f, *a +@@ -48,3 +48,11 @@ def call_and_wrap_exc(msg, origin, f, *a if isinstance(e, PatsyError): e.set_origin(origin) raise diff -Nru patsy-0.4.1/doc/changes.rst patsy-0.4.1+git34-ga5b54c2/doc/changes.rst --- patsy-0.4.1/doc/changes.rst 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/doc/changes.rst 2016-11-03 15:09:01.000000000 +0000 @@ -3,9 +3,17 @@ .. currentmodule:: patsy +v0.5.0 (not yet released) +------ + +* Dropped support for Python 2.6 and 3.3. + v0.4.1 ------ +.. image:: https://zenodo.org/badge/doi/10.5281/zenodo.33471.svg + :target: http://dx.doi.org/10.5281/zenodo.33471 + New features: * On Python 2, accept ``unicode`` strings containing only ASCII diff -Nru patsy-0.4.1/MANIFEST.in patsy-0.4.1+git34-ga5b54c2/MANIFEST.in --- patsy-0.4.1/MANIFEST.in 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/MANIFEST.in 2016-11-03 15:09:01.000000000 +0000 @@ -1,5 +1,5 @@ include setup.cfg .coveragerc tox.ini -include TODO LICENSE.txt README.rst +include TODO LICENSE.txt README.rst CODE_OF_CONDUCT.md recursive-include tools *.py *.R recursive-include doc * prune doc/_build diff -Nru patsy-0.4.1/patsy/categorical.py patsy-0.4.1+git34-ga5b54c2/patsy/categorical.py --- patsy-0.4.1/patsy/categorical.py 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/patsy/categorical.py 2016-11-03 15:09:01.000000000 +0000 @@ -134,7 +134,7 @@ def test_guess_categorical(): if have_pandas_categorical: - c = pandas.Categorical.from_array([1, 2, 3]) + c = pandas.Categorical([1, 2, 3]) assert guess_categorical(c) if have_pandas_categorical_dtype: assert guess_categorical(pandas.Series(c)) @@ -242,7 +242,7 @@ preps += [pandas.Series, lambda x: C(pandas.Series(x))] for prep in preps: - t([], [prep(pandas.Categorical.from_array([1, 2, None]))], + t([], [prep(pandas.Categorical([1, 2, None]))], True, (1, 2)) # check order preservation t([], [prep(pandas_Categorical_from_codes([1, 0], ["a", "b"]))], @@ -250,7 +250,7 @@ t([], [prep(pandas_Categorical_from_codes([1, 0], ["b", "a"]))], True, ("b", "a")) # check that if someone sticks a .contrast field onto our object - obj = prep(pandas.Categorical.from_array(["a", "b"])) + obj = prep(pandas.Categorical(["a", "b"])) obj.contrast = "CONTRAST" t([], [obj], True, ("a", "b"), "CONTRAST") diff -Nru patsy-0.4.1/patsy/compat.py patsy-0.4.1+git34-ga5b54c2/patsy/compat.py --- patsy-0.4.1/patsy/compat.py 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/patsy/compat.py 2016-11-03 15:09:01.000000000 +0000 @@ -12,20 +12,6 @@ # To force use of the compat code, set this env var to a non-empty value: optional_dep_ok = not os.environ.get("PATSY_AVOID_OPTIONAL_DEPENDENCIES") -# The *_indices functions were added in numpy 1.4 -import numpy as np -if optional_dep_ok and hasattr(np, "triu_indices"): - from numpy import triu_indices - from numpy import tril_indices - from numpy import diag_indices -else: - def triu_indices(n): - return np.triu(np.ones((n, n))).nonzero() - def tril_indices(n): - return np.tril(np.ones((n, n))).nonzero() - def diag_indices(n): - return (np.arange(n), np.arange(n)) - ##### Python standard library # The Python license requires that all derivative works contain a "brief @@ -34,73 +20,6 @@ # add here explaining their provenance, any changes made, and what versions of # Python require them: -# Copied unchanged from Python 2.7.3's re.py module; all I did was add the -# import statements at the top. -# This code seems to be included in Python 2.5+. -import re -if optional_dep_ok and hasattr(re, "Scanner"): - Scanner = re.Scanner -else: - import sre_parse - import sre_compile - class Scanner: - def __init__(self, lexicon, flags=0): - from sre_constants import BRANCH, SUBPATTERN - self.lexicon = lexicon - # combine phrases into a compound pattern - p = [] - s = sre_parse.Pattern() - s.flags = flags - for phrase, action in lexicon: - p.append(sre_parse.SubPattern(s, [ - (SUBPATTERN, (len(p)+1, sre_parse.parse(phrase, flags))), - ])) - s.groups = len(p)+1 - p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) - self.scanner = sre_compile.compile(p) - def scan(self, string): - result = [] - append = result.append - match = self.scanner.scanner(string).match - i = 0 - while 1: - m = match() - if not m: - break - j = m.end() - if i == j: - break - action = self.lexicon[m.lastindex-1][1] - if hasattr(action, '__call__'): - self.match = m - action = action(self, m.group()) - if action is not None: - append(action) - i = j - return result, string[i:] - -# functools available in Python 2.5+ -# This is just a cosmetic thing, so don't bother emulating it if we don't -# have it. -def compat_wraps(f1): - def do_wrap(f2): - return f2 - return do_wrap -if optional_dep_ok: - try: - from functools import wraps - except ImportError: - wraps = compat_wraps -else: - wraps = compat_wraps - -# collections.Mapping available in Python 2.6+ -import collections -if optional_dep_ok and hasattr(collections, "Mapping"): - Mapping = collections.Mapping -else: - Mapping = dict - # OrderedDict is only available in Python 2.7+. compat_ordereddict.py has # comments at the top. import collections diff -Nru patsy-0.4.1/patsy/constraint.py patsy-0.4.1+git34-ga5b54c2/patsy/constraint.py --- patsy-0.4.1/patsy/constraint.py 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/patsy/constraint.py 2016-11-03 15:09:01.000000000 +0000 @@ -10,6 +10,7 @@ __all__ = ["LinearConstraint"] import re +from collections import Mapping import six import numpy as np from patsy import PatsyError @@ -19,7 +20,6 @@ SortAnythingKey, no_pickling, assert_no_pickling) from patsy.infix_parser import Token, Operator, ParseNode, infix_parse -from patsy.compat import Scanner, Mapping class LinearConstraint(object): """A linear constraint in matrix form. @@ -58,8 +58,6 @@ raise ValueError("must have at least one row in constraint matrix") if self.coefs.shape[0] != self.constants.shape[0]: raise ValueError("shape mismatch between coefs and constants") - if np.any(np.all(self.coefs == 0, axis=1)): - raise ValueError("can't test a constant constraint") __repr__ = repr_pretty_delegate def _repr_pretty_(self, p, cycle): @@ -102,12 +100,19 @@ assert lc.coefs.dtype == np.dtype(float) assert lc.constants.dtype == np.dtype(float) + + # statsmodels wants to be able to create degenerate constraints like this, + # see: + # https://github.com/pydata/patsy/issues/89 + # We used to forbid it, but I guess it's harmless, so why not. + lc = LinearConstraint(["a"], [[0]]) + assert_equal(lc.coefs, [[0]]) + from nose.tools import assert_raises assert_raises(ValueError, LinearConstraint, ["a"], [[1, 2]]) assert_raises(ValueError, LinearConstraint, ["a"], [[[1]]]) assert_raises(ValueError, LinearConstraint, ["a"], [[1, 2]], [3, 4]) assert_raises(ValueError, LinearConstraint, ["a", "b"], [[1, 2]], [3, 4]) - assert_raises(ValueError, LinearConstraint, ["a"], [[0]]) assert_raises(ValueError, LinearConstraint, ["a"], [[1]], [[]]) assert_raises(ValueError, LinearConstraint, ["a", "b"], []) assert_raises(ValueError, LinearConstraint, ["a", "b"], @@ -176,7 +181,7 @@ (whitespace_re, None), ] - scanner = Scanner(lexicon) + scanner = re.Scanner(lexicon) tokens, leftover = scanner.scan(string) if leftover: offset = len(string) - len(leftover) diff -Nru patsy-0.4.1/patsy/contrasts.py patsy-0.4.1+git34-ga5b54c2/patsy/contrasts.py --- patsy-0.4.1/patsy/contrasts.py 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/patsy/contrasts.py 2016-11-03 15:09:01.000000000 +0000 @@ -14,7 +14,6 @@ import six import numpy as np from patsy import PatsyError -from patsy.compat import triu_indices, tril_indices, diag_indices from patsy.util import (repr_pretty_delegate, repr_pretty_impl, safe_issubdtype, no_pickling, assert_no_pickling) @@ -479,8 +478,8 @@ #r-like contr = np.zeros((n, n - 1)) - contr[1:][diag_indices(n - 1)] = np.arange(1, n) - contr[triu_indices(n - 1)] = -1 + contr[1:][np.diag_indices(n - 1)] = np.arange(1, n) + contr[np.triu_indices(n - 1)] = -1 return contr def code_with_intercept(self, levels): @@ -539,14 +538,14 @@ contr = np.zeros((nlevels, nlevels-1)) int_range = np.arange(1, nlevels) upper_int = np.repeat(int_range, int_range) - row_i, col_i = triu_indices(nlevels-1) + row_i, col_i = np.triu_indices(nlevels-1) # we want to iterate down the columns not across the rows # it would be nice if the index functions had a row/col order arg col_order = np.argsort(col_i) contr[row_i[col_order], col_i[col_order]] = (upper_int-nlevels)/float(nlevels) lower_int = np.repeat(int_range, int_range[::-1]) - row_i, col_i = tril_indices(nlevels-1) + row_i, col_i = np.tril_indices(nlevels-1) # we want to iterate down the columns not across the rows col_order = np.argsort(col_i) contr[row_i[col_order]+1, col_i[col_order]] = lower_int/float(nlevels) diff -Nru patsy-0.4.1/patsy/design_info.py patsy-0.4.1+git34-ga5b54c2/patsy/design_info.py --- patsy-0.4.1/patsy/design_info.py 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/patsy/design_info.py 2016-11-03 15:09:01.000000000 +0000 @@ -1085,8 +1085,13 @@ formatted_cols = [_format_float_column(PRECISION, printable_part[:, i]) for i in range(self.shape[1])] - column_num_widths = [max([len(s) for s in col]) - for col in formatted_cols] + def max_width(col): + assert col.ndim == 1 + if not col.shape[0]: + return 0 + else: + return max([len(s) for s in col]) + column_num_widths = [max_width(col) for col in formatted_cols] column_widths = [max(name_width, num_width) for (name_width, num_width) in zip(column_name_widths, column_num_widths)] @@ -1188,3 +1193,7 @@ repr(DesignMatrix(np.arange(100).reshape((1, 100)))) repr(DesignMatrix([np.nan, np.inf])) repr(DesignMatrix([np.nan, 0, 1e20, 20.5])) + # handling of zero-size matrices + repr(DesignMatrix(np.zeros((1, 0)))) + repr(DesignMatrix(np.zeros((0, 1)))) + repr(DesignMatrix(np.zeros((0, 0)))) diff -Nru patsy-0.4.1/patsy/state.py patsy-0.4.1+git34-ga5b54c2/patsy/state.py --- patsy-0.4.1/patsy/state.py 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/patsy/state.py 2016-11-03 15:09:01.000000000 +0000 @@ -24,12 +24,12 @@ # because right now I'm not sure how to tell whether we are being called for # fitting versus being called for prediction. +from functools import wraps import numpy as np from patsy.util import (atleast_2d_column_default, asarray_or_pandas, pandas_friendly_reshape, wide_dtype_for, safe_issubdtype, no_pickling, assert_no_pickling) -from patsy.compat import wraps # These are made available in the patsy.* namespace __all__ = ["stateful_transform", diff -Nru patsy-0.4.1/patsy/test_build.py patsy-0.4.1+git34-ga5b54c2/patsy/test_build.py --- patsy-0.4.1/patsy/test_build.py 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/patsy/test_build.py 2016-11-03 15:09:01.000000000 +0000 @@ -166,6 +166,8 @@ [("a", "b", "x2"), ("a", "b", "x1")], [("b", "x1", "x2"), ("a", "x1", "x2")]] count = 0 + import time + start = time.time() for termlist_template in all_termlist_templates: termlist_set = set(termlist_template) for dispreferred, preferred in redundant: @@ -189,7 +191,9 @@ else: make_matrix(data, expected_rank, termlist_template) count += 1 - print(count) + if count % 100 == 0: + print("Completed:", count) + print("Took %0.2f seconds" % (time.time() - start,)) test_redundancy_thoroughly.slow = 1 @@ -425,7 +429,7 @@ return_type="dataframe") assert isinstance(int_df, pandas.DataFrame) assert np.array_equal(int_df, [[1], [1], [1]]) - assert int_df.index.equals([10, 20, 30]) + assert int_df.index.equals(pandas.Index([10, 20, 30])) import patsy.build had_pandas = patsy.build.have_pandas @@ -444,7 +448,7 @@ dtype=object)}, NA_action="drop", return_type="dataframe") - assert x_df.index.equals([2]) + assert x_df.index.equals(pandas.Index([2])) def test_data_mismatch(): test_cases_twoway = [ @@ -576,7 +580,7 @@ data_categ = {"a": C(["a2", "a1", "a2"])} datas = [data_strings, data_categ] if have_pandas_categorical: - data_pandas = {"a": pandas.Categorical.from_array(["a1", "a2", "a2"])} + data_pandas = {"a": pandas.Categorical(["a1", "a2", "a2"])} datas.append(data_pandas) def t(data1, data2): def iter_maker(): diff -Nru patsy-0.4.1/patsy/test_highlevel.py patsy-0.4.1+git34-ga5b54c2/patsy/test_highlevel.py --- patsy-0.4.1/patsy/test_highlevel.py 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/patsy/test_highlevel.py 2016-11-03 15:09:01.000000000 +0000 @@ -672,7 +672,7 @@ assert np.array_equal(mat, [[1, 2, 20], [1, 3, 30]]) if return_type == "dataframe": - assert mat.index.equals([1, 2]) + assert mat.index.equals(pandas.Index([1, 2])) assert_raises(PatsyError, dmatrix, "x + y", data=data, return_type=return_type, NA_action="raise") @@ -681,8 +681,8 @@ assert np.array_equal(lmat, [[20], [30]]) assert np.array_equal(rmat, [[1, 2], [1, 3]]) if return_type == "dataframe": - assert lmat.index.equals([1, 2]) - assert rmat.index.equals([1, 2]) + assert lmat.index.equals(pandas.Index([1, 2])) + assert rmat.index.equals(pandas.Index([1, 2])) assert_raises(PatsyError, dmatrices, "y ~ x", data=data, return_type=return_type, NA_action="raise") @@ -693,8 +693,8 @@ assert np.array_equal(lmat, [[20], [30], [40]]) assert np.array_equal(rmat, [[1], [1], [1]]) if return_type == "dataframe": - assert lmat.index.equals([1, 2, 3]) - assert rmat.index.equals([1, 2, 3]) + assert lmat.index.equals(pandas.Index([1, 2, 3])) + assert rmat.index.equals(pandas.Index([1, 2, 3])) assert_raises(PatsyError, dmatrices, "y ~ 1", data=data, return_type=return_type, NA_action="raise") diff -Nru patsy-0.4.1/patsy/util.py patsy-0.4.1+git34-ga5b54c2/patsy/util.py --- patsy-0.4.1/patsy/util.py 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/patsy/util.py 2016-11-03 15:09:01.000000000 +0000 @@ -40,9 +40,20 @@ # Can drop this guard whenever we drop support for such older versions of # pandas. have_pandas_categorical = (have_pandas and hasattr(pandas, "Categorical")) -have_pandas_categorical_dtype = (have_pandas - and hasattr(pandas.core.common, - "is_categorical_dtype")) +if not have_pandas: + have_pandas_categorical_dtype = False + _pandas_is_categorical_dtype = None +else: + if hasattr(pandas, "api"): + # This is available starting in pandas v0.19.0 + have_pandas_categorical_dtype = True + _pandas_is_categorical_dtype = pandas.api.types.is_categorical_dtype + else: + # This is needed for pandas v0.18.0 and earlier + _pandas_is_categorical_dtype = getattr(pandas.core.common, + "is_categorical_dtype", None) + have_pandas_categorical_dtype = (_pandas_is_categorical_dtype + is not None) # Passes through Series and DataFrames, call np.asarray() on everything else def asarray_or_pandas(a, copy=False, dtype=None, subok=False): @@ -595,6 +606,8 @@ return pandas.Categorical(codes, categories) def test_pandas_Categorical_from_codes(): + if not have_pandas_categorical: + return c = pandas_Categorical_from_codes([1, 1, 0, -1], ["a", "b"]) assert np.all(np.asarray(c)[:-1] == ["b", "b", "a"]) assert np.isnan(np.asarray(c)[-1]) @@ -624,6 +637,8 @@ return cat.labels def test_pandas_Categorical_accessors(): + if not have_pandas_categorical: + return c = pandas_Categorical_from_codes([1, 1, 0, -1], ["a", "b"]) assert np.all(pandas_Categorical_categories(c) == ["a", "b"]) assert np.all(pandas_Categorical_codes(c) == [1, 1, 0, -1]) @@ -637,10 +652,7 @@ def safe_is_pandas_categorical_dtype(dt): if not have_pandas_categorical_dtype: return False - # WTF this incredibly crucial function is not even publically exported. - # Also if you read its source it uses a bare except: block which is broken - # by definition, but oh well there is not much I can do about this. - return pandas.core.common.is_categorical_dtype(dt) + return _pandas_is_categorical_dtype(dt) # Needed to support pandas >= 0.15 (!) def safe_is_pandas_categorical(data): @@ -656,7 +668,7 @@ assert not safe_is_pandas_categorical(np.arange(10)) if have_pandas_categorical: - c_obj = pandas.Categorical.from_array(["a", "b"]) + c_obj = pandas.Categorical(["a", "b"]) assert safe_is_pandas_categorical(c_obj) if have_pandas_categorical_dtype: diff -Nru patsy-0.4.1/patsy/version.py patsy-0.4.1+git34-ga5b54c2/patsy/version.py --- patsy-0.4.1/patsy/version.py 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/patsy/version.py 2016-11-03 15:09:01.000000000 +0000 @@ -17,4 +17,4 @@ # want. (Contrast with the special suffix 1.0.0.dev, which sorts *before* # 1.0.0.) -__version__ = "0.4.1" +__version__ = "0.4.1+dev" diff -Nru patsy-0.4.1/README.rst patsy-0.4.1+git34-ga5b54c2/README.rst --- patsy-0.4.1/README.rst 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/README.rst 2016-11-03 15:09:01.000000000 +0000 @@ -9,7 +9,7 @@ :target: https://coveralls.io/r/pydata/patsy?branch=master Documentation: - http://patsy.readthedocs.org/ + https://patsy.readthedocs.io/ Downloads: http://pypi.python.org/pypi/patsy/ diff -Nru patsy-0.4.1/setup.py patsy-0.4.1+git34-ga5b54c2/setup.py --- patsy-0.4.1/setup.py 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/setup.py 2016-11-03 15:09:01.000000000 +0000 @@ -21,7 +21,12 @@ license="2-clause BSD", packages=["patsy"], url="https://github.com/pydata/patsy", - install_requires=["six", "numpy"], + install_requires=[ + "six", + # Possibly we need an even newer numpy than this, but we definitely + # need at least 1.4 for triu_indices + "numpy >= 1.4", + ], classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", @@ -29,12 +34,10 @@ "Intended Audience :: Financial and Insurance Industry", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.2", - "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", "Topic :: Scientific/Engineering", ], ) diff -Nru patsy-0.4.1/.travis.yml patsy-0.4.1+git34-ga5b54c2/.travis.yml --- patsy-0.4.1/.travis.yml 2015-11-09 05:32:22.000000000 +0000 +++ patsy-0.4.1+git34-ga5b54c2/.travis.yml 2016-11-03 15:09:01.000000000 +0000 @@ -1,20 +1,34 @@ language: python python: - - 2.6 - 2.7 - - 3.3 - 3.4 + - 3.5 matrix: include: # 0.14.0 is the last version with the old categorical system - - python: 3.3 - env: PANDAS_VERSION_STR="=0.14.0" + # libfortran=1.0 is needed to work around a bug in anaconda + # (https://github.com/pydata/patsy/pull/83#issuecomment-206895923) + - python: 3.4 + env: PANDAS_VERSION_STR="=0.14.0 libgfortran=1.0" - python: 2.7 - env: PANDAS_VERSION_STR="=0.14.0" + env: PANDAS_VERSION_STR="=0.14.0 libgfortran=1.0" + # 0.18.0 has is_categorical_dtype in a different place than 0.19.0+ + - python: 3.4 + env: PANDAS_VERSION_STR="=0.18.0" + - python: 2.7 + env: PANDAS_VERSION_STR="=0.18.0" + # make sure it works without pandas + - python: 3.5 + env: PANDAS_VERSION_STR="NONE" + - python: 2.7 + env: PANDAS_VERSION_STR="NONE" + # This disables sudo, but makes builds start much faster # See http://blog.travis-ci.com/2014-12-17-faster-builds-with-container-based-infrastructure/ sudo: false before_install: + # Work around terrible pathological behaviour in OpenBLAS multithreading, that causes execution time to blow up from 3 minutes to 18 minutes, apparently in SVD on smallish matrices + - export OMP_NUM_THREADS=1 # Escape Travis virtualenv - deactivate # See: http://conda.pydata.org/docs/travis.html @@ -25,11 +39,9 @@ - conda config --set always_yes yes --set changeps1 no - conda update -q conda - conda info -a - # Should remove the numpy/scipy rules here ASAP, as soon as - # numpy 1.10.2 and scipy 0.16.1 are in conda. - - conda create -q -n testenv python=$TRAVIS_PYTHON_VERSION numpy==1.9.2 scipy==0.15.1 coverage nose pip + - conda create -q -n testenv python=$TRAVIS_PYTHON_VERSION numpy scipy coverage nose pip - source activate testenv - - conda install pandas${PANDAS_VERSION_STR} + - if [ "$PANDAS_VERSION_STR" != "NONE" ]; then conda install pandas${PANDAS_VERSION_STR}; fi install: - python setup.py sdist - pip install dist/* @@ -43,11 +55,12 @@ # The --exe is because python sometimes marks all installed modules # as executable, so without --exe nosetests will just ignore # everything. Baffling, but so it goes. - - coverage run --source=$INSTALLDIR --rcfile=../.coveragerc $(which nosetests) -vvv --exe --failure-detail --all-modules $INSTALLDIR + - coverage run --source=$INSTALLDIR --rcfile=../.coveragerc $(which nosetests) -vvv --nocapture --exe --failure-detail --all-modules $INSTALLDIR - coverage report --rcfile=../.coveragerc --show-missing - python ../tools/check-API-refs.py notifications: email: - njs@pobox.com after_success: - - pip install coveralls && coveralls + #- pip install coveralls && coveralls + - pip install codecov && codecov