This is an automated email from the git hooks/post-receive script. tille pushed a commit to branch master in repository python-skbio.
commit e49698c2544e3dc7f4e3731b9f2474b2126cadcf Author: Andreas Tille <[email protected]> Date: Fri Oct 6 21:12:57 2017 +0200 Apply upstream patch dealing with new pandas version --- debian/changelog | 3 +- debian/control | 2 +- ...ry-pick-upstream-fix-for-numpy-transition.patch | 2 - ...t-with-new-pandas-and-numpydoc-fix-deprec.patch | 499 +++++++++++++++++++++ debian/patches/series | 1 + 5 files changed, 503 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index c694f62..ab97b9b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,7 +1,8 @@ python-skbio (0.5.1-3) UNRELEASED; urgency=medium * Standards-Version: 4.1.1 - * Versioned Build-Depends: python3-pandas (>= 0.20) + * Versioned Build-Depends: python3-pandas (>= 0.19.2) + * Apply upstream patch dealing with new pandas version Closes: #868962 -- Andreas Tille <[email protected]> Fri, 06 Oct 2017 20:52:31 +0200 diff --git a/debian/control b/debian/control index f92c223..dc15dd5 100644 --- a/debian/control +++ b/debian/control @@ -20,7 +20,7 @@ Build-Depends: debhelper (>= 10), python3-nose, python3-numpy (>= 1:1.9.2), python3-numpydoc, - python3-pandas (>= 0.20), + python3-pandas (>= 0.19.2), python3-scipy, python3-setuptools, python3-sphinx, diff --git a/debian/patches/0003-Cherry-pick-upstream-fix-for-numpy-transition.patch b/debian/patches/0003-Cherry-pick-upstream-fix-for-numpy-transition.patch index cc30ee2..7a4340a 100644 --- a/debian/patches/0003-Cherry-pick-upstream-fix-for-numpy-transition.patch +++ b/debian/patches/0003-Cherry-pick-upstream-fix-for-numpy-transition.patch @@ -6,8 +6,6 @@ Subject: Cherry-pick upstream fix for numpy transition skbio/stats/composition.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) -diff --git a/skbio/stats/composition.py b/skbio/stats/composition.py -index eb6b364..95f7820 100644 --- a/skbio/stats/composition.py +++ b/skbio/stats/composition.py @@ -973,8 +973,8 @@ def ancom(table, grouping, diff --git a/debian/patches/0004-MAINT-compat-with-new-pandas-and-numpydoc-fix-deprec.patch b/debian/patches/0004-MAINT-compat-with-new-pandas-and-numpydoc-fix-deprec.patch new file mode 100644 index 0000000..c8d44fb --- /dev/null +++ b/debian/patches/0004-MAINT-compat-with-new-pandas-and-numpydoc-fix-deprec.patch @@ -0,0 +1,499 @@ +Author: Jai Ram Rideout <[email protected]> +Last-Update: Fri, 6 Oct 2017 11:40:08 -0700 +Origin: Upstream + https://github.com/biocore/scikit-bio/issues/1531 +Bug-Debian: https://bugs.debian.org/868962 +Subject: MAINT: compat with new pandas and numpydoc; fix deprecation + warnings (#1535) + . + Made the following compatibility updates to fix the longstanding Travis-CI failures and make the codebase a little more futureproof: + - The codebase is now compatible with pandas >=0.19.2, including the latest pandas release (0.20.3), which introduced a number of backwards-incompatible changes. + - Fixed doc build failures by unpinning numpydoc version (latest PyPI numpydoc release is now compatible with latest Sphinx release). + - Fixed all deprecation warnings coming from third-party packages -- most were pandas deprecations, and one was from `scipy.stats`. + - Fixed docs in a couple of places that weren't compatible with numpydoc. + +--- a/ci/pip_requirements.txt ++++ b/ci/pip_requirements.txt +@@ -5,5 +5,5 @@ lockfile + CacheControl + git+git://github.com/sphinx-doc/sphinx.git + sphinx-bootstrap-theme +-git+git://github.com/numpy/numpydoc.git@1a848331c2cf53d4fe356f4607799524bcc577ed ++numpydoc + check-manifest +--- a/doc/source/conf.py ++++ b/doc/source/conf.py +@@ -70,20 +70,7 @@ class NewAuto(autosummary.Autosummary): + autosummary.Autosummary = NewAuto + + import sphinx_bootstrap_theme +- +-# We currently rely on the latest version of numpydoc available on GitHub: +-# git+git://github.com/numpy/numpydoc.git +-# +-# There isn't a way to specify this in setup.py as a dependency since this +-# feature is being removed from pip. We also can't check the version of +-# numpydoc installed because there isn't a numpydoc.__version__ defined. +-try: +- import numpydoc +-except ImportError: +- raise RuntimeError( +- "numpydoc v0.6 or later required. Install it with:\n" +- " pip install git+git://github.com/numpy/numpydoc.git@1a848331c2cf53" +- "d4fe356f4607799524bcc577ed") ++import numpydoc + + @property + def _extras(self): +--- a/setup.py ++++ b/setup.py +@@ -98,7 +98,7 @@ setup(name='scikit-bio', + 'matplotlib >= 1.4.3', + 'natsort >= 4.0.3', + 'numpy >= 1.9.2', +- 'pandas >= 0.18.0', ++ 'pandas >= 0.19.2', + 'scipy >= 0.15.1', + 'nose >= 1.3.7' + ], +--- a/skbio/alignment/_indexing.py ++++ b/skbio/alignment/_indexing.py +@@ -180,7 +180,7 @@ class TabularMSALoc(_Indexing): + self._assert_tuple_rules(indexable) + if (self._has_fancy_index() and + type(indexable) is not tuple and +- pd.core.common.is_list_like(indexable) and ++ pd.api.types.is_list_like(indexable) and + len(indexable) > 0): + if not self.is_scalar(indexable[0], axis=0): + raise TypeError("A list is used with complete labels, try" +--- a/skbio/alignment/_tabular_msa.py ++++ b/skbio/alignment/_tabular_msa.py +@@ -2123,6 +2123,12 @@ class TabularMSA(MetadataMixin, Position + + Examples + -------- ++ .. note:: The following examples call `.sort()` on the joined MSA ++ because there isn't a guaranteed ordering to the index. The joined ++ MSA is sorted in these examples to make the output reproducible. ++ When using this method with your own data, sorting the joined MSA is ++ not necessary. ++ + Join MSAs by sequence: + + >>> from skbio import DNA, TabularMSA +@@ -2131,6 +2137,7 @@ class TabularMSA(MetadataMixin, Position + >>> msa2 = TabularMSA([DNA('G-T'), + ... DNA('T--')]) + >>> joined = msa1.join(msa2) ++ >>> joined.sort() # unnecessary in practice, see note above + >>> joined + TabularMSA[DNA] + --------------------- +@@ -2148,6 +2155,7 @@ class TabularMSA(MetadataMixin, Position + >>> msa2 = TabularMSA([DNA('G-T'), + ... DNA('T--')], index=['b', 'a']) + >>> joined = msa1.join(msa2) ++ >>> joined.sort() # unnecessary in practice, see note above + >>> joined + TabularMSA[DNA] + --------------------- +@@ -2174,6 +2182,7 @@ class TabularMSA(MetadataMixin, Position + ... positional_metadata={'col2': [3, 4, 5], + ... 'col3': ['f', 'o', 'o']}) + >>> joined = msa1.join(msa2, how='inner') ++ >>> joined.sort() # unnecessary in practice, see note above + >>> joined + TabularMSA[DNA] + -------------------------- +@@ -2183,10 +2192,10 @@ class TabularMSA(MetadataMixin, Position + sequence count: 2 + position count: 5 + -------------------------- +- A-G-T + ACT-- ++ A-G-T + >>> joined.index +- Index(['b', 'a'], dtype='object') ++ Index(['a', 'b'], dtype='object') + >>> joined.positional_metadata + col2 + 0 1 +@@ -2200,6 +2209,7 @@ class TabularMSA(MetadataMixin, Position + ``positional_metadata`` columns are padded with NaN: + + >>> joined = msa1.join(msa2, how='outer') ++ >>> joined.sort() # unnecessary in practice, see note above + >>> joined + TabularMSA[DNA] + ---------------------------- +@@ -2284,12 +2294,12 @@ class TabularMSA(MetadataMixin, Position + + def _get_join_index(self, other, how): + if how == 'strict': +- diff = self.index.sym_diff(other.index) ++ diff = self.index.symmetric_difference(other.index) + if len(diff) > 0: + raise ValueError( + "Index labels must all match with `how='strict'`") + +- diff = self.positional_metadata.columns.sym_diff( ++ diff = self.positional_metadata.columns.symmetric_difference( + other.positional_metadata.columns) + + if not self.has_positional_metadata(): +--- a/skbio/alignment/tests/test_tabular_msa.py ++++ b/skbio/alignment/tests/test_tabular_msa.py +@@ -1137,7 +1137,7 @@ class SharedIndexTests: + def test_bad_fancy_index(self): + msa = TabularMSA([DNA("ABCD"), DNA("GHKM"), DNA("NRST")]) + +- with self.assertRaises((KeyError, TypeError)): ++ with self.assertRaises((KeyError, TypeError, ValueError)): + self.get(msa, [0, "foo"]) + + with self.assertRaises(IndexError): +@@ -2506,6 +2506,19 @@ class TestExtend(unittest.TestCase): + + + class TestJoin(unittest.TestCase): ++ def assertEqualJoinedMSA(self, msa1, msa2): ++ # `TabularMSA.join` doesn't guarantee index order in the joined MSA. ++ # The order differs across pandas versions, so sort each MSA before ++ # comparing for equality. ++ ++ # copy because `TabularMSA.sort` is in-place. ++ msa1 = copy.copy(msa1) ++ msa2 = copy.copy(msa2) ++ msa1.sort() ++ msa2.sort() ++ ++ self.assertEqual(msa1, msa2) ++ + def test_invalid_how(self): + with self.assertRaisesRegex(ValueError, '`how`'): + TabularMSA([]).join(TabularMSA([]), how='really') +@@ -2543,7 +2556,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2) + +- self.assertEqual( ++ self.assertEqualJoinedMSA( + joined, + TabularMSA([DNA('AC-C'), + DNA('G..G')])) +@@ -2560,7 +2573,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2) + +- self.assertEqual( ++ self.assertEqualJoinedMSA( + joined, + TabularMSA([DNA('ACCA'), + DNA('G..G'), +@@ -2576,7 +2589,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2) + +- self.assertEqual( ++ self.assertEqualJoinedMSA( + joined, + TabularMSA([ + DNA('ACCA', +@@ -2594,7 +2607,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2) + +- self.assertEqual(joined, TabularMSA([])) ++ self.assertEqualJoinedMSA(joined, TabularMSA([])) + + def test_no_positions(self): + msa1 = TabularMSA([DNA('', positional_metadata={'1': []}), +@@ -2606,7 +2619,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2) + +- self.assertEqual( ++ self.assertEqualJoinedMSA( + joined, + TabularMSA([DNA('', positional_metadata={'1': [], '3': []}), + DNA('', positional_metadata={'2': [], '4': []})], +@@ -2622,7 +2635,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2) + +- self.assertEqual( ++ self.assertEqualJoinedMSA( + joined, + TabularMSA([DNA('A', positional_metadata={'1': ['a'], + '3': [np.nan]}), +@@ -2644,7 +2657,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2) + +- self.assertEqual( ++ self.assertEqualJoinedMSA( + joined, + TabularMSA([DNA('ACCA'), + DNA('G..G'), +@@ -2693,7 +2706,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2, how='inner') + +- self.assertEqual( ++ self.assertEqualJoinedMSA( + joined, + TabularMSA([DNA('C--C'), + DNA('G..G'), +@@ -2710,7 +2723,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2, how='inner') + +- self.assertEqual( ++ self.assertEqualJoinedMSA( + joined, + TabularMSA([DNA('G.-C'), + DNA('AC.G')], index=['a', 'b'])) +@@ -2725,7 +2738,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2, how='inner') + +- self.assertEqual(joined, TabularMSA([])) ++ self.assertEqualJoinedMSA(joined, TabularMSA([])) + + def test_how_outer(self): + msa1 = TabularMSA([DNA('AC'), +@@ -2743,7 +2756,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2, how='outer') + +- self.assertEqual( ++ self.assertEqualJoinedMSA( + joined, + TabularMSA([DNA('--...'), + DNA('ACCAA'), +@@ -2771,7 +2784,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2, how='left') + +- self.assertEqual( ++ self.assertEqualJoinedMSA( + joined, + TabularMSA([DNA('ACCAA'), + DNA('G..GG'), +@@ -2797,7 +2810,7 @@ class TestJoin(unittest.TestCase): + + joined = msa1.join(msa2, how='right') + +- self.assertEqual( ++ self.assertEqualJoinedMSA( + joined, + TabularMSA([DNA('C--CC'), + DNA('G..GG'), +--- a/skbio/diversity/_block.py ++++ b/skbio/diversity/_block.py +@@ -185,8 +185,8 @@ def _block_compute(**kwargs): + def _map(func, kw_gen): + """Map a function over arguments + +- Note +- ---- ++ Notes ++ ----- + builtin map does not allow for mapping with kwargs. + + Parallel uses of block decomposition will likely replace this method with +@@ -276,8 +276,8 @@ def block_beta_diversity(metric, counts, + A distance matrix relating all samples represented by counts to each + other. + +- Note +- ---- ++ Notes ++ ----- + This method is designed to facilitate computing beta diversity in parallel. + In general, if you are processing a few hundred samples or less, then it is + likely the case that `skbio.diversity.beta_diversity` will be faster. The +--- a/skbio/metadata/_mixin.py ++++ b/skbio/metadata/_mixin.py +@@ -254,7 +254,7 @@ class PositionalMetadataMixin(metaclass= + Set positional metadata: + + >>> seq.positional_metadata = {'degenerates': seq.degenerates()} +- >>> seq.positional_metadata ++ >>> seq.positional_metadata # doctest: +NORMALIZE_WHITESPACE + degenerates + 0 False + 1 False +@@ -285,7 +285,10 @@ class PositionalMetadataMixin(metaclass= + try: + # Pass copy=True to copy underlying data buffer. + positional_metadata = pd.DataFrame(positional_metadata, copy=True) +- except pd.core.common.PandasError as e: ++ # Different versions of pandas will raise different error types. We ++ # don't really care what the type of the error is, just its message, so ++ # a blanket Exception will do. ++ except Exception as e: + raise TypeError( + "Invalid positional metadata. Must be consumable by " + "`pd.DataFrame` constructor. Original pandas error message: " +@@ -368,7 +371,15 @@ class PositionalMetadataMixin(metaclass= + + def _deepcopy_(self, memo): + if self.has_positional_metadata(): +- return copy.deepcopy(self.positional_metadata, memo) ++ # `copy.deepcopy` no longer recursively copies contents of the ++ # DataFrame, so we must handle the deep copy ourselves. ++ # Reference: https://github.com/pandas-dev/pandas/issues/17406 ++ df = self.positional_metadata ++ data_cp = copy.deepcopy(df.values.tolist(), memo) ++ return pd.DataFrame(data_cp, ++ index=df.index.copy(deep=True), ++ columns=df.columns.copy(deep=True), ++ copy=False) + else: + return None + +--- a/skbio/stats/gradient.py ++++ b/skbio/stats/gradient.py +@@ -163,8 +163,10 @@ def _weight_by_vector(trajectories, w_ve + for i, idx in enumerate(trajectories.index): + # Skipping the first element is it doesn't need to be weighted + if i != 0: +- trajectories.ix[idx] = (trajectories.ix[idx] * optimal_gradient / +- (np.abs((w_vector[i] - w_vector[i-1])))) ++ trajectories.loc[idx] = ( ++ trajectories.loc[idx] * optimal_gradient / ++ np.abs((w_vector[i] - w_vector[i-1])) ++ ) + + return trajectories + +@@ -428,7 +430,7 @@ class GradientANOVA: + % (len(prop_expl), axes)) + + # Restrict coordinates to those axes that we actually need to compute +- self._coords = coords.ix[:, :axes-1] ++ self._coords = coords.loc[:, :axes-1] + self._prop_expl = prop_expl[:axes] + self._metadata_map = metadata_map + self._weighted = weighted +@@ -501,10 +503,10 @@ class GradientANOVA: + + # Need to take a subset of coords + if coords_sample_ids != sample_ids: +- self._coords = self._coords.ix[sample_ids] ++ self._coords = self._coords.loc[sample_ids] + # Need to take a subset of metadata_map + if mm_sample_ids != sample_ids: +- self._metadata_map = self._metadata_map.ix[sample_ids] ++ self._metadata_map = self._metadata_map.loc[sample_ids] + + def _make_groups(self, trajectory_categories, sort_category): + r"""Groups the sample ids in `self._metadata_map` by the values in +@@ -566,7 +568,7 @@ class GradientANOVA: + If sids is an empty list + """ + # We multiply the coord values with the prop_expl +- trajectories = self._coords.ix[sids] * self._prop_expl ++ trajectories = self._coords.loc[sids] * self._prop_expl + + if trajectories.empty: + # Raising a RuntimeError since in a usual execution this should +@@ -590,7 +592,7 @@ class GradientANOVA: + trajectories = trajectories_copy + + return self._compute_trajectories_results(group_name, +- trajectories.ix[sids]) ++ trajectories.loc[sids]) + + def _compute_trajectories_results(self, group_name, trajectories): + r"""Do the actual trajectories computation over trajectories +@@ -695,8 +697,8 @@ class TrajectoryGradientANOVA(GradientAN + # Loop through all the rows in trajectories and create '2-norm' + # by taking the norm of the 2nd row - 1st row, 3rd row - 2nd row... + trajectory = \ +- np.array([np.linalg.norm(trajectories.ix[i+1].get_values() - +- trajectories.ix[i].get_values()) ++ np.array([np.linalg.norm(trajectories.iloc[i+1].get_values() - ++ trajectories.iloc[i].get_values()) + for i in range(len(trajectories) - 1)]) + calc = {'2-norm': np.linalg.norm(trajectory)} + +@@ -745,8 +747,8 @@ class FirstDifferenceGradientANOVA(Gradi + calc = {'mean': trajectory[0], 'std': 0} + else: + vec_norm = \ +- np.array([np.linalg.norm(trajectories.ix[i+1].get_values() - +- trajectories.ix[i].get_values()) ++ np.array([np.linalg.norm(trajectories.iloc[i+1].get_values() - ++ trajectories.iloc[i].get_values()) + for i in range(len(trajectories) - 1)]) + trajectory = np.diff(vec_norm) + calc = {'mean': np.mean(trajectory), 'std': np.std(trajectory)} +@@ -830,8 +832,8 @@ class WindowDifferenceGradientANOVA(Grad + calc = {'mean': trajectory, 'std': 0} + else: + vec_norm = \ +- np.array([np.linalg.norm(trajectories.ix[i+1].get_values() - +- trajectories.ix[i].get_values()) ++ np.array([np.linalg.norm(trajectories.iloc[i+1].get_values() - ++ trajectories.iloc[i].get_values()) + for i in range(len(trajectories) - 1)]) + # windowed first differences won't be able on every group, + # specially given the variation of size that a trajectory tends +--- a/skbio/stats/ordination/_ordination_results.py ++++ b/skbio/stats/ordination/_ordination_results.py +@@ -93,8 +93,6 @@ class OrdinationResults(SkbioObject): + str + String representation of the ordination results. + +- .. shownumpydoc +- + """ + lines = ['Ordination results:'] + method = '%s (%s)' % (self.long_method_name, self.short_method_name) +--- a/skbio/stats/tests/test_composition.py ++++ b/skbio/stats/tests/test_composition.py +@@ -6,6 +6,7 @@ + # The full license is in the file COPYING.txt, distributed with this software. + # ---------------------------------------------------------------------------- + ++import functools + from unittest import TestCase, main + import numpy as np + import numpy.testing as npt +@@ -882,10 +883,12 @@ class AncomTests(TestCase): + assert_data_frame_almost_equal(result[0], exp) + + def test_ancom_multiple_comparisons(self): ++ significance_test = functools.partial(scipy.stats.mannwhitneyu, ++ alternative='two-sided') + result = ancom(self.table1, + self.cats1, + multiple_comparisons_correction='holm-bonferroni', +- significance_test=scipy.stats.mannwhitneyu) ++ significance_test=significance_test) + exp = pd.DataFrame( + {'W': np.array([0]*7), + 'Reject null hypothesis': np.array([False]*7, dtype=bool)}) +--- a/skbio/stats/tests/test_gradient.py ++++ b/skbio/stats/tests/test_gradient.py +@@ -335,7 +335,7 @@ class GradientTests(BaseTests): + -0.44931561, + 0.74490965]) + }, orient='index') +- obs = _weight_by_vector(trajectory.ix[sample_ids], ++ obs = _weight_by_vector(trajectory.loc[sample_ids], + w_vector[sample_ids]) + assert_data_frame_almost_equal(obs.sort_index(), exp.sort_index()) + +@@ -779,7 +779,7 @@ class GradientANOVATests(BaseTests): + """Should raise a RuntimeError if the user call _get_group_trajectories + with erroneous inputs""" + bv = GradientANOVA(self.coords, self.prop_expl, self.metadata_map) +- with self.assertRaises(RuntimeError): ++ with self.assertRaises(KeyError): + bv._get_group_trajectories("foo", ['foo']) + with self.assertRaises(RuntimeError): + bv._get_group_trajectories("bar", []) diff --git a/debian/patches/series b/debian/patches/series index 9614d0f..18e965d 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,3 +1,4 @@ mathjax-path 0002-use-libsww-as-library-not-embedded-src.patch 0003-Cherry-pick-upstream-fix-for-numpy-transition.patch +0004-MAINT-compat-with-new-pandas-and-numpydoc-fix-deprec.patch -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/python-skbio.git _______________________________________________ debian-med-commit mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit
