From 1b009c60c471f88ab48345d288199ff79de8bfdd Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 12 Sep 2021 17:40:41 +0300 Subject: [PATCH] Remove redundant _compat.py --- .pre-commit-config.yaml | 2 +- babel/_compat.py | 79 ------------------------------- babel/core.py | 4 +- babel/dates.py | 13 ++--- babel/localedata.py | 8 ++-- babel/messages/catalog.py | 47 ++++++++---------- babel/messages/checkers.py | 7 ++- babel/messages/extract.py | 13 +---- babel/messages/frontend.py | 27 ++++------- babel/messages/jslexer.py | 3 +- babel/messages/mofile.py | 7 ++- babel/messages/pofile.py | 15 +++--- babel/numbers.py | 8 ++-- babel/plural.py | 3 +- babel/support.py | 26 +++------- babel/units.py | 9 ++-- babel/util.py | 5 +- scripts/import_cldr.py | 60 +++++++++++------------ tests/messages/test_catalog.py | 2 +- tests/messages/test_checkers.py | 2 +- tests/messages/test_extract.py | 2 +- tests/messages/test_frontend.py | 38 +++++++-------- tests/messages/test_js_extract.py | 2 +- tests/messages/test_mofile.py | 12 ++--- tests/messages/test_pofile.py | 2 +- tests/test_core.py | 2 - tests/test_numbers.py | 2 +- tests/test_plural.py | 2 +- tests/test_smoke.py | 2 +- tests/test_support.py | 19 ++------ tests/test_util.py | 2 +- 31 files changed, 144 insertions(+), 281 deletions(-) delete mode 100644 babel/_compat.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1fd8b5cb5..0a345cee9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ - id: debug-statements - id: end-of-file-fixer - id: flake8 - exclude: (docs/conf.py|babel/messages/__init__.py|babel/__init__.py|babel/_compat.py|tests/messages/data|scripts/import_cldr.py) + exclude: (docs/conf.py|babel/messages/__init__.py|babel/__init__.py|tests/messages/data|scripts/import_cldr.py) - id: name-tests-test args: ['--django'] exclude: (tests/messages/data/) diff --git a/babel/_compat.py b/babel/_compat.py deleted file mode 100644 index 11b4d7a6b..000000000 --- a/babel/_compat.py +++ /dev/null @@ -1,79 +0,0 @@ -import sys -import array - -PY2 = sys.version_info[0] == 2 - -_identity = lambda x: x - - -if not PY2: - text_type = str - string_types = (str,) - integer_types = (int, ) - - text_to_native = lambda s, enc: s - unichr = chr - - iterkeys = lambda d: iter(d.keys()) - itervalues = lambda d: iter(d.values()) - iteritems = lambda d: iter(d.items()) - - from io import StringIO, BytesIO - import pickle - - izip = zip - imap = map - range_type = range - - cmp = lambda a, b: (a > b) - (a < b) - - array_tobytes = array.array.tobytes - from collections import abc - -else: - text_type = unicode - string_types = (str, unicode) - integer_types = (int, long) - - text_to_native = lambda s, enc: s.encode(enc) - unichr = unichr - - iterkeys = lambda d: d.iterkeys() - itervalues = lambda d: d.itervalues() - iteritems = lambda d: d.iteritems() - - from cStringIO import StringIO as BytesIO - from StringIO import StringIO - import cPickle as pickle - - from itertools import imap - from itertools import izip - range_type = xrange - - cmp = cmp - - array_tobytes = array.array.tostring - import collections as abc - -number_types = integer_types + (float,) - - -def force_text(s, encoding='utf-8', errors='strict'): - if isinstance(s, text_type): - return s - if isinstance(s, bytes): - return s.decode(encoding, errors) - return text_type(s) - - -# -# Since Python 3.3, a fast decimal implementation is already included in the -# standard library. Otherwise use cdecimal when available -# -if sys.version_info[:2] >= (3, 3): - import decimal -else: - try: - import cdecimal as decimal - except ImportError: - import decimal diff --git a/babel/core.py b/babel/core.py index a323a7295..456202fb9 100644 --- a/babel/core.py +++ b/babel/core.py @@ -9,10 +9,10 @@ :license: BSD, see LICENSE for more details. """ +import pickle import os from babel import localedata -from babel._compat import pickle, string_types from babel.plural import PluralRule __all__ = ['UnknownLocaleError', 'Locale', 'default_locale', 'negotiate_locale', @@ -262,7 +262,7 @@ def parse(cls, identifier, sep='_', resolve_likely_subtags=True): return None elif isinstance(identifier, Locale): return identifier - elif not isinstance(identifier, string_types): + elif not isinstance(identifier, str): raise TypeError('Unexpected value for identifier: %r' % (identifier,)) parts = parse_locale(identifier, sep=sep) diff --git a/babel/dates.py b/babel/dates.py index 75e8f3501..154b1dd32 100644 --- a/babel/dates.py +++ b/babel/dates.py @@ -27,7 +27,6 @@ from babel.core import default_locale, get_global, Locale from babel.util import UTC, LOCALTZ -from babel._compat import string_types, integer_types, number_types, PY2 # "If a given short metazone form is known NOT to be understood in a given # locale and the parent locale has this value such that it would normally @@ -58,10 +57,10 @@ def _get_dt_and_tzinfo(dt_or_tzinfo): if dt_or_tzinfo is None: dt = datetime.now() tzinfo = LOCALTZ - elif isinstance(dt_or_tzinfo, string_types): + elif isinstance(dt_or_tzinfo, str): dt = None tzinfo = get_timezone(dt_or_tzinfo) - elif isinstance(dt_or_tzinfo, integer_types): + elif isinstance(dt_or_tzinfo, int): dt = None tzinfo = UTC elif isinstance(dt_or_tzinfo, (datetime, time)): @@ -123,7 +122,7 @@ def _get_datetime(instant): """ if instant is None: return datetime_.utcnow() - elif isinstance(instant, integer_types) or isinstance(instant, float): + elif isinstance(instant, int) or isinstance(instant, float): return datetime_.utcfromtimestamp(instant) elif isinstance(instant, time): return datetime_.combine(date.today(), instant) @@ -173,7 +172,7 @@ def _get_time(time, tzinfo=None): """ if time is None: time = datetime.utcnow() - elif isinstance(time, number_types): + elif isinstance(time, (int, float)): time = datetime.utcfromtimestamp(time) if time.tzinfo is None: time = time.replace(tzinfo=UTC) @@ -201,7 +200,7 @@ def get_timezone(zone=None): """ if zone is None: return LOCALTZ - if not isinstance(zone, string_types): + if not isinstance(zone, str): return zone try: return _pytz.timezone(zone) @@ -1227,8 +1226,6 @@ def __unicode__(self): def __str__(self): pat = self.pattern - if PY2: - pat = pat.encode('utf-8') return pat def __mod__(self, other): diff --git a/babel/localedata.py b/babel/localedata.py index 438afb643..55e51ea99 100644 --- a/babel/localedata.py +++ b/babel/localedata.py @@ -12,14 +12,14 @@ :license: BSD, see LICENSE for more details. """ +import pickle import os import re import sys import threading +from collections import abc from itertools import chain -from babel._compat import pickle, string_types, abc - _cache = {} _cache_lock = threading.RLock() @@ -33,7 +33,7 @@ def normalize_locale(name): Returns the normalized locale ID string or `None` if the ID is not recognized. """ - if not name or not isinstance(name, string_types): + if not name or not isinstance(name, str): return None name = name.strip().lower() for locale_id in chain.from_iterable([_cache, locale_identifiers()]): @@ -64,7 +64,7 @@ def exists(name): :param name: the locale identifier string """ - if not name or not isinstance(name, string_types): + if not name or not isinstance(name, str): return False if name in _cache: return True diff --git a/babel/messages/catalog.py b/babel/messages/catalog.py index a19a3e6d8..3a48c6bcd 100644 --- a/babel/messages/catalog.py +++ b/babel/messages/catalog.py @@ -23,8 +23,7 @@ from babel.core import Locale, UnknownLocaleError from babel.dates import format_datetime from babel.messages.plurals import get_plural -from babel.util import distinct, LOCALTZ, FixedOffsetTimezone -from babel._compat import string_types, number_types, PY2, cmp, text_type, force_text +from babel.util import distinct, LOCALTZ, FixedOffsetTimezone, _cmp __all__ = ['Message', 'Catalog', 'TranslationError'] @@ -106,7 +105,7 @@ def __init__(self, id, string=u'', locations=(), flags=(), auto_comments=(), self.flags.discard('python-format') self.auto_comments = list(distinct(auto_comments)) self.user_comments = list(distinct(user_comments)) - if isinstance(previous_id, string_types): + if isinstance(previous_id, str): self.previous_id = [previous_id] else: self.previous_id = list(previous_id) @@ -123,7 +122,7 @@ def values_to_compare(obj): if isinstance(obj, Message) and obj.pluralizable: return obj.id[0], obj.context or '' return obj.id, obj.context or '' - return cmp(values_to_compare(self), values_to_compare(other)) + return _cmp(values_to_compare(self), values_to_compare(other)) def __gt__(self, other): return self.__cmp__(other) > 0 @@ -224,21 +223,6 @@ class TranslationError(Exception): #""" -if PY2: - def _parse_header(header_string): - # message_from_string only works for str, not for unicode - headers = message_from_string(header_string.encode('utf8')) - decoded_headers = {} - for name, value in headers.items(): - name = name.decode('utf8') - value = value.decode('utf8') - decoded_headers[name] = value - return decoded_headers - -else: - _parse_header = message_from_string - - class Catalog(object): """Representation of a message catalog.""" @@ -307,12 +291,12 @@ def _set_locale(self, locale): return if isinstance(locale, Locale): - self._locale_identifier = text_type(locale) + self._locale_identifier = str(locale) self._locale = locale return - if isinstance(locale, string_types): - self._locale_identifier = text_type(locale) + if isinstance(locale, str): + self._locale_identifier = str(locale) try: self._locale = Locale.parse(locale) except UnknownLocaleError: @@ -388,7 +372,7 @@ def _get_mime_headers(self): headers.append(('POT-Creation-Date', format_datetime(self.creation_date, 'yyyy-MM-dd HH:mmZ', locale='en'))) - if isinstance(self.revision_date, (datetime, time_) + number_types): + if isinstance(self.revision_date, (datetime, time_, int, float)): headers.append(('PO-Revision-Date', format_datetime(self.revision_date, 'yyyy-MM-dd HH:mmZ', locale='en'))) @@ -412,10 +396,17 @@ def _get_mime_headers(self): headers.append(('Generated-By', 'Babel %s\n' % VERSION)) return headers + def _force_text(self, s, encoding='utf-8', errors='strict'): + if isinstance(s, str): + return s + if isinstance(s, bytes): + return s.decode(encoding, errors) + return str(s) + def _set_mime_headers(self, headers): for name, value in headers: - name = force_text(name.lower(), encoding=self.charset) - value = force_text(value, encoding=self.charset) + name = self._force_text(name.lower(), encoding=self.charset) + value = self._force_text(value, encoding=self.charset) if name == 'project-id-version': parts = value.split(' ') self.project = u' '.join(parts[:-1]) @@ -523,7 +514,7 @@ def plural_expr(self): >>> Catalog(locale='ding').plural_expr # unknown locale '(n != 1)' - :type: `string_types`""" + :type: `str`""" if self._plural_expr is None: expr = '(n != 1)' if self.locale: @@ -625,7 +616,7 @@ def __setitem__(self, id, message): message = current elif id == '': # special treatment for the header message - self.mime_headers = _parse_header(message.string).items() + self.mime_headers = message_from_string(message.string).items() self.header_comment = '\n'.join([('# %s' % c).rstrip() for c in message.user_comments]) self.fuzzy = message.fuzzy @@ -773,7 +764,7 @@ def _merge(message, oldkey, newkey): fuzzy = True fuzzy_matches.add(oldkey) oldmsg = messages.get(oldkey) - if isinstance(oldmsg.id, string_types): + if isinstance(oldmsg.id, str): message.previous_id = [oldmsg.id] else: message.previous_id = list(oldmsg.id) diff --git a/babel/messages/checkers.py b/babel/messages/checkers.py index cba911d72..bf462fc34 100644 --- a/babel/messages/checkers.py +++ b/babel/messages/checkers.py @@ -12,7 +12,6 @@ """ from babel.messages.catalog import TranslationError, PYTHON_FORMAT -from babel._compat import string_types, izip #: list of format chars that are compatible to each other @@ -26,7 +25,7 @@ def num_plurals(catalog, message): """Verify the number of plurals in the translation.""" if not message.pluralizable: - if not isinstance(message.string, string_types): + if not isinstance(message.string, str): raise TranslationError("Found plural forms for non-pluralizable " "message") return @@ -54,7 +53,7 @@ def python_format(catalog, message): if not isinstance(msgstrs, (list, tuple)): msgstrs = (msgstrs,) - for msgid, msgstr in izip(msgids, msgstrs): + for msgid, msgstr in zip(msgids, msgstrs): if msgstr: _validate_format(msgid, msgstr) @@ -134,7 +133,7 @@ def _check_positional(results): if len(a) != len(b): raise TranslationError('positional format placeholders are ' 'unbalanced') - for idx, ((_, first), (_, second)) in enumerate(izip(a, b)): + for idx, ((_, first), (_, second)) in enumerate(zip(a, b)): if not _compatible(first, second): raise TranslationError('incompatible format for placeholder ' '%d: %r and %r are not compatible' % diff --git a/babel/messages/extract.py b/babel/messages/extract.py index 64497762c..7c555572a 100644 --- a/babel/messages/extract.py +++ b/babel/messages/extract.py @@ -23,7 +23,6 @@ from tokenize import generate_tokens, COMMENT, NAME, OP, STRING from babel.util import parse_encoding, parse_future_flags, pathmatch -from babel._compat import PY2, text_type from textwrap import dedent @@ -259,7 +258,7 @@ def extract(method, fileobj, keywords=DEFAULT_KEYWORDS, comment_tags=(), ... print(_('Hello, world!')) ... ''' - >>> from babel._compat import BytesIO + >>> from io import BytesIO >>> for message in extract('python', BytesIO(source)): ... print(message) (3, u'Hello, world!', [], None) @@ -408,11 +407,7 @@ def extract_python(fileobj, keywords, comment_tags, options): encoding = parse_encoding(fileobj) or options.get('encoding', 'UTF-8') future_flags = parse_future_flags(fileobj, encoding) - - if PY2: - next_line = fileobj.readline - else: - next_line = lambda: fileobj.readline().decode(encoding) + next_line = lambda: fileobj.readline().decode(encoding) tokens = generate_tokens(next_line) for tok, value, (lineno, _), _, _ in tokens: @@ -433,8 +428,6 @@ def extract_python(fileobj, keywords, comment_tags, options): continue elif call_stack == -1 and tok == COMMENT: # Strip the comment token from the line - if PY2: - value = value.decode(encoding) value = value[1:].strip() if in_translator_comments and \ translator_comments[-1][0] == lineno - 1: @@ -485,8 +478,6 @@ def extract_python(fileobj, keywords, comment_tags, options): code = compile('# coding=%s\n%s' % (str(encoding), value), '', 'eval', future_flags) value = eval(code, {'__builtins__': {}}, {}) - if PY2 and not isinstance(value, text_type): - value = value.decode(encoding) buf.append(value) elif tok == OP and value == ',': if buf: diff --git a/babel/messages/frontend.py b/babel/messages/frontend.py index a61c4f562..810acc652 100644 --- a/babel/messages/frontend.py +++ b/babel/messages/frontend.py @@ -18,12 +18,13 @@ import sys import tempfile from collections import OrderedDict +from configparser import RawConfigParser from datetime import datetime +from io import StringIO from locale import getpreferredencoding from babel import __version__ as VERSION from babel import Locale, localedata -from babel._compat import StringIO, string_types, text_type, PY2 from babel.core import UnknownLocaleError from babel.messages.catalog import Catalog from babel.messages.extract import DEFAULT_KEYWORDS, DEFAULT_MAPPING, check_and_call_extract_file, extract_from_dir @@ -34,14 +35,6 @@ from distutils.cmd import Command as _Command from distutils.errors import DistutilsOptionError, DistutilsSetupError -try: - from ConfigParser import RawConfigParser -except ImportError: - from configparser import RawConfigParser - - -po_file_read_mode = ('rU' if PY2 else 'r') - def listify_value(arg, split=None): """ @@ -80,8 +73,8 @@ def listify_value(arg, split=None): if isinstance(val, (list, tuple)): out.extend(listify_value(val, split=split)) continue - out.extend(s.strip() for s in text_type(val).split(split)) - assert all(isinstance(val, string_types) for val in out) + out.extend(s.strip() for s in str(val).split(split)) + assert all(isinstance(val, str) for val in out) return out @@ -404,7 +397,7 @@ def finalize_options(self): "are mutually exclusive") if self.input_paths: - if isinstance(self.input_paths, string_types): + if isinstance(self.input_paths, str): self.input_paths = re.split(r',\s*', self.input_paths) elif self.distribution is not None: self.input_paths = dict.fromkeys([ @@ -499,7 +492,7 @@ def _get_mappings(self): mappings = [] if self.mapping_file: - with open(self.mapping_file, po_file_read_mode) as fileobj: + with open(self.mapping_file) as fileobj: method_map, options_map = parse_mapping(fileobj) for path in self.input_paths: mappings.append((path, method_map, options_map)) @@ -507,7 +500,7 @@ def _get_mappings(self): elif getattr(self.distribution, 'message_extractors', None): message_extractors = self.distribution.message_extractors for path, mapping in message_extractors.items(): - if isinstance(mapping, string_types): + if isinstance(mapping, str): method_map, options_map = parse_mapping(StringIO(mapping)) else: method_map, options_map = [], {} @@ -1017,11 +1010,7 @@ def parse_mapping(fileobj, filename=None): parser = RawConfigParser() parser._sections = OrderedDict(parser._sections) # We need ordered sections - - if PY2: - parser.readfp(fileobj, filename) - else: - parser.read_file(fileobj, filename) + parser.read_file(fileobj, filename) for section in parser.sections(): if section == 'extractors': diff --git a/babel/messages/jslexer.py b/babel/messages/jslexer.py index c57b1213f..e3fb10f5a 100644 --- a/babel/messages/jslexer.py +++ b/babel/messages/jslexer.py @@ -11,7 +11,6 @@ """ from collections import namedtuple import re -from babel._compat import unichr operators = sorted([ '+', '-', '*', '%', '!=', '==', '<', '>', '<=', '>=', '=', @@ -117,7 +116,7 @@ def unquote_string(string): escaped_value = escaped.group() if len(escaped_value) == 4: try: - add(unichr(int(escaped_value, 16))) + add(chr(int(escaped_value, 16))) except ValueError: pass else: diff --git a/babel/messages/mofile.py b/babel/messages/mofile.py index 8d3cfc905..65c07f48d 100644 --- a/babel/messages/mofile.py +++ b/babel/messages/mofile.py @@ -13,7 +13,6 @@ import struct from babel.messages.catalog import Catalog, Message -from babel._compat import range_type, array_tobytes LE_MAGIC = 0x950412de @@ -53,7 +52,7 @@ def read_mo(fileobj): # Now put all messages from the .mo file buffer into the catalog # dictionary - for i in range_type(0, msgcount): + for i in range(0, msgcount): mlen, moff = unpack(ii, buf[origidx:origidx + 8]) mend = moff + mlen tlen, toff = unpack(ii, buf[transidx:transidx + 8]) @@ -111,7 +110,7 @@ def write_mo(fileobj, catalog, use_fuzzy=False): >>> import sys >>> from babel.messages import Catalog >>> from gettext import GNUTranslations - >>> from babel._compat import BytesIO + >>> from io import BytesIO >>> catalog = Catalog(locale='en_US') >>> catalog.add('foo', 'Voh') @@ -207,4 +206,4 @@ def write_mo(fileobj, catalog, use_fuzzy=False): 7 * 4, # start of key index 7 * 4 + len(messages) * 8, # start of value index 0, 0 # size and offset of hash table - ) + array_tobytes(array.array("i", offsets)) + ids + strs) + ) + array.array.tobytes(array.array("i", offsets)) + ids + strs) diff --git a/babel/messages/pofile.py b/babel/messages/pofile.py index be33b831d..5cd0f0aa1 100644 --- a/babel/messages/pofile.py +++ b/babel/messages/pofile.py @@ -15,8 +15,7 @@ import re from babel.messages.catalog import Catalog, Message -from babel.util import wraptext -from babel._compat import text_type, cmp +from babel.util import wraptext, _cmp def unescape(string): @@ -107,7 +106,7 @@ def __cmp__(self, other): if not other: return 1 - return cmp(text_type(self), text_type(other)) + return _cmp(str(self), str(other)) def __gt__(self, other): return self.__cmp__(other) > 0 @@ -297,7 +296,7 @@ def parse(self, fileobj): for lineno, line in enumerate(fileobj): line = line.strip() - if not isinstance(line, text_type): + if not isinstance(line, str): line = line.decode(self.catalog.charset) if not line: continue @@ -319,7 +318,7 @@ def parse(self, fileobj): self._add_message() def _invalid_pofile(self, line, lineno, msg): - assert isinstance(line, text_type) + assert isinstance(line, str) if self.abort_invalid: raise PoFileError(msg, self.catalog, line, lineno) print("WARNING:", msg) @@ -334,7 +333,7 @@ def read_po(fileobj, locale=None, domain=None, ignore_obsolete=False, charset=No file-like object and return a `Catalog`. >>> from datetime import datetime - >>> from babel._compat import StringIO + >>> from io import StringIO >>> buf = StringIO(''' ... #: main.py:1 ... #, fuzzy, python-format @@ -480,7 +479,7 @@ def write_po(fileobj, catalog, width=76, no_location=False, omit_header=False, >>> catalog.add((u'bar', u'baz'), locations=[('main.py', 3)]) - >>> from babel._compat import BytesIO + >>> from io import BytesIO >>> buf = BytesIO() >>> write_po(buf, catalog, omit_header=True) >>> print(buf.getvalue().decode("utf8")) @@ -518,7 +517,7 @@ def _normalize(key, prefix=''): return normalize(key, prefix=prefix, width=width) def _write(text): - if isinstance(text, text_type): + if isinstance(text, str): text = text.encode(catalog.charset, 'backslashreplace') fileobj.write(text) diff --git a/babel/numbers.py b/babel/numbers.py index 0fcc07e15..1b5f83ed0 100644 --- a/babel/numbers.py +++ b/babel/numbers.py @@ -18,12 +18,12 @@ # TODO: # Padding and rounding increments in pattern: # - https://www.unicode.org/reports/tr35/ (Appendix G.6) +import decimal import re from datetime import date as date_, datetime as datetime_ import warnings from babel.core import default_locale, Locale, get_global -from babel._compat import decimal, string_types try: # Python 2 @@ -85,7 +85,7 @@ def is_currency(currency, locale=None): This method always return a Boolean and never raise. """ - if not currency or not isinstance(currency, string_types): + if not currency or not isinstance(currency, str): return False try: validate_currency(currency, locale) @@ -102,7 +102,7 @@ def normalize_currency(currency, locale=None): Returns None if the currency is unknown to Babel. """ - if isinstance(currency, string_types): + if isinstance(currency, str): currency = currency.upper() if not is_currency(currency, locale): return @@ -547,7 +547,7 @@ def _format_currency_long_name( # Step 2. # Correct number to numeric type, important for looking up plural rules: - if isinstance(number, string_types): + if isinstance(number, str): number_n = float(number) else: number_n = number diff --git a/babel/plural.py b/babel/plural.py index e705e9b8d..4a5d4ec1f 100644 --- a/babel/plural.py +++ b/babel/plural.py @@ -8,10 +8,9 @@ :copyright: (c) 2013-2021 by the Babel Team. :license: BSD, see LICENSE for more details. """ +import decimal import re -from babel._compat import decimal - _plural_tags = ('zero', 'one', 'two', 'few', 'many', 'other') _fallback_tag = 'other' diff --git a/babel/support.py b/babel/support.py index 4be9ed37f..653e6ef1c 100644 --- a/babel/support.py +++ b/babel/support.py @@ -20,7 +20,6 @@ format_timedelta from babel.numbers import format_number, format_decimal, format_currency, \ format_percent, format_scientific -from babel._compat import PY2, text_type, text_to_native class Format(object): @@ -372,11 +371,6 @@ def pgettext(self, context, message): if self._fallback: return self._fallback.pgettext(context, message) return message - # Encode the Unicode tmsg back to an 8-bit string, if possible - if self._output_charset: - return text_to_native(tmsg, self._output_charset) - elif self._charset: - return text_to_native(tmsg, self._charset) return tmsg def lpgettext(self, context, message): @@ -409,10 +403,6 @@ def npgettext(self, context, singular, plural, num): ctxt_msg_id = self.CONTEXT_ENCODING % (context, singular) try: tmsg = self._catalog[(ctxt_msg_id, self.plural(num))] - if self._output_charset: - return text_to_native(tmsg, self._output_charset) - elif self._charset: - return text_to_native(tmsg, self._charset) return tmsg except KeyError: if self._fallback: @@ -454,7 +444,7 @@ def upgettext(self, context, message): if tmsg is missing: if self._fallback: return self._fallback.upgettext(context, message) - return text_type(message) + return str(message) return tmsg def unpgettext(self, context, singular, plural, num): @@ -475,9 +465,9 @@ def unpgettext(self, context, singular, plural, num): if self._fallback: return self._fallback.unpgettext(context, singular, plural, num) if num == 1: - tmsg = text_type(singular) + tmsg = str(singular) else: - tmsg = text_type(plural) + tmsg = str(plural) return tmsg def dpgettext(self, domain, context, message): @@ -525,9 +515,8 @@ def ldnpgettext(self, domain, context, singular, plural, num): return self._domains.get(domain, self).lnpgettext(context, singular, plural, num) - if not PY2: - ugettext = gettext.NullTranslations.gettext - ungettext = gettext.NullTranslations.ngettext + ugettext = gettext.NullTranslations.gettext + ungettext = gettext.NullTranslations.ngettext class Translations(NullTranslations, gettext.GNUTranslations): @@ -544,9 +533,8 @@ def __init__(self, fp=None, domain=None): super(Translations, self).__init__(fp=fp) self.domain = domain or self.DEFAULT_DOMAIN - if not PY2: - ugettext = gettext.GNUTranslations.gettext - ungettext = gettext.GNUTranslations.ngettext + ugettext = gettext.GNUTranslations.gettext + ungettext = gettext.GNUTranslations.ngettext @classmethod def load(cls, dirname=None, locales=None, domain=None): diff --git a/babel/units.py b/babel/units.py index 07637358c..bec8676aa 100644 --- a/babel/units.py +++ b/babel/units.py @@ -1,6 +1,5 @@ # -- encoding: UTF-8 -- -from babel._compat import string_types from babel.core import Locale from babel.numbers import format_decimal, LC_NUMERIC @@ -82,7 +81,7 @@ def format_unit(value, measurement_unit, length='long', format=None, locale=LC_N Number formats may be overridden with the ``format`` parameter. - >>> from babel._compat import decimal + >>> import decimal >>> format_unit(decimal.Decimal("-42.774"), 'temperature-celsius', 'short', format='#.0', locale='fr') u'-42,8\\u202f\\xb0C' @@ -119,7 +118,7 @@ def format_unit(value, measurement_unit, length='long', format=None, locale=LC_N raise UnknownUnitError(unit=measurement_unit, locale=locale) unit_patterns = locale._data["unit_patterns"][q_unit].get(length, {}) - if isinstance(value, string_types): # Assume the value is a preformatted singular. + if isinstance(value, str): # Assume the value is a preformatted singular. formatted_value = value plural_form = "one" else: @@ -245,7 +244,7 @@ def format_compound_unit( # ... failing that, construct one "by hand". - if isinstance(numerator_value, string_types): # Numerator is preformatted + if isinstance(numerator_value, str): # Numerator is preformatted formatted_numerator = numerator_value elif numerator_unit: # Numerator has unit formatted_numerator = format_unit( @@ -254,7 +253,7 @@ def format_compound_unit( else: # Unitless numerator formatted_numerator = format_decimal(numerator_value, format=format, locale=locale) - if isinstance(denominator_value, string_types): # Denominator is preformatted + if isinstance(denominator_value, str): # Denominator is preformatted formatted_denominator = denominator_value elif denominator_unit: # Denominator has unit if denominator_value == 1: # support perUnitPatterns when the denominator is 1 diff --git a/babel/util.py b/babel/util.py index a8fbac1d9..14ce8a107 100644 --- a/babel/util.py +++ b/babel/util.py @@ -15,7 +15,6 @@ import os import re import textwrap -from babel._compat import izip, imap import pytz as _pytz from babel import localtime @@ -260,3 +259,7 @@ def dst(self, dt): DSTOFFSET = localtime.DSTOFFSET DSTDIFF = localtime.DSTDIFF ZERO = localtime.ZERO + + +def _cmp(a, b): + return (a > b) - (a < b) diff --git a/scripts/import_cldr.py b/scripts/import_cldr.py index 7876d5208..a212edd06 100755 --- a/scripts/import_cldr.py +++ b/scripts/import_cldr.py @@ -15,6 +15,7 @@ import collections from optparse import OptionParser import os +import pickle import re import sys import logging @@ -33,7 +34,6 @@ sys.path.insert(0, CHECKOUT_ROOT) from babel import dates, numbers -from babel._compat import pickle, text_type from babel.dates import split_interval_pattern from babel.localedata import Alias from babel.plural import PluralRule @@ -117,7 +117,7 @@ def _extract_plural_rules(file_path): for elem in prsup.findall('.//plurals/pluralRules'): rules = [] for rule in elem.findall('pluralRule'): - rules.append((rule.attrib['count'], text_type(rule.text))) + rules.append((rule.attrib['count'], str(rule.text))) pr = PluralRule(rules) for locale in elem.attrib['locales'].split(): rule_dict[locale] = pr @@ -237,13 +237,13 @@ def parse_global(srcdir, sup): for map_zone in sup_windows_zones.findall('.//windowsZones/mapTimezones/mapZone'): if map_zone.attrib.get('territory') == '001': win_mapping[map_zone.attrib['other']] = map_zone.attrib['type'].split()[0] - for tzid in text_type(map_zone.attrib['type']).split(): - _zone_territory_map[tzid] = text_type(map_zone.attrib['territory']) + for tzid in str(map_zone.attrib['type']).split(): + _zone_territory_map[tzid] = str(map_zone.attrib['territory']) for key_elem in bcp47_timezone.findall('.//keyword/key'): if key_elem.attrib['name'] == 'tz': for elem in key_elem.findall('type'): if 'deprecated' not in elem.attrib: - aliases = text_type(elem.attrib['alias']).split() + aliases = str(elem.attrib['alias']).split() tzid = aliases.pop(0) territory = _zone_territory_map.get(tzid, '001') territory_zones.setdefault(territory, []).append(tzid) @@ -552,22 +552,22 @@ def parse_dates(data, tree, sup, regions, territory): zone_formats = data.setdefault('zone_formats', {}) for elem in tree.findall('.//timeZoneNames/gmtFormat'): if not _should_skip_elem(elem): - zone_formats['gmt'] = text_type(elem.text).replace('{0}', '%s') + zone_formats['gmt'] = str(elem.text).replace('{0}', '%s') break for elem in tree.findall('.//timeZoneNames/regionFormat'): if not _should_skip_elem(elem): - zone_formats['region'] = text_type(elem.text).replace('{0}', '%s') + zone_formats['region'] = str(elem.text).replace('{0}', '%s') break for elem in tree.findall('.//timeZoneNames/fallbackFormat'): if not _should_skip_elem(elem): zone_formats['fallback'] = ( - text_type(elem.text).replace('{0}', '%(0)s').replace('{1}', '%(1)s') + str(elem.text).replace('{0}', '%(0)s').replace('{1}', '%(1)s') ) break for elem in tree.findall('.//timeZoneNames/fallbackRegionFormat'): if not _should_skip_elem(elem): zone_formats['fallback_region'] = ( - text_type(elem.text).replace('{0}', '%(0)s').replace('{1}', '%(1)s') + str(elem.text).replace('{0}', '%(0)s').replace('{1}', '%(1)s') ) break time_zones = data.setdefault('time_zones', {}) @@ -575,22 +575,22 @@ def parse_dates(data, tree, sup, regions, territory): info = {} city = elem.findtext('exemplarCity') if city: - info['city'] = text_type(city) + info['city'] = str(city) for child in elem.findall('long/*'): - info.setdefault('long', {})[child.tag] = text_type(child.text) + info.setdefault('long', {})[child.tag] = str(child.text) for child in elem.findall('short/*'): - info.setdefault('short', {})[child.tag] = text_type(child.text) + info.setdefault('short', {})[child.tag] = str(child.text) time_zones[elem.attrib['type']] = info meta_zones = data.setdefault('meta_zones', {}) for elem in tree.findall('.//timeZoneNames/metazone'): info = {} city = elem.findtext('exemplarCity') if city: - info['city'] = text_type(city) + info['city'] = str(city) for child in elem.findall('long/*'): - info.setdefault('long', {})[child.tag] = text_type(child.text) + info.setdefault('long', {})[child.tag] = str(child.text) for child in elem.findall('short/*'): - info.setdefault('short', {})[child.tag] = text_type(child.text) + info.setdefault('short', {})[child.tag] = str(child.text) meta_zones[elem.attrib['type']] = info @@ -674,7 +674,7 @@ def parse_calendar_periods(data, calendar): for day_period in day_period_width.findall('dayPeriod'): period_type = day_period.attrib['type'] if 'alt' not in day_period.attrib: - dest_dict[period_type] = text_type(day_period.text) + dest_dict[period_type] = str(day_period.text) def parse_calendar_date_formats(data, calendar): @@ -687,7 +687,7 @@ def parse_calendar_date_formats(data, calendar): continue try: date_formats[type] = dates.parse_pattern( - text_type(elem.findtext('dateFormat/pattern')) + str(elem.findtext('dateFormat/pattern')) ) except ValueError as e: log.error(e) @@ -707,7 +707,7 @@ def parse_calendar_time_formats(data, calendar): continue try: time_formats[type] = dates.parse_pattern( - text_type(elem.findtext('timeFormat/pattern')) + str(elem.findtext('timeFormat/pattern')) ) except ValueError as e: log.error(e) @@ -727,7 +727,7 @@ def parse_calendar_datetime_skeletons(data, calendar): if _should_skip_elem(elem, type, datetime_formats): continue try: - datetime_formats[type] = text_type(elem.findtext('dateTimeFormat/pattern')) + datetime_formats[type] = str(elem.findtext('dateTimeFormat/pattern')) except ValueError as e: log.error(e) elif elem.tag == 'alias': @@ -737,7 +737,7 @@ def parse_calendar_datetime_skeletons(data, calendar): elif elem.tag == 'availableFormats': for datetime_skeleton in elem.findall('dateFormatItem'): datetime_skeletons[datetime_skeleton.attrib['id']] = ( - dates.parse_pattern(text_type(datetime_skeleton.text)) + dates.parse_pattern(str(datetime_skeleton.text)) ) @@ -750,7 +750,7 @@ def parse_number_symbols(data, tree): for elem in symbol_elem.findall('./*'): if _should_skip_elem(elem): continue - number_symbols[elem.tag] = text_type(elem.text) + number_symbols[elem.tag] = str(elem.text) def parse_decimal_formats(data, tree): @@ -767,7 +767,7 @@ def parse_decimal_formats(data, tree): continue for pattern_el in elem.findall('./decimalFormat/pattern'): pattern_type = pattern_el.attrib.get('type') - pattern = numbers.parse_pattern(text_type(pattern_el.text)) + pattern = numbers.parse_pattern(str(pattern_el.text)) if pattern_type: # This is a compact decimal format, see: # https://www.unicode.org/reports/tr35/tr35-45/tr35-numbers.html#Compact_Number_Formats @@ -794,7 +794,7 @@ def parse_scientific_formats(data, tree): type = elem.attrib.get('type') if _should_skip_elem(elem, type, scientific_formats): continue - pattern = text_type(elem.findtext('scientificFormat/pattern')) + pattern = str(elem.findtext('scientificFormat/pattern')) scientific_formats[type] = numbers.parse_pattern(pattern) @@ -808,7 +808,7 @@ def parse_percent_formats(data, tree): type = elem.attrib.get('type') if _should_skip_elem(elem, type, percent_formats): continue - pattern = text_type(elem.findtext('percentFormat/pattern')) + pattern = str(elem.findtext('percentFormat/pattern')) percent_formats[type] = numbers.parse_pattern(pattern) @@ -823,15 +823,15 @@ def parse_currency_names(data, tree): continue if 'count' in name.attrib: currency_names_plural.setdefault(code, {})[ - name.attrib['count']] = text_type(name.text) + name.attrib['count']] = str(name.text) else: - currency_names[code] = text_type(name.text) + currency_names[code] = str(name.text) for symbol in elem.findall('symbol'): if 'draft' in symbol.attrib or 'choice' in symbol.attrib: # Skip drafts and choice-patterns continue if symbol.attrib.get('alt'): # Skip alternate forms continue - currency_symbols[code] = text_type(symbol.text) + currency_symbols[code] = str(symbol.text) def parse_unit_patterns(data, tree): @@ -885,7 +885,7 @@ def parse_date_fields(data, tree): rel_time_type = rel_time.attrib['type'] for pattern in rel_time.findall('relativeTimePattern'): type_dict = date_fields[field_type].setdefault(rel_time_type, {}) - type_dict[pattern.attrib['count']] = text_type(pattern.text) + type_dict[pattern.attrib['count']] = str(pattern.text) def parse_interval_formats(data, tree): @@ -928,7 +928,7 @@ def parse_currency_formats(data, tree): child.attrib['path']) ) elif child.tag == 'pattern': - pattern = text_type(child.text) + pattern = str(child.text) currency_formats[type] = numbers.parse_pattern(pattern) @@ -939,7 +939,7 @@ def parse_currency_unit_patterns(data, tree): continue for unit_pattern_elem in currency_formats_elem.findall('./unitPattern'): count = unit_pattern_elem.attrib['count'] - pattern = text_type(unit_pattern_elem.text) + pattern = str(unit_pattern_elem.text) currency_unit_patterns[count] = pattern diff --git a/tests/messages/test_catalog.py b/tests/messages/test_catalog.py index 661999648..47e51bbc7 100644 --- a/tests/messages/test_catalog.py +++ b/tests/messages/test_catalog.py @@ -14,8 +14,8 @@ import copy import datetime import unittest +from io import StringIO -from babel._compat import StringIO from babel.dates import format_datetime, UTC from babel.messages import catalog, pofile from babel.util import FixedOffsetTimezone diff --git a/tests/messages/test_checkers.py b/tests/messages/test_checkers.py index 49abb51b0..5354e783e 100644 --- a/tests/messages/test_checkers.py +++ b/tests/messages/test_checkers.py @@ -14,6 +14,7 @@ from datetime import datetime import time import unittest +from io import BytesIO from babel import __version__ as VERSION from babel.core import Locale, UnknownLocaleError @@ -22,7 +23,6 @@ from babel.messages.plurals import PLURALS from babel.messages.pofile import read_po from babel.util import LOCALTZ -from babel._compat import BytesIO class CheckersTestCase(unittest.TestCase): diff --git a/tests/messages/test_extract.py b/tests/messages/test_extract.py index ac7f0a642..5676717a0 100644 --- a/tests/messages/test_extract.py +++ b/tests/messages/test_extract.py @@ -14,9 +14,9 @@ import codecs import sys import unittest +from io import BytesIO, StringIO from babel.messages import extract -from babel._compat import BytesIO, StringIO class ExtractPythonTestCase(unittest.TestCase): diff --git a/tests/messages/test_frontend.py b/tests/messages/test_frontend.py index b56554c81..f8b163493 100644 --- a/tests/messages/test_frontend.py +++ b/tests/messages/test_frontend.py @@ -16,6 +16,7 @@ from distutils.dist import Distribution from distutils.errors import DistutilsOptionError from distutils.log import _global_log +from io import StringIO import logging import os import shutil @@ -28,10 +29,9 @@ from babel import __version__ as VERSION from babel.dates import format_datetime from babel.messages import frontend, Catalog -from babel.messages.frontend import CommandLineInterface, extract_messages, update_catalog, po_file_read_mode +from babel.messages.frontend import CommandLineInterface, extract_messages, update_catalog from babel.util import LOCALTZ from babel.messages.pofile import read_po, write_po -from babel._compat import StringIO this_dir = os.path.abspath(os.path.dirname(__file__)) data_dir = os.path.join(this_dir, 'data') @@ -122,7 +122,7 @@ def test_input_paths_is_treated_as_list(self): self.cmd.finalize_options() self.cmd.run() - with open(pot_file, po_file_read_mode) as f: + with open(pot_file) as f: catalog = read_po(f) msg = catalog.get('bar') self.assertEqual(1, len(msg.locations)) @@ -202,7 +202,7 @@ def test_extraction_with_default_mapping(self): 'year': time.strftime('%Y'), 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(pot_file, po_file_read_mode) as f: + with open(pot_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -255,7 +255,7 @@ def test_extraction_with_mapping_file(self): 'year': time.strftime('%Y'), 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(pot_file, po_file_read_mode) as f: + with open(pot_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -313,7 +313,7 @@ def test_extraction_with_mapping_dict(self): 'year': time.strftime('%Y'), 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(pot_file, po_file_read_mode) as f: + with open(pot_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -344,7 +344,7 @@ def test_extraction_add_location_file(self): msgstr[1] "" """ - with open(pot_file, po_file_read_mode) as f: + with open(pot_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -430,7 +430,7 @@ def test_with_output_dir(self): """ % {'version': VERSION, 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(po_file, po_file_read_mode) as f: + with open(po_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -482,7 +482,7 @@ def test_keeps_catalog_non_fuzzy(self): """ % {'version': VERSION, 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(po_file, po_file_read_mode) as f: + with open(po_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -536,7 +536,7 @@ def test_correct_init_more_than_2_plurals(self): """ % {'version': VERSION, 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(po_file, po_file_read_mode) as f: + with open(po_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -587,7 +587,7 @@ def test_correct_init_singular_plural_forms(self): """ % {'version': VERSION, 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='ja_JP')} - with open(po_file, po_file_read_mode) as f: + with open(po_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -648,7 +648,7 @@ def test_supports_no_wrap(self): 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en_US'), 'long_message': long_message} - with open(po_file, po_file_read_mode) as f: + with open(po_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -708,7 +708,7 @@ def test_supports_width(self): 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en_US'), 'long_message': long_message} - with open(po_file, po_file_read_mode) as f: + with open(po_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -865,7 +865,7 @@ def test_extract_with_default_mapping(self): 'year': time.strftime('%Y'), 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(pot_file, po_file_read_mode) as f: + with open(pot_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -915,7 +915,7 @@ def test_extract_with_mapping_file(self): 'year': time.strftime('%Y'), 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(pot_file, po_file_read_mode) as f: + with open(pot_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -963,7 +963,7 @@ def test_extract_with_exact_file(self): 'year': time.strftime('%Y'), 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(pot_file, po_file_read_mode) as f: + with open(pot_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -1011,7 +1011,7 @@ def test_init_with_output_dir(self): """ % {'version': VERSION, 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(po_file, po_file_read_mode) as f: + with open(po_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -1058,7 +1058,7 @@ def test_init_singular_plural_forms(self): """ % {'version': VERSION, 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(po_file, po_file_read_mode) as f: + with open(po_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) @@ -1108,7 +1108,7 @@ def test_init_more_than_2_plural_forms(self): """ % {'version': VERSION, 'date': format_datetime(datetime(1994, 11, 11, 00, 00), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale='en')} - with open(po_file, po_file_read_mode) as f: + with open(po_file) as f: actual_content = f.read() self.assertEqual(expected_content, actual_content) diff --git a/tests/messages/test_js_extract.py b/tests/messages/test_js_extract.py index d19c255fb..73b16a934 100644 --- a/tests/messages/test_js_extract.py +++ b/tests/messages/test_js_extract.py @@ -1,6 +1,6 @@ # -- encoding: UTF-8 -- +from io import BytesIO import pytest -from babel._compat import BytesIO from babel.messages import extract diff --git a/tests/messages/test_mofile.py b/tests/messages/test_mofile.py index fb672a80c..5cc796f2c 100644 --- a/tests/messages/test_mofile.py +++ b/tests/messages/test_mofile.py @@ -13,9 +13,9 @@ import os import unittest +from io import BytesIO from babel.messages import mofile, Catalog -from babel._compat import BytesIO, text_type from babel.support import Translations @@ -56,15 +56,15 @@ def test_sorting(self): buf.seek(0) translations = Translations(fp=buf) self.assertEqual(u'Voh', translations.ugettext('foo')) - assert isinstance(translations.ugettext('foo'), text_type) + assert isinstance(translations.ugettext('foo'), str) self.assertEqual(u'Es gibt', translations.ungettext('There is', 'There are', 1)) - assert isinstance(translations.ungettext('There is', 'There are', 1), text_type) + assert isinstance(translations.ungettext('There is', 'There are', 1), str) self.assertEqual(u'Fizz', translations.ugettext('Fizz')) - assert isinstance(translations.ugettext('Fizz'), text_type) + assert isinstance(translations.ugettext('Fizz'), str) self.assertEqual(u'Fuzz', translations.ugettext('Fuzz')) - assert isinstance(translations.ugettext('Fuzz'), text_type) + assert isinstance(translations.ugettext('Fuzz'), str) self.assertEqual(u'Fuzzes', translations.ugettext('Fuzzes')) - assert isinstance(translations.ugettext('Fuzzes'), text_type) + assert isinstance(translations.ugettext('Fuzzes'), str) def test_more_plural_forms(self): catalog2 = Catalog(locale='ru_RU') diff --git a/tests/messages/test_pofile.py b/tests/messages/test_pofile.py index be1172a88..4dd13d3cd 100644 --- a/tests/messages/test_pofile.py +++ b/tests/messages/test_pofile.py @@ -13,12 +13,12 @@ from datetime import datetime import unittest +from io import BytesIO, StringIO from babel.core import Locale from babel.messages.catalog import Catalog, Message from babel.messages import pofile from babel.util import FixedOffsetTimezone -from babel._compat import StringIO, BytesIO class ReadPoTestCase(unittest.TestCase): diff --git a/tests/test_core.py b/tests/test_core.py index 558322e00..da7d0a2f6 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -302,8 +302,6 @@ def test_parse_locale(): 'babel/locale-data/es_419.dat', ]) def test_compatible_classes_in_global_and_localedata(filename): - # Use pickle module rather than cPickle since cPickle.Unpickler is a method - # on Python 2 import pickle class Unpickler(pickle.Unpickler): diff --git a/tests/test_numbers.py b/tests/test_numbers.py index 11e61d37d..896a31641 100644 --- a/tests/test_numbers.py +++ b/tests/test_numbers.py @@ -11,6 +11,7 @@ # individuals. For the exact contribution history, see the revision # history and logs, available at http://babel.edgewall.org/log/. +import decimal import unittest import pytest @@ -20,7 +21,6 @@ from babel.numbers import ( list_currencies, validate_currency, UnknownCurrencyError, is_currency, normalize_currency, get_currency_precision, get_decimal_precision, get_currency_unit_pattern) -from babel._compat import decimal class FormatDecimalTestCase(unittest.TestCase): diff --git a/tests/test_plural.py b/tests/test_plural.py index bea8115ce..809f971bb 100644 --- a/tests/test_plural.py +++ b/tests/test_plural.py @@ -10,11 +10,11 @@ # This software consists of voluntary contributions made by many # individuals. For the exact contribution history, see the revision # history and logs, available at http://babel.edgewall.org/log/. +import decimal import unittest import pytest from babel import plural, localedata -from babel._compat import decimal EPSILON = decimal.Decimal("0.0001") diff --git a/tests/test_smoke.py b/tests/test_smoke.py index 23d82aa13..f5319f21f 100644 --- a/tests/test_smoke.py +++ b/tests/test_smoke.py @@ -5,13 +5,13 @@ operations don't fail due to odd corner cases on any locale that we ship. """ +import decimal from datetime import datetime import pytest from babel import Locale from babel import dates from babel import numbers -from babel._compat import decimal @pytest.mark.all_locales diff --git a/tests/test_support.py b/tests/test_support.py index a683591dc..99217b3bf 100644 --- a/tests/test_support.py +++ b/tests/test_support.py @@ -19,13 +19,12 @@ import pytest import sys from datetime import date, datetime, timedelta +from io import BytesIO from babel import support from babel.messages import Catalog from babel.messages.mofile import write_mo -from babel._compat import BytesIO, PY2 -get_arg_spec = (inspect.getargspec if PY2 else inspect.getfullargspec) SKIP_LGETTEXT = sys.version_info >= (3, 8) @@ -219,8 +218,8 @@ def test_method_signature_compatibility(self): translations_method = getattr(self.translations, name) null_method = getattr(self.null_translations, name) self.assertEqual( - get_arg_spec(translations_method), - get_arg_spec(null_method), + inspect.getfullargspec(translations_method), + inspect.getfullargspec(null_method), ) def test_same_return_values(self): @@ -232,7 +231,7 @@ def test_same_return_values(self): for name in self.method_names(): method = getattr(self.translations, name) null_method = getattr(self.null_translations, name) - signature = get_arg_spec(method) + signature = inspect.getfullargspec(method) parameter_names = [name for name in signature.args if name != 'self'] values = [data[name] for name in parameter_names] self.assertEqual(method(*values), null_method(*values)) @@ -365,15 +364,7 @@ def test_catalog_merge_files(): t1 = support.Translations() assert t1.files == [] t1._catalog["foo"] = "bar" - if PY2: - # Explicitly use the pure-Python `StringIO` class, as we need to - # augment it with the `name` attribute, which we can't do for - # `babel._compat.BytesIO`, which is `cStringIO.StringIO` under - # `PY2`... - from StringIO import StringIO - fp = StringIO() - else: - fp = BytesIO() + fp = BytesIO() write_mo(fp, Catalog()) fp.seek(0) fp.name = "pro.mo" diff --git a/tests/test_util.py b/tests/test_util.py index b29278e00..0e9a09e0e 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -13,11 +13,11 @@ import __future__ import unittest +from io import BytesIO import pytest from babel import util -from babel._compat import BytesIO from babel.util import parse_future_flags