From 83a41e68f5c110731b6b1217bd5339e3eb222625 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Thu, 24 Oct 2019 13:56:46 -0500 Subject: [PATCH 01/14] CI: Drop Python 3.5 support --- ci/azure/posix.yml | 11 ++----- ci/deps/azure-35-compat.yaml | 30 ------------------- ...zure-macos-35.yaml => azure-macos-36.yaml} | 0 setup.py | 3 +- 4 files changed, 4 insertions(+), 40 deletions(-) delete mode 100644 ci/deps/azure-35-compat.yaml rename ci/deps/{azure-macos-35.yaml => azure-macos-36.yaml} (100%) diff --git a/ci/azure/posix.yml b/ci/azure/posix.yml index 281107559a38c..99e7dda0fee3e 100644 --- a/ci/azure/posix.yml +++ b/ci/azure/posix.yml @@ -9,17 +9,12 @@ jobs: strategy: matrix: ${{ if eq(parameters.name, 'macOS') }}: - py35_macos: - ENV_FILE: ci/deps/azure-macos-35.yaml - CONDA_PY: "35" + py36_macos: + ENV_FILE: ci/deps/azure-macos-36.yaml + CONDA_PY: "36" PATTERN: "not slow and not network" ${{ if eq(parameters.name, 'Linux') }}: - py35_compat: - ENV_FILE: ci/deps/azure-35-compat.yaml - CONDA_PY: "35" - PATTERN: "not slow and not network" - py36_locale_slow_old_np: ENV_FILE: ci/deps/azure-36-locale.yaml CONDA_PY: "36" diff --git a/ci/deps/azure-35-compat.yaml b/ci/deps/azure-35-compat.yaml deleted file mode 100644 index dd54001984ec7..0000000000000 --- a/ci/deps/azure-35-compat.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: pandas-dev -channels: - - defaults - - conda-forge -dependencies: - - beautifulsoup4=4.6.0 - - bottleneck=1.2.1 - - jinja2=2.8 - - numexpr=2.6.2 - - numpy=1.13.3 - - openpyxl=2.4.8 - - pytables=3.4.2 - - python-dateutil=2.6.1 - - python=3.5.3 - - pytz=2017.2 - - scipy=0.19.0 - - xlrd=1.1.0 - - xlsxwriter=0.9.8 - - xlwt=1.2.0 - # universal - - hypothesis>=3.58.0 - - pytest-xdist - - pytest-mock - - pytest-azurepipelines - - pip - - pip: - # for python 3.5, pytest>=4.0.2, cython>=0.29.13 is not available in conda - - cython>=0.29.13 - - pytest==4.5.0 - - html5lib==1.0b2 diff --git a/ci/deps/azure-macos-35.yaml b/ci/deps/azure-macos-36.yaml similarity index 100% rename from ci/deps/azure-macos-35.yaml rename to ci/deps/azure-macos-36.yaml diff --git a/setup.py b/setup.py index 0dd1980088db8..1c940270eb259 100755 --- a/setup.py +++ b/setup.py @@ -223,7 +223,6 @@ def build_extensions(self): "Intended Audience :: Science/Research", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", @@ -817,7 +816,7 @@ def srcpath(name=None, suffix=".pyx", subdir="src"): long_description=LONG_DESCRIPTION, classifiers=CLASSIFIERS, platforms="any", - python_requires=">=3.5.3", + python_requires=">=3.6", extras_require={ "test": [ # sync with setup.cfg minversion & install.rst From e0dd3b398d9980a34dbca21b1637806f1f09da51 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Thu, 24 Oct 2019 14:05:25 -0500 Subject: [PATCH 02/14] Updating documentation --- doc/source/development/contributing.rst | 27 ++------------ doc/source/development/policies.rst | 2 +- doc/source/getting_started/dsintro.rst | 47 ------------------------- doc/source/getting_started/install.rst | 4 +-- doc/source/whatsnew/v1.0.0.rst | 4 +++ 5 files changed, 9 insertions(+), 75 deletions(-) diff --git a/doc/source/development/contributing.rst b/doc/source/development/contributing.rst index 677e28b60c51d..baa5425796b1c 100644 --- a/doc/source/development/contributing.rst +++ b/doc/source/development/contributing.rst @@ -236,7 +236,7 @@ Creating a Python environment (pip) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you aren't using conda for your development environment, follow these instructions. -You'll need to have at least python3.5 installed on your system. +You'll need to have at least Python 3.6 installed on your system. .. code-block:: none @@ -818,29 +818,6 @@ The limitation here is that while a human can reasonably understand that ``is_nu With custom types and inference this is not always possible so exceptions are made, but every effort should be exhausted to avoid ``cast`` before going down such paths. -Syntax Requirements -~~~~~~~~~~~~~~~~~~~ - -Because *pandas* still supports Python 3.5, :pep:`526` does not apply and variables **must** be annotated with type comments. Specifically, this is a valid annotation within pandas: - -.. code-block:: python - - primes = [] # type: List[int] - -Whereas this is **NOT** allowed: - -.. code-block:: python - - primes: List[int] = [] # not supported in Python 3.5! - -Note that function signatures can always be annotated per :pep:`3107`: - -.. code-block:: python - - def sum_of_primes(primes: List[int] = []) -> int: - ... - - Pandas-specific Types ~~~~~~~~~~~~~~~~~~~~~ @@ -1267,7 +1244,7 @@ environment by:: or, to use a specific Python interpreter,:: - asv run -e -E existing:python3.5 + asv run -e -E existing:python3.6 This will display stderr from the benchmarks, and use your local ``python`` that comes from your ``$PATH``. diff --git a/doc/source/development/policies.rst b/doc/source/development/policies.rst index 2083a30af09c3..224948738341e 100644 --- a/doc/source/development/policies.rst +++ b/doc/source/development/policies.rst @@ -51,7 +51,7 @@ Pandas may change the behavior of experimental features at any time. Python Support ~~~~~~~~~~~~~~ -Pandas will only drop support for specific Python versions (e.g. 3.5.x, 3.6.x) in +Pandas will only drop support for specific Python versions (e.g. 3.6.x, 3.7.x) in pandas **major** releases. .. _SemVer: https://semver.org diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index 9e18951fe3f4c..a07fcbd8b67c4 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -564,53 +564,6 @@ to a column created earlier in the same :meth:`~DataFrame.assign`. In the second expression, ``x['C']`` will refer to the newly created column, that's equal to ``dfa['A'] + dfa['B']``. -To write code compatible with all versions of Python, split the assignment in two. - -.. ipython:: python - - dependent = pd.DataFrame({"A": [1, 1, 1]}) - (dependent.assign(A=lambda x: x['A'] + 1) - .assign(B=lambda x: x['A'] + 2)) - -.. warning:: - - Dependent assignment may subtly change the behavior of your code between - Python 3.6 and older versions of Python. - - If you wish to write code that supports versions of python before and after 3.6, - you'll need to take care when passing ``assign`` expressions that - - * Update an existing column - * Refer to the newly updated column in the same ``assign`` - - For example, we'll update column "A" and then refer to it when creating "B". - - .. code-block:: python - - >>> dependent = pd.DataFrame({"A": [1, 1, 1]}) - >>> dependent.assign(A=lambda x: x["A"] + 1, B=lambda x: x["A"] + 2) - - For Python 3.5 and earlier the expression creating ``B`` refers to the - "old" value of ``A``, ``[1, 1, 1]``. The output is then - - .. code-block:: console - - A B - 0 2 3 - 1 2 3 - 2 2 3 - - For Python 3.6 and later, the expression creating ``A`` refers to the - "new" value of ``A``, ``[2, 2, 2]``, which results in - - .. code-block:: console - - A B - 0 2 4 - 1 2 4 - 2 2 4 - - Indexing / selection ~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/getting_started/install.rst b/doc/source/getting_started/install.rst index 7d1150c2f65fa..233dcf7419d81 100644 --- a/doc/source/getting_started/install.rst +++ b/doc/source/getting_started/install.rst @@ -18,7 +18,7 @@ Instructions for installing from source, Python version support ---------------------- -Officially Python 3.5.3 and above, 3.6, 3.7, and 3.8. +Officially Python 3.6 and above, 3.7, and 3.8. Installing pandas ----------------- @@ -140,7 +140,7 @@ Installing with ActivePython Installation instructions for `ActivePython `__ can be found `here `__. Versions -2.7 and 3.5 include pandas. +2.7, 3.5 and 3.6 include pandas. Installing using your Linux distribution's package manager. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 8c1ce1195369d..e57c553714884 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -3,6 +3,10 @@ What's new in 1.0.0 (??) ------------------------ +.. warning:: + + Starting with the 1.x series of releases, pandas only supports Python 3.6 and higher. + New Deprecation Policy ~~~~~~~~~~~~~~~~~~~~~~ From 74f0cc4c7c47a9d91e47ccced75a6ab79d479056 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Thu, 24 Oct 2019 14:52:16 -0500 Subject: [PATCH 03/14] Removing PY35 compatibility stuff, and other updates --- ci/deps/azure-macos-36.yaml | 2 +- pandas/compat/__init__.py | 1 - pandas/io/json/_json.py | 4 +-- .../tests/groupby/aggregate/test_aggregate.py | 11 -------- .../tests/io/json/test_json_table_schema.py | 22 +++++---------- pandas/tests/io/json/test_pandas.py | 27 +++---------------- pandas/tests/scalar/period/test_period.py | 8 ------ pyproject.toml | 2 -- 8 files changed, 12 insertions(+), 65 deletions(-) diff --git a/ci/deps/azure-macos-36.yaml b/ci/deps/azure-macos-36.yaml index 4e0f09904b695..85c090bf6f938 100644 --- a/ci/deps/azure-macos-36.yaml +++ b/ci/deps/azure-macos-36.yaml @@ -14,7 +14,7 @@ dependencies: - openpyxl - pyarrow - pytables - - python=3.5.* + - python=3.6.* - python-dateutil==2.6.1 - pytz - xarray diff --git a/pandas/compat/__init__.py b/pandas/compat/__init__.py index 9c778f68727c6..104240eee52b5 100644 --- a/pandas/compat/__init__.py +++ b/pandas/compat/__init__.py @@ -12,7 +12,6 @@ import sys import warnings -PY35 = sys.version_info[:2] == (3, 5) PY36 = sys.version_info >= (3, 6) PY37 = sys.version_info >= (3, 7) PY38 = sys.version_info >= (3, 8) diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py index 6e9e0a0b01200..8615355996031 100644 --- a/pandas/io/json/_json.py +++ b/pandas/io/json/_json.py @@ -12,7 +12,7 @@ from pandas.core.dtypes.common import ensure_str, is_period_dtype -from pandas import DataFrame, MultiIndex, Series, compat, isna, to_datetime +from pandas import DataFrame, MultiIndex, Series, isna, to_datetime from pandas._typing import JSONSerializable from pandas.core.reshape.concat import concat @@ -1115,8 +1115,6 @@ def _parse_no_numpy(self): dtype=None, orient="index", ) - if compat.PY35: - self.obj = self.obj.sort_index(axis="columns").sort_index(axis="index") elif orient == "table": self.obj = parse_table_schema(json, precise_float=self.precise_float) else: diff --git a/pandas/tests/groupby/aggregate/test_aggregate.py b/pandas/tests/groupby/aggregate/test_aggregate.py index aa80c461a00e7..75e2d9e83e6b9 100644 --- a/pandas/tests/groupby/aggregate/test_aggregate.py +++ b/pandas/tests/groupby/aggregate/test_aggregate.py @@ -573,8 +573,6 @@ def test_agg_with_one_lambda(self): # sort for 35 and earlier columns = ["height_sqr_min", "height_max", "weight_max"] - if compat.PY35: - columns = ["height_max", "height_sqr_min", "weight_max"] expected = pd.DataFrame( { "height_sqr_min": [82.81, 36.00], @@ -613,7 +611,6 @@ def test_agg_multiple_lambda(self): "weight": [7.9, 7.5, 9.9, 198.0], } ) - # sort for 35 and earlier columns = [ "height_sqr_min", "height_max", @@ -621,14 +618,6 @@ def test_agg_multiple_lambda(self): "height_max_2", "weight_min", ] - if compat.PY35: - columns = [ - "height_max", - "height_max_2", - "height_sqr_min", - "weight_max", - "weight_min", - ] expected = pd.DataFrame( { "height_sqr_min": [82.81, 36.00], diff --git a/pandas/tests/io/json/test_json_table_schema.py b/pandas/tests/io/json/test_json_table_schema.py index 569e299860614..ef9b0bdf053e9 100644 --- a/pandas/tests/io/json/test_json_table_schema.py +++ b/pandas/tests/io/json/test_json_table_schema.py @@ -5,8 +5,6 @@ import numpy as np import pytest -from pandas.compat import PY35 - from pandas.core.dtypes.dtypes import CategoricalDtype, DatetimeTZDtype, PeriodDtype import pandas as pd @@ -22,14 +20,6 @@ ) -def assert_results_equal(result, expected): - """Helper function for comparing deserialized JSON with Py35 compat.""" - if PY35: - assert sorted(result.items()) == sorted(expected.items()) - else: - assert result == expected - - class TestBuildSchema: def setup_method(self, method): self.df = DataFrame( @@ -245,7 +235,7 @@ def test_build_series(self): ] ) - assert_results_equal(result, expected) + assert result == expected def test_to_json(self): df = self.df.copy() @@ -335,7 +325,7 @@ def test_to_json(self): ] expected = OrderedDict([("schema", schema), ("data", data)]) - assert_results_equal(result, expected) + assert result == expected def test_to_json_float_index(self): data = pd.Series(1, index=[1.0, 2.0]) @@ -365,7 +355,7 @@ def test_to_json_float_index(self): ] ) - assert_results_equal(result, expected) + assert result == expected def test_to_json_period_index(self): idx = pd.period_range("2016", freq="Q-JAN", periods=2) @@ -386,7 +376,7 @@ def test_to_json_period_index(self): ] expected = OrderedDict([("schema", schema), ("data", data)]) - assert_results_equal(result, expected) + assert result == expected def test_to_json_categorical_index(self): data = pd.Series(1, pd.CategoricalIndex(["a", "b"])) @@ -421,7 +411,7 @@ def test_to_json_categorical_index(self): ] ) - assert_results_equal(result, expected) + assert result == expected def test_date_format_raises(self): with pytest.raises(ValueError): @@ -558,7 +548,7 @@ def test_categorical(self): ] ) - assert_results_equal(result, expected) + assert result == expected @pytest.mark.parametrize( "idx,nm,prop", diff --git a/pandas/tests/io/json/test_pandas.py b/pandas/tests/io/json/test_pandas.py index 8e28740c70bad..d7fa8f3a9a432 100644 --- a/pandas/tests/io/json/test_pandas.py +++ b/pandas/tests/io/json/test_pandas.py @@ -7,7 +7,7 @@ import numpy as np import pytest -from pandas.compat import PY35, is_platform_32bit, is_platform_windows +from pandas.compat import is_platform_32bit, is_platform_windows import pandas.util._test_decorators as td import pandas as pd @@ -166,9 +166,6 @@ def test_roundtrip_simple(self, orient, convert_axes, numpy, dtype): expected = self.frame.copy() - if not numpy and PY35 and orient in ("index", "columns"): - expected = expected.sort_index() - assert_json_roundtrip_equal(result, expected, orient) @pytest.mark.parametrize("dtype", [False, np.int64]) @@ -180,9 +177,6 @@ def test_roundtrip_intframe(self, orient, convert_axes, numpy, dtype): data, orient=orient, convert_axes=convert_axes, numpy=numpy, dtype=dtype ) expected = self.intframe.copy() - if not numpy and PY35 and orient in ("index", "columns"): - expected = expected.sort_index() - if ( numpy and (is_platform_32bit() or is_platform_windows()) @@ -215,9 +209,6 @@ def test_roundtrip_str_axes(self, orient, convert_axes, numpy, dtype): ) expected = df.copy() - if not numpy and PY35 and orient in ("index", "columns"): - expected = expected.sort_index() - if not dtype: expected = expected.astype(np.int64) @@ -256,7 +247,7 @@ def test_roundtrip_categorical(self, orient, convert_axes, numpy): expected.index = expected.index.astype(str) # Categorical not preserved expected.index.name = None # index names aren't preserved in JSON - if not numpy and (orient == "index" or (PY35 and orient == "columns")): + if not numpy and orient == "index": expected = expected.sort_index() assert_json_roundtrip_equal(result, expected, orient) @@ -323,7 +314,7 @@ def test_roundtrip_mixed(self, orient, convert_axes, numpy): expected = df.copy() expected = expected.assign(**expected.select_dtypes("number").astype(np.int64)) - if not numpy and (orient == "index" or (PY35 and orient == "columns")): + if not numpy and orient == "index": expected = expected.sort_index() assert_json_roundtrip_equal(result, expected, orient) @@ -658,8 +649,6 @@ def test_series_roundtrip_simple(self, orient, numpy): result = pd.read_json(data, typ="series", orient=orient, numpy=numpy) expected = self.series.copy() - if not numpy and PY35 and orient in ("index", "columns"): - expected = expected.sort_index() if orient in ("values", "records"): expected = expected.reset_index(drop=True) if orient != "split": @@ -676,8 +665,6 @@ def test_series_roundtrip_object(self, orient, numpy, dtype): ) expected = self.objSeries.copy() - if not numpy and PY35 and orient in ("index", "columns"): - expected = expected.sort_index() if orient in ("values", "records"): expected = expected.reset_index(drop=True) if orient != "split": @@ -692,8 +679,6 @@ def test_series_roundtrip_empty(self, orient, numpy): expected = self.empty_series.copy() # TODO: see what causes inconsistency - if not numpy and PY35 and orient == "index": - expected = expected.sort_index() if orient in ("values", "records"): expected = expected.reset_index(drop=True) else: @@ -1615,11 +1600,7 @@ def test_json_indent_all_orients(self, orient, expected): # GH 12004 df = pd.DataFrame([["foo", "bar"], ["baz", "qux"]], columns=["a", "b"]) result = df.to_json(orient=orient, indent=4) - - if PY35: - assert json.loads(result) == json.loads(expected) - else: - assert result == expected + assert result == expected def test_json_negative_indent_raises(self): with pytest.raises(ValueError, match="must be a nonnegative integer"): diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index a1de205afc0e2..a9f7b765f4ae1 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -10,7 +10,6 @@ from pandas._libs.tslibs.parsing import DateParseError from pandas._libs.tslibs.period import IncompatibleFrequency from pandas._libs.tslibs.timezones import dateutil_gettz, maybe_get_tz -from pandas.compat import PY35 from pandas.compat.numpy import np_datetime64_compat import pandas as pd @@ -1548,13 +1547,6 @@ def test_period_immutable(): per.freq = 2 * freq -@pytest.mark.xfail( - # xpassing on MacPython with strict=False - # https://travis-ci.org/MacPython/pandas-wheels/jobs/574706922 - PY35, - reason="Parsing as Period('0007-01-01', 'D') for reasons unknown", - strict=False, -) def test_small_year_parsing(): per1 = Period("0001-01-07", "D") assert per1.year == 1 diff --git a/pyproject.toml b/pyproject.toml index 2ec4739c2f7f8..b105f8aeb3291 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,10 +5,8 @@ requires = [ "setuptools", "wheel", "Cython>=0.29.13", # Note: sync with setup.py - "numpy==1.13.3; python_version=='3.5' and platform_system!='AIX'", "numpy==1.13.3; python_version=='3.6' and platform_system!='AIX'", "numpy==1.14.5; python_version>='3.7' and platform_system!='AIX'", - "numpy==1.16.0; python_version=='3.5' and platform_system=='AIX'", "numpy==1.16.0; python_version=='3.6' and platform_system=='AIX'", "numpy==1.16.0; python_version>='3.7' and platform_system=='AIX'", ] From da1a24fe7655264babdca177fd11d735b53c4e8f Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Thu, 24 Oct 2019 15:46:27 -0500 Subject: [PATCH 04/14] Fixing test in Mac --- pandas/tests/scalar/period/test_period.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index a9f7b765f4ae1..b7858dd6a1adf 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -1,4 +1,5 @@ from datetime import date, datetime, timedelta +import platform import numpy as np import pytest @@ -1547,6 +1548,13 @@ def test_period_immutable(): per.freq = 2 * freq +@pytest.mark.xfail( + # xpassing on MacPython with strict=False + # https://travis-ci.org/MacPython/pandas-wheels/jobs/574706922 + platform.system == 'Darwin', + reason="Parsing as Period('0007-01-01', 'D') for reasons unknown", + strict=False, +) def test_small_year_parsing(): per1 = Period("0001-01-07", "D") assert per1.year == 1 From fca25314da1782b803f51413a45b23c3c2509b53 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Thu, 24 Oct 2019 16:13:25 -0500 Subject: [PATCH 05/14] Fix typo in previous commit --- pandas/tests/scalar/period/test_period.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index b7858dd6a1adf..822609907f4da 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -1551,7 +1551,7 @@ def test_period_immutable(): @pytest.mark.xfail( # xpassing on MacPython with strict=False # https://travis-ci.org/MacPython/pandas-wheels/jobs/574706922 - platform.system == 'Darwin', + platform.system() == 'Darwin', reason="Parsing as Period('0007-01-01', 'D') for reasons unknown", strict=False, ) From 50a18ad1b818ac72eaf52333e38dbdf0573dad89 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Fri, 25 Oct 2019 10:40:30 -0500 Subject: [PATCH 06/14] Restoring build with the minimum versions of dependencies, but for py36 not py35 --- ci/azure/posix.yml | 4 ++++ ci/deps/azure-36-minimum_versions.yaml | 29 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 ci/deps/azure-36-minimum_versions.yaml diff --git a/ci/azure/posix.yml b/ci/azure/posix.yml index 99e7dda0fee3e..6b2b01c2bf2c7 100644 --- a/ci/azure/posix.yml +++ b/ci/azure/posix.yml @@ -15,6 +15,10 @@ jobs: PATTERN: "not slow and not network" ${{ if eq(parameters.name, 'Linux') }}: + py36_minimum_versions: + ENV_FILE: ci/deps/azure-36-minimum_versions.yaml + CONDA_PY: "36" + PATTERN: "not slow and not network" py36_locale_slow_old_np: ENV_FILE: ci/deps/azure-36-locale.yaml CONDA_PY: "36" diff --git a/ci/deps/azure-36-minimum_versions.yaml b/ci/deps/azure-36-minimum_versions.yaml new file mode 100644 index 0000000000000..9a82e61e62cd6 --- /dev/null +++ b/ci/deps/azure-36-minimum_versions.yaml @@ -0,0 +1,29 @@ +name: pandas-dev +channels: + - defaults + - conda-forge +dependencies: + - beautifulsoup4=4.6.0 + - bottleneck=1.2.1 + - cython>=0.29.13 + - jinja2=2.8 + - numexpr=2.6.2 + - numpy=1.13.3 + - openpyxl=2.4.8 + - pytables=3.4.2 + - python-dateutil=2.6.1 + - python=3.6 + - pytz=2017.2 + - scipy=0.19.0 + - xlrd=1.1.0 + - xlsxwriter=0.9.8 + - xlwt=1.2.0 + # universal + - hypothesis>=3.58.0 + - pytest=4.5.0 + - pytest-xdist + - pytest-mock + - pytest-azurepipelines + - pip + - pip: + - html5lib==1.0b2 From 92cce08c72fa5fe366e1ec82ba54c238b20515bb Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Fri, 25 Oct 2019 10:48:25 -0500 Subject: [PATCH 07/14] Pinning to Python 3.6.0 --- ci/deps/azure-36-minimum_versions.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/deps/azure-36-minimum_versions.yaml b/ci/deps/azure-36-minimum_versions.yaml index 9a82e61e62cd6..9d59b0c3ffabc 100644 --- a/ci/deps/azure-36-minimum_versions.yaml +++ b/ci/deps/azure-36-minimum_versions.yaml @@ -12,7 +12,7 @@ dependencies: - openpyxl=2.4.8 - pytables=3.4.2 - python-dateutil=2.6.1 - - python=3.6 + - python=3.6.0 - pytz=2017.2 - scipy=0.19.0 - xlrd=1.1.0 From bb1b53d1fe26c1948a69d5cd650c7c99d6a94535 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Fri, 25 Oct 2019 12:53:53 -0500 Subject: [PATCH 08/14] Fixing black error, moving dependency to conda --- ci/deps/azure-36-minimum_versions.yaml | 4 +--- pandas/tests/scalar/period/test_period.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ci/deps/azure-36-minimum_versions.yaml b/ci/deps/azure-36-minimum_versions.yaml index 9d59b0c3ffabc..434d510edbba9 100644 --- a/ci/deps/azure-36-minimum_versions.yaml +++ b/ci/deps/azure-36-minimum_versions.yaml @@ -19,11 +19,9 @@ dependencies: - xlsxwriter=0.9.8 - xlwt=1.2.0 # universal + - html5lib=1.0.1 - hypothesis>=3.58.0 - pytest=4.5.0 - pytest-xdist - pytest-mock - pytest-azurepipelines - - pip - - pip: - - html5lib==1.0b2 diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index 822609907f4da..9747b48fe4329 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -1551,7 +1551,7 @@ def test_period_immutable(): @pytest.mark.xfail( # xpassing on MacPython with strict=False # https://travis-ci.org/MacPython/pandas-wheels/jobs/574706922 - platform.system() == 'Darwin', + platform.system() == "Darwin", reason="Parsing as Period('0007-01-01', 'D') for reasons unknown", strict=False, ) From 4bbb571387c1f420c970e3d86a27aab0c2b9e5f2 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Fri, 25 Oct 2019 12:56:30 -0500 Subject: [PATCH 09/14] Removing comment about py35 --- pandas/tests/groupby/aggregate/test_aggregate.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/groupby/aggregate/test_aggregate.py b/pandas/tests/groupby/aggregate/test_aggregate.py index 75e2d9e83e6b9..f0f9ffed107dd 100644 --- a/pandas/tests/groupby/aggregate/test_aggregate.py +++ b/pandas/tests/groupby/aggregate/test_aggregate.py @@ -571,7 +571,6 @@ def test_agg_with_one_lambda(self): } ) - # sort for 35 and earlier columns = ["height_sqr_min", "height_max", "weight_max"] expected = pd.DataFrame( { From ad93f0a705d4bcfa49989bc84858a42a3fce09fd Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Sun, 27 Oct 2019 13:03:31 -0500 Subject: [PATCH 10/14] xfailing for the right reason (dateutil version) --- pandas/tests/scalar/period/test_period.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index 9747b48fe4329..6ed2d5cb50d7d 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -1,6 +1,7 @@ from datetime import date, datetime, timedelta -import platform +from distutils.version import StrictVersion +import dateutil import numpy as np import pytest import pytz @@ -1549,9 +1550,8 @@ def test_period_immutable(): @pytest.mark.xfail( - # xpassing on MacPython with strict=False - # https://travis-ci.org/MacPython/pandas-wheels/jobs/574706922 - platform.system() == "Darwin", + # Bug in old versions of python-dateutil (failing in 2.6.1) + StrictVersion(dateutil.__version__) <= StrictVersion("2.6.1"), reason="Parsing as Period('0007-01-01', 'D') for reasons unknown", strict=False, ) From 29e59ec180d7f7940cb62cf6582a69bb7b526585 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Sun, 27 Oct 2019 16:15:44 -0500 Subject: [PATCH 11/14] Better fix for the xfail in dateutil < 2.7.0 --- pandas/tests/scalar/period/test_period.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index 6ed2d5cb50d7d..ec8ba7ad3313f 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -1550,9 +1550,8 @@ def test_period_immutable(): @pytest.mark.xfail( - # Bug in old versions of python-dateutil (failing in 2.6.1) - StrictVersion(dateutil.__version__) <= StrictVersion("2.6.1"), - reason="Parsing as Period('0007-01-01', 'D') for reasons unknown", + StrictVersion(dateutil.__version__.split(".dev")[0]) < StrictVersion("2.7.0"), + reason="Bug in dateutil < 2.7.0 when parsing old dates: Period('0001-01-07', 'D')", strict=False, ) def test_small_year_parsing(): From 2b1abcaef43b1f8b7ab3839c1cb74ef8001ba149 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Tue, 29 Oct 2019 12:45:55 -0500 Subject: [PATCH 12/14] Temporary running tests in Python 3.5 to see if 'only integer scalar arrays' is caused by py36 --- ci/deps/azure-36-minimum_versions.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/deps/azure-36-minimum_versions.yaml b/ci/deps/azure-36-minimum_versions.yaml index 434d510edbba9..ecd17ba9999ef 100644 --- a/ci/deps/azure-36-minimum_versions.yaml +++ b/ci/deps/azure-36-minimum_versions.yaml @@ -12,7 +12,7 @@ dependencies: - openpyxl=2.4.8 - pytables=3.4.2 - python-dateutil=2.6.1 - - python=3.6.0 + - python=3.5.3 - pytz=2017.2 - scipy=0.19.0 - xlrd=1.1.0 From eebaec9f45436b2f189839a3dbac9091781b7548 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Fri, 8 Nov 2019 01:37:00 +0000 Subject: [PATCH 13/14] Restoring minimal versions build to py36 --- ci/deps/azure-36-minimum_versions.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/deps/azure-36-minimum_versions.yaml b/ci/deps/azure-36-minimum_versions.yaml index ecd17ba9999ef..434d510edbba9 100644 --- a/ci/deps/azure-36-minimum_versions.yaml +++ b/ci/deps/azure-36-minimum_versions.yaml @@ -12,7 +12,7 @@ dependencies: - openpyxl=2.4.8 - pytables=3.4.2 - python-dateutil=2.6.1 - - python=3.5.3 + - python=3.6.0 - pytz=2017.2 - scipy=0.19.0 - xlrd=1.1.0 From 4c0a0661c03fc89e069dcf6b762ab544dd12095a Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Fri, 8 Nov 2019 03:31:22 +0000 Subject: [PATCH 14/14] Requiring 3.6.1 (3.6 seems to have a bug failing our tests) --- ci/deps/azure-36-minimum_versions.yaml | 2 +- doc/source/development/contributing.rst | 2 +- doc/source/getting_started/install.rst | 2 +- doc/source/whatsnew/v1.0.0.rst | 6 +----- setup.py | 2 +- 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/ci/deps/azure-36-minimum_versions.yaml b/ci/deps/azure-36-minimum_versions.yaml index 434d510edbba9..e2c78165fe4b9 100644 --- a/ci/deps/azure-36-minimum_versions.yaml +++ b/ci/deps/azure-36-minimum_versions.yaml @@ -12,7 +12,7 @@ dependencies: - openpyxl=2.4.8 - pytables=3.4.2 - python-dateutil=2.6.1 - - python=3.6.0 + - python=3.6.1 - pytz=2017.2 - scipy=0.19.0 - xlrd=1.1.0 diff --git a/doc/source/development/contributing.rst b/doc/source/development/contributing.rst index d5851c4ed4914..8fe5b174c77d3 100644 --- a/doc/source/development/contributing.rst +++ b/doc/source/development/contributing.rst @@ -236,7 +236,7 @@ Creating a Python environment (pip) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you aren't using conda for your development environment, follow these instructions. -You'll need to have at least Python 3.6 installed on your system. +You'll need to have at least Python 3.6.1 installed on your system. **Unix**/**Mac OS** diff --git a/doc/source/getting_started/install.rst b/doc/source/getting_started/install.rst index 233dcf7419d81..f5bb152d6c1b9 100644 --- a/doc/source/getting_started/install.rst +++ b/doc/source/getting_started/install.rst @@ -18,7 +18,7 @@ Instructions for installing from source, Python version support ---------------------- -Officially Python 3.6 and above, 3.7, and 3.8. +Officially Python 3.6.1 and above, 3.7, and 3.8. Installing pandas ----------------- diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 79901051b5920..057cdff881296 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -5,7 +5,7 @@ What's new in 1.0.0 (??) .. warning:: - Starting with the 1.x series of releases, pandas only supports Python 3.6 and higher. + Starting with the 1.x series of releases, pandas only supports Python 3.6.1 and higher. New Deprecation Policy ~~~~~~~~~~~~~~~~~~~~~~ @@ -41,10 +41,6 @@ See :ref:`policies.version` for more. .. _2019 Pandas User Survey: http://dev.pandas.io/pandas-blog/2019-pandas-user-survey.html .. _SemVer: https://semver.org -.. warning:: - - The minimum supported Python version will be bumped to 3.6 in a future release. - {{ header }} These are the changes in pandas 1.0.0. See :ref:`release` for a full changelog diff --git a/setup.py b/setup.py index d510815ee5dcf..a7bc7a333cdd6 100755 --- a/setup.py +++ b/setup.py @@ -811,7 +811,7 @@ def srcpath(name=None, suffix=".pyx", subdir="src"): long_description=LONG_DESCRIPTION, classifiers=CLASSIFIERS, platforms="any", - python_requires=">=3.6", + python_requires=">=3.6.1", extras_require={ "test": [ # sync with setup.cfg minversion & install.rst