Skip to content

CLN: Use pandas.compat instead of sys.version_info for Python version checks #20545

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pandas/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import re
import subprocess
import sys
from pandas.compat import PY3


def get_keywords():
Expand Down Expand Up @@ -83,7 +84,7 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False):
print("unable to find command, tried %s" % (commands,))
return None
stdout = p.communicate()[0].strip()
if sys.version_info[0] >= 3:
if PY3:
stdout = stdout.decode()
if p.returncode != 0:
if verbose:
Expand Down
2 changes: 1 addition & 1 deletion pandas/compat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ def callable(obj):
return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)


if sys.version_info[0] < 3:
if PY2:
# In PY2 functools.wraps doesn't provide metadata pytest needs to generate
# decorated tests using parametrization. See pytest GH issue #2782
def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
Expand Down
4 changes: 1 addition & 3 deletions pandas/io/clipboard/clipboards.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import sys
import subprocess
from .exceptions import PyperclipException
from pandas.compat import PY2, text_type

EXCEPT_MSG = """
Pyperclip could not find a copy/paste mechanism for your system.
For more information, please visit https://pyperclip.readthedocs.org """
PY2 = sys.version_info[0] == 2
text_type = unicode if PY2 else str # noqa


def init_osx_clipboard():
Expand Down
5 changes: 3 additions & 2 deletions pandas/io/formats/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
from __future__ import print_function

import os
import sys
import shutil
from pandas.compat import PY3


__all__ = ['get_terminal_size', 'is_terminal']

