diff --git a/pandas/compat/__init__.py b/pandas/compat/__init__.py index e5779b8578889..5a52479a4bfcb 100644 --- a/pandas/compat/__init__.py +++ b/pandas/compat/__init__.py @@ -8,7 +8,6 @@ * lists: lrange(), lmap(), lzip(), lfilter() * iterable method compatibility: iteritems, iterkeys, itervalues * Uses the original method if available, otherwise uses items, keys, values. -* bind_method: binds functions to classes * add_metaclass(metaclass) - class decorator that recreates class with with the given metaclass instead (and avoids intermediary class creation) @@ -22,7 +21,6 @@ from distutils.version import LooseVersion import sys import platform -import types import struct PY2 = sys.version_info[0] == 2 @@ -32,8 +30,6 @@ PY37 = sys.version_info >= (3, 7) PYPY = platform.python_implementation() == 'PyPy' -from pandas.compat.chainmap import DeepChainMap - # list-producing versions of the major Python iterating functions def lrange(*args, **kwargs): @@ -52,29 +48,6 @@ def lfilter(*args, **kwargs): return list(filter(*args, **kwargs)) -if PY3: - def isidentifier(s): - return s.isidentifier() - - def str_to_bytes(s, encoding=None): - return s.encode(encoding or 'ascii') - - def bytes_to_str(b, encoding=None): - return b.decode(encoding or 'utf-8') - -else: - # Python 2 - _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$") - - def isidentifier(s, dotted=False): - return bool(_name_re.match(s)) - - def str_to_bytes(s, encoding='ascii'): - return s - - def bytes_to_str(b, encoding='ascii'): - return b - if PY2: def iteritems(obj, **kw): return obj.iteritems(**kw) @@ -95,30 +68,6 @@ def iterkeys(obj, **kw): def itervalues(obj, **kw): return iter(obj.values(**kw)) - -def bind_method(cls, name, func): - """Bind a method to class, python 2 and python 3 compatible. - - Parameters - ---------- - - cls : type - class to receive bound method - name : basestring - name of method on class instance - func : function - function to be bound as method - - - Returns - ------- - None - """ - # only python 2 has bound/unbound method issue - if not PY3: - setattr(cls, name, types.MethodType(func, None, cls)) - else: - setattr(cls, name, func) # ---------------------------------------------------------------------------- # functions largely based / taken from the six module @@ -133,7 +82,7 @@ def to_str(s): Convert bytes and non-string into Python 3 str """ if isinstance(s, bytes): - s = bytes_to_str(s) + s = s.decode('utf-8') elif not isinstance(s, str): s = str(s) return s @@ -172,6 +121,7 @@ def wrapper(cls): return metaclass(cls.__name__, cls.__bases__, orig_vars) return wrapper + if PY3: def raise_with_traceback(exc, traceback=Ellipsis): if traceback == Ellipsis: @@ -207,6 +157,7 @@ def raise_with_traceback(exc, traceback=Ellipsis): else: re_type = type(re.compile('')) + # https://github.com/pandas-dev/pandas/pull/9123 def is_platform_little_endian(): """ am I little endian """ diff --git a/pandas/core/computation/pytables.py b/pandas/core/computation/pytables.py index 52e255446bd1f..6b03237d5991e 100644 --- a/pandas/core/computation/pytables.py +++ b/pandas/core/computation/pytables.py @@ -6,7 +6,7 @@ import numpy as np from pandas._libs.tslibs import Timedelta, Timestamp -from pandas.compat import DeepChainMap +from pandas.compat.chainmap import DeepChainMap from pandas.core.dtypes.common import is_list_like diff --git a/pandas/core/computation/scope.py b/pandas/core/computation/scope.py index 62d78b3e207e0..185b5dd36e4fc 100644 --- a/pandas/core/computation/scope.py +++ b/pandas/core/computation/scope.py @@ -13,7 +13,7 @@ import numpy as np from pandas._libs.tslibs import Timestamp -from pandas.compat import DeepChainMap +from pandas.compat.chainmap import DeepChainMap from pandas.core.base import StringMixin import pandas.core.computation as compu diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 5e8876404d1ad..885c499c58dfa 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -16,7 +16,7 @@ from pandas._libs import Timestamp, iNaT, properties import pandas.compat as compat -from pandas.compat import isidentifier, lrange, lzip, set_function_name, to_str +from pandas.compat import lrange, lzip, set_function_name, to_str from pandas.compat.numpy import function as nv from pandas.errors import AbstractMethodError from pandas.util._decorators import ( @@ -5150,7 +5150,7 @@ def _dir_additions(self): If info_axis is a MultiIndex, it's first level values are used. """ additions = {c for c in self._info_axis.unique(level=0)[:100] - if isinstance(c, str) and isidentifier(c)} + if isinstance(c, str) and c.isidentifier()} return super(NDFrame, self)._dir_additions().union(additions) # ---------------------------------------------------------------------- diff --git a/pandas/core/ops.py b/pandas/core/ops.py index 92465a4acd9d7..b7e24ccad3736 100644 --- a/pandas/core/ops.py +++ b/pandas/core/ops.py @@ -12,7 +12,6 @@ from pandas._libs import algos as libalgos, lib, ops as libops import pandas.compat as compat -from pandas.compat import bind_method from pandas.errors import NullFrequencyError from pandas.util._decorators import Appender @@ -1545,7 +1544,7 @@ def add_methods(cls, new_methods): force = not (issubclass(cls, ABCSparseArray) and name.startswith('__i')) if force or name not in cls.__dict__: - bind_method(cls, name, method) + setattr(cls, name, method) # ---------------------------------------------------------------------- diff --git a/pandas/io/clipboards.py b/pandas/io/clipboards.py index d5c9a1f3ec2cf..be1256edf7afe 100644 --- a/pandas/io/clipboards.py +++ b/pandas/io/clipboards.py @@ -2,8 +2,6 @@ from io import StringIO import warnings -import pandas.compat as compat - from pandas.core.dtypes.generic import ABCDataFrame from pandas import get_option, option_context @@ -38,10 +36,8 @@ def read_clipboard(sep=r'\s+', **kwargs): # pragma: no cover # Try to decode (if needed, as "text" might already be a string here). try: - text = compat.bytes_to_str( - text, encoding=(kwargs.get('encoding') or - get_option('display.encoding')) - ) + text = text.decode(kwargs.get('encoding') + or get_option('display.encoding')) except AttributeError: pass diff --git a/pandas/io/common.py b/pandas/io/common.py index bcbfa7930311e..3bdfe52a27e7e 100644 --- a/pandas/io/common.py +++ b/pandas/io/common.py @@ -16,7 +16,6 @@ from urllib.request import pathname2url, urlopen import zipfile -import pandas.compat as compat from pandas.errors import ( # noqa AbstractMethodError, DtypeWarning, EmptyDataError, ParserError, ParserWarning) @@ -460,7 +459,7 @@ def __next__(self): # readline returns bytes, not str, but Python's CSV reader # expects str, so convert the output to str before continuing - newline = compat.bytes_to_str(newline) + newline = newline.decode('utf-8') # mmap doesn't raise if reading past the allocated # data but instead returns an empty string, so raise diff --git a/pandas/tests/io/formats/test_printing.py b/pandas/tests/io/formats/test_printing.py index 1c4c97e832931..5ec9114675fdb 100644 --- a/pandas/tests/io/formats/test_printing.py +++ b/pandas/tests/io/formats/test_printing.py @@ -5,7 +5,6 @@ import pandas._config.config as cf import pandas as pd -from pandas import compat import pandas.io.formats.format as fmt import pandas.io.formats.printing as printing @@ -27,7 +26,7 @@ def test_repr_binary_type(): raw = bytes(letters, encoding=cf.get_option('display.encoding')) except TypeError: raw = bytes(letters) - b = str(compat.bytes_to_str(raw)) + b = str(raw.decode('utf-8')) res = printing.pprint_thing(b, quote_strings=True) assert res == repr(b) res = printing.pprint_thing(b, quote_strings=False) diff --git a/pandas/tests/io/json/test_ujson.py b/pandas/tests/io/json/test_ujson.py index e947100ba8605..8bf315b73366e 100644 --- a/pandas/tests/io/json/test_ujson.py +++ b/pandas/tests/io/json/test_ujson.py @@ -654,7 +654,7 @@ def test_decode_big_escape(self): # Make sure no Exception is raised. for _ in range(10): base = '\u00e5'.encode("utf-8") - quote = compat.str_to_bytes("\"") + quote = b'"' escape_input = quote + (base * 1024 * 1024 * 2) + quote ujson.decode(escape_input) diff --git a/pandas/tests/series/test_api.py b/pandas/tests/series/test_api.py index e4f8bf1dee18b..81642f65f05a4 100644 --- a/pandas/tests/series/test_api.py +++ b/pandas/tests/series/test_api.py @@ -8,7 +8,7 @@ import pytest import pandas.compat as compat -from pandas.compat import isidentifier, lzip +from pandas.compat import lzip import pandas as pd from pandas import ( @@ -282,7 +282,7 @@ def test_index_tab_completion(self, index): for i, x in enumerate(s.index.unique(level=0)): if i < 100: assert (not isinstance(x, str) or - not isidentifier(x) or x in dir_s) + not x.isidentifier() or x in dir_s) else: assert x not in dir_s