Expand All @@ -29,7 +30,7 @@ def get_terminal_size():
"""
import platform

if sys.version_info[0] >= 3:
if PY3:
return shutil.get_terminal_size()

current_os = platform.system()
Expand Down
11 changes: 2 additions & 9 deletions pandas/tests/frame/test_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

import warnings
from datetime import timedelta
from distutils.version import LooseVersion
import operator
import sys
import pytest

from string import ascii_lowercase
Expand Down Expand Up @@ -1857,13 +1855,8 @@ def test_round(self):
'col1': [1.123, 2.123, 3.123],
'col2': [1.2, 2.2, 3.2]})

if LooseVersion(sys.version) < LooseVersion('2.7'):
# Rounding with decimal is a ValueError in Python < 2.7
with pytest.raises(ValueError):
df.round(nan_round_Series)
else:
with pytest.raises(TypeError):
df.round(nan_round_Series)
with pytest.raises(TypeError):
df.round(nan_round_Series)

# Make sure this doesn't break existing Series.round
tm.assert_series_equal(df['col1'].round(1), expected_rounded['col1'])
Expand Down
14 changes: 4 additions & 10 deletions pandas/tests/frame/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
# pylint: disable-msg=W0612,E1101
from copy import deepcopy
import pydoc
import sys
from distutils.version import LooseVersion

from pandas.compat import range, lrange, long
from pandas import compat
Expand Down Expand Up @@ -253,18 +251,14 @@ def test_itertuples(self):
'[(0, 1, 4), (1, 2, 5), (2, 3, 6)]')

tup = next(df.itertuples(name='TestName'))

if LooseVersion(sys.version) >= LooseVersion('2.7'):
assert tup._fields == ('Index', 'a', 'b')
assert (tup.Index, tup.a, tup.b) == tup
assert type(tup).__name__ == 'TestName'
assert tup._fields == ('Index', 'a', 'b')
assert (tup.Index, tup.a, tup.b) == tup
assert type(tup).__name__ == 'TestName'

df.columns = ['def', 'return']
tup2 = next(df.itertuples(name='TestName'))
assert tup2 == (0, 1, 4)

if LooseVersion(sys.version) >= LooseVersion('2.7'):
assert tup2._fields == ('Index', '_1', '_2')
assert tup2._fields == ('Index', '_1', '_2')

df3 = DataFrame({'f' + str(i): [i] for i in range(1024)})
# will raise SyntaxError if trying to create namedtuple
Expand Down
4 changes: 0 additions & 4 deletions pandas/tests/indexes/datetimes/test_tools.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
""" test to_datetime """

import sys
import pytz
import pytest
import locale
Expand Down Expand Up @@ -149,9 +148,6 @@ def test_to_datetime_with_non_exact(self, cache):
# GH 10834
# 8904
# exact kw
if sys.version_info < (2, 7):
pytest.skip('on python version < 2.7')

s = Series(['19MAY11', 'foobar19MAY11', '19MAY11:00:00:00',
'19MAY11 00:00:00Z'])
result = to_datetime(s, format='%d%b%y', exact=False, cache=cache)
Expand Down
5 changes: 1 addition & 4 deletions pandas/tests/io/formats/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -1256,8 +1256,6 @@ def test_to_string_float_formatting(self):

df_s = df.to_string()

# Python 2.5 just wants me to be sad. And debian 32-bit
# sys.version_info[0] == 2 and sys.version_info[1] < 6:
if _three_digit_exp():
expected = (' x\n0 0.00000e+000\n1 2.50000e-001\n'
'2 3.45600e+003\n3 1.20000e+046\n4 1.64000e+006\n'
Expand All @@ -1281,8 +1279,7 @@ def test_to_string_float_formatting(self):

df = DataFrame({'x': [1e9, 0.2512]})
df_s = df.to_string()
# Python 2.5 just wants me to be sad. And debian 32-bit
# sys.version_info[0] == 2 and sys.version_info[1] < 6:

if _three_digit_exp():
expected = (' x\n'
'0 1.000000e+009\n'
Expand Down
4 changes: 1 addition & 3 deletions pandas/tests/io/parser/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1275,10 +1275,8 @@ def test_verbose_import(self):
else: # Python engine
assert output == 'Filled 1 NA values in column a\n'

@pytest.mark.skipif(PY3, reason="won't work in Python 3")
def test_iteration_open_handle(self):
if PY3:
pytest.skip(
"won't work in Python 3 {0}".format(sys.version_info))

with tm.ensure_clean() as path:
with open(path, 'wb') as f:
Expand Down
10 changes: 2 additions & 8 deletions pandas/tests/io/test_excel.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# pylint: disable=E1101
import os
import sys
import warnings
from datetime import datetime, date, time, timedelta
from distutils.version import LooseVersion
Expand All @@ -16,7 +15,7 @@
import pandas.util.testing as tm
import pandas.util._test_decorators as td
from pandas import DataFrame, Index, MultiIndex
from pandas.compat import u, range, map, BytesIO, iteritems
from pandas.compat import u, range, map, BytesIO, iteritems, PY36
from pandas.core.config import set_option, get_option
from pandas.io.common import URLError
from pandas.io.excel import (
Expand Down Expand Up @@ -585,9 +584,6 @@ def test_read_from_s3_url(self, ext):
def test_read_from_file_url(self, ext):

# FILE
if sys.version_info[:2] < (2, 6):
pytest.skip("file:// not supported with Python < 2.6")

localtable = os.path.join(self.dirpath, 'test1' + ext)
local_table = read_excel(localtable)

Expand Down Expand Up @@ -2314,9 +2310,9 @@ def custom_converter(css):


@td.skip_if_no('openpyxl')
@pytest.mark.skipif(not PY36, reason='requires fspath')
class TestFSPath(object):

@pytest.mark.skipif(sys.version_info < (3, 6), reason='requires fspath')
def test_excelfile_fspath(self):
with tm.ensure_clean('foo.xlsx') as path:
df = DataFrame({"A": [1, 2]})
Expand All @@ -2325,8 +2321,6 @@ def test_excelfile_fspath(self):
result = os.fspath(xl)
assert result == path

@pytest.mark.skipif(sys.version_info < (3, 6), reason='requires fspath')
# @pytest.mark.xfail
def test_excelwriter_fspath(self):
with tm.ensure_clean('foo.xlsx') as path:
writer = ExcelWriter(path)
Expand Down
6 changes: 0 additions & 6 deletions pandas/tests/io/test_packers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import os
import datetime
import numpy as np
import sys
from distutils.version import LooseVersion

from pandas import compat
Expand Down Expand Up @@ -298,11 +297,6 @@ def test_nat(self):

def test_datetimes(self):

# fails under 2.6/win32 (np.datetime64 seems broken)

if LooseVersion(sys.version) < LooseVersion('2.7'):
pytest.skip('2.6 with np.datetime64 is broken')

for i in [datetime.datetime(2013, 1, 1),
datetime.datetime(2013, 1, 1, 5, 1),
datetime.date(2013, 1, 1),
Expand Down
22 changes: 6 additions & 16 deletions pandas/tests/io/test_pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@
from distutils.version import LooseVersion
import pandas as pd
from pandas import Index
from pandas.compat import is_platform_little_endian
from pandas.compat import is_platform_little_endian, PY3
import pandas
import pandas.util.testing as tm
import pandas.util._test_decorators as td
from pandas.tseries.offsets import Day, MonthEnd
import shutil
import sys


@pytest.fixture(scope='module')
Expand Down Expand Up @@ -474,21 +473,12 @@ def test_read(self, protocol, get_random_path):
tm.assert_frame_equal(df, df2)

@pytest.mark.parametrize('protocol', [3, 4])
@pytest.mark.skipif(sys.version_info[:2] >= (3, 4),
reason="Testing invalid parameters for "
"Python 2.x and 3.y (y < 4).")
@pytest.mark.skipif(PY3, reason="Testing invalid parameters for Python 2")
def test_read_bad_versions(self, protocol, get_random_path):
# For Python 2.x (respectively 3.y with y < 4), [expected]
# HIGHEST_PROTOCOL should be 2 (respectively 3). Hence, the protocol
# parameter should not exceed 2 (respectively 3).
if sys.version_info[:2] < (3, 0):
expect_hp = 2
else:
expect_hp = 3
with tm.assert_raises_regex(ValueError,
"pickle protocol %d asked for; the highest"
" available protocol is %d" % (protocol,
expect_hp)):
# For Python 2, HIGHEST_PROTOCOL should be 2.
msg = ("pickle protocol {protocol} asked for; the highest available "
"protocol is 2").format(protocol=protocol)
with tm.assert_raises_regex(ValueError, msg):
with tm.ensure_clean(get_random_path) as path:
df = tm.makeDataFrame()
df.to_pickle(path, protocol=protocol)
4 changes: 0 additions & 4 deletions pandas/tests/io/test_stata.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
import datetime as dt
import os
import struct
import sys
import warnings
from datetime import datetime
from distutils.version import LooseVersion
from collections import OrderedDict

import numpy as np
Expand Down Expand Up @@ -144,8 +142,6 @@ def test_read_dta1(self, file):
tm.assert_frame_equal(parsed, expected)

def test_read_dta2(self):
if LooseVersion(sys.version) < LooseVersion('2.7'):
pytest.skip('datetime interp under 2.6 is faulty')

expected = DataFrame.from_records(
[
Expand Down
9 changes: 4 additions & 5 deletions pandas/tests/scalar/timestamp/test_comparisons.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
import sys
from datetime import datetime
import operator

Expand All @@ -9,7 +8,7 @@
from dateutil.tz import tzutc
from pytz import utc

from pandas.compat import long
from pandas.compat import long, PY2
from pandas import Timestamp


Expand Down Expand Up @@ -104,7 +103,7 @@ def test_cant_compare_tz_naive_w_aware(self):
pytest.raises(Exception, b.__lt__, a)
pytest.raises(Exception, b.__gt__, a)

if sys.version_info < (3, 3):
if PY2:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise, <3.3 implies PY2 based on the currently supported versions. Could be more explicit if desired though.

Copy link
Member

@gfyoung gfyoung Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's reasonable. 2.7, 3.5 - 3.6 are the only supported versions.

pytest.raises(Exception, a.__eq__, b.to_pydatetime())
pytest.raises(Exception, a.to_pydatetime().__eq__, b)
else:
Expand All @@ -125,7 +124,7 @@ def test_cant_compare_tz_naive_w_aware_explicit_pytz(self):
pytest.raises(Exception, b.__lt__, a)
pytest.raises(Exception, b.__gt__, a)

if sys.version_info < (3, 3):
if PY2:
pytest.raises(Exception, a.__eq__, b.to_pydatetime())
pytest.raises(Exception, a.to_pydatetime().__eq__, b)
else:
Expand All @@ -146,7 +145,7 @@ def test_cant_compare_tz_naive_w_aware_dateutil(self):
pytest.raises(Exception, b.__lt__, a)
pytest.raises(Exception, b.__gt__, a)

if sys.version_info < (3, 3):
if PY2:
pytest.raises(Exception, a.__eq__, b.to_pydatetime())
pytest.raises(Exception, a.to_pydatetime().__eq__, b)
else:
Expand Down
7 changes: 2 additions & 5 deletions pandas/tests/util/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from collections import OrderedDict

import pytest
from pandas.compat import intern
from pandas.compat import intern, PY3
import pandas.core.common as com
from pandas.util._move import move_into_mutable_buffer, BadMove, stolenbuf
from pandas.util._decorators import deprecate_kwarg, make_signature
Expand Down Expand Up @@ -374,10 +374,7 @@ def test_exactly_one_ref(self):
# materialize as bytearray to show that it is mutable
assert bytearray(as_stolen_buf) == b'test'

@pytest.mark.skipif(
sys.version_info[0] > 2,
reason='bytes objects cannot be interned in py3',
)
@pytest.mark.skipif(PY3, reason='bytes objects cannot be interned in py3')
def test_interned(self):
salt = uuid4().hex

Expand Down
2 changes: 1 addition & 1 deletion pandas/util/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2088,7 +2088,7 @@ def dec(f):
# and conditionally raise on these exception types
_network_error_classes = (IOError, httplib.HTTPException)

if sys.version_info >= (3, 3):
if PY3:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since 3.0 - 3.4 are no longer supported, seems fine to use PY3. Could use PY35 if being explicit would be preferred here (or maybe just leave as-is).

Copy link
Member

@gfyoung gfyoung Mar 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this change. We should be encouraging code that relies solely on the supported versions of Python and not do the C-esque thing of making it super-backwards-compatible 😄

_network_error_classes += (TimeoutError,) # noqa


Expand Down