summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAarni Koskela <akx@iki.fi>2023-01-19 10:43:08 +0200
committerGitHub <noreply@github.com>2023-01-19 10:43:08 +0200
commitcf405e2836bbcc32aaeaa6b7a7cc7bbabe873019 (patch)
treec75005ebf3ac8b79a6058da9823331f7d3d3765e
parent6e02940868a73cbcf3cc86077fc83c7cb21a4780 (diff)
parentd14f9565c03ba10d493437784db439ca260ba69d (diff)
downloadbabel-cf405e2836bbcc32aaeaa6b7a7cc7bbabe873019.tar.gz
Merge pull request #949 from python-babel/ruffify
Add ruff for linting
-rw-r--r--.pre-commit-config.yaml7
-rw-r--r--babel/core.py11
-rw-r--r--babel/dates.py32
-rw-r--r--babel/localtime/__init__.py2
-rw-r--r--babel/localtime/_helpers.py1
-rw-r--r--babel/localtime/_unix.py6
-rw-r--r--babel/localtime/_win32.py3
-rw-r--r--babel/messages/catalog.py27
-rw-r--r--babel/messages/checkers.py5
-rw-r--r--babel/messages/extract.py25
-rw-r--r--babel/messages/frontend.py70
-rw-r--r--babel/messages/jslexer.py12
-rw-r--r--babel/messages/mofile.py2
-rw-r--r--babel/messages/plurals.py2
-rw-r--r--babel/messages/pofile.py34
-rw-r--r--babel/numbers.py50
-rw-r--r--babel/plural.py8
-rw-r--r--babel/support.py23
-rw-r--r--babel/units.py1
-rw-r--r--babel/util.py8
-rw-r--r--docs/conf.py17
-rw-r--r--pyproject.toml23
-rwxr-xr-xscripts/download_import_cldr.py9
-rwxr-xr-xscripts/dump_data.py2
-rwxr-xr-xscripts/dump_global.py5
-rw-r--r--scripts/generate_authors.py3
-rwxr-xr-xscripts/import_cldr.py10
-rwxr-xr-xsetup.py2
-rw-r--r--tests/conftest.py1
-rw-r--r--tests/messages/test_catalog.py46
-rw-r--r--tests/messages/test_extract.py38
-rw-r--r--tests/messages/test_frontend.py46
-rw-r--r--tests/messages/test_js_extract.py30
-rw-r--r--tests/messages/test_jslexer.py6
-rw-r--r--tests/messages/test_mofile.py18
-rw-r--r--tests/messages/test_pofile.py88
-rw-r--r--tests/test_core.py81
-rw-r--r--tests/test_date_intervals.py4
-rw-r--r--tests/test_dates.py288
-rw-r--r--tests/test_day_periods.py3
-rw-r--r--tests/test_lists.py10
-rw-r--r--tests/test_localedata.py21
-rw-r--r--tests/test_numbers.py327
-rw-r--r--tests/test_plural.py3
-rw-r--r--tests/test_smoke.py5
-rw-r--r--tests/test_support.py60
-rw-r--r--tests/test_util.py19
47 files changed, 785 insertions, 709 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index b61dac4..4c3eb9c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,4 +1,11 @@
repos:
+ - repo: https://github.com/charliermarsh/ruff-pre-commit
+ rev: v0.0.224
+ hooks:
+ - id: ruff
+ args:
+ - --fix
+ - --force-exclude
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
diff --git a/babel/core.py b/babel/core.py
index 5041c1b..ce564d7 100644
--- a/babel/core.py
+++ b/babel/core.py
@@ -46,6 +46,7 @@ if TYPE_CHECKING:
_global_data = None
_default_plural_rule = PluralRule({})
+
def _raise_no_data_error():
raise RuntimeError('The babel data files are not available. '
'This usually happens because you are using '
@@ -383,10 +384,12 @@ class Locale:
for key in ('language', 'territory', 'script', 'variant'):
if not hasattr(other, key):
return False
- return (self.language == getattr(other, 'language')) and \
- (self.territory == getattr(other, 'territory')) and \
- (self.script == getattr(other, 'script')) and \
- (self.variant == getattr(other, 'variant'))
+ return (
+ self.language == getattr(other, 'language') and # noqa: B009
+ self.territory == getattr(other, 'territory') and # noqa: B009
+ self.script == getattr(other, 'script') and # noqa: B009
+ self.variant == getattr(other, 'variant') # noqa: B009
+ )
def __ne__(self, other: object) -> bool:
return not self.__eq__(other)
diff --git a/babel/dates.py b/babel/dates.py
index 51bc7ff..e626df5 100644
--- a/babel/dates.py
+++ b/babel/dates.py
@@ -27,9 +27,9 @@ except ModuleNotFoundError:
pytz = None
import zoneinfo
+import datetime
from bisect import bisect_right
from collections.abc import Iterable
-import datetime
from babel import localtime
from babel.core import Locale, default_locale, get_global
@@ -49,7 +49,7 @@ if TYPE_CHECKING:
# empty set characters ( U+2205 )."
# - https://www.unicode.org/reports/tr35/tr35-dates.html#Metazone_Names
-NO_INHERITANCE_MARKER = u'\u2205\u2205\u2205'
+NO_INHERITANCE_MARKER = '\u2205\u2205\u2205'
if pytz:
@@ -247,13 +247,13 @@ def get_timezone(zone: str | datetime.tzinfo | None = None) -> datetime.tzinfo:
if pytz:
try:
return pytz.timezone(zone)
- except pytz.UnknownTimeZoneError as exc:
+ except pytz.UnknownTimeZoneError as exc: # noqa: F841
pass
else:
assert zoneinfo
try:
return zoneinfo.ZoneInfo(zone)
- except zoneinfo.ZoneInfoNotFoundError as exc:
+ except zoneinfo.ZoneInfoNotFoundError as exc: # noqa: F841
pass
raise LookupError(f"Unknown timezone {zone}") from exc
@@ -558,11 +558,11 @@ def get_timezone_gmt(
if return_z and hours == 0 and seconds == 0:
return 'Z'
elif seconds == 0 and width == 'iso8601_short':
- return u'%+03d' % hours
+ return '%+03d' % hours
elif width == 'short' or width == 'iso8601_short':
- pattern = u'%+03d%02d'
+ pattern = '%+03d%02d'
elif width == 'iso8601':
- pattern = u'%+03d:%02d'
+ pattern = '%+03d:%02d'
else:
pattern = locale.zone_formats['gmt'] % '%+03d:%02d'
return pattern % (hours, seconds // 60)
@@ -1083,10 +1083,10 @@ def format_timedelta(
break
# This really should not happen
if pattern is None:
- return u''
+ return ''
return pattern.replace('{0}', str(value))
- return u''
+ return ''
def _format_fallback_interval(
@@ -1349,8 +1349,7 @@ def parse_date(
month_idx = format_str.index('l')
day_idx = format_str.index('d')
- indexes = [(year_idx, 'Y'), (month_idx, 'M'), (day_idx, 'D')]
- indexes.sort()
+ indexes = sorted([(year_idx, 'Y'), (month_idx, 'M'), (day_idx, 'D')])
indexes = {item[1]: idx for idx, item in enumerate(indexes)}
# FIXME: this currently only supports numbers, but should also support month
@@ -1399,8 +1398,7 @@ def parse_time(
min_idx = format_str.index('m')
sec_idx = format_str.index('s')
- indexes = [(hour_idx, 'H'), (min_idx, 'M'), (sec_idx, 'S')]
- indexes.sort()
+ indexes = sorted([(hour_idx, 'H'), (min_idx, 'M'), (sec_idx, 'S')])
indexes = {item[1]: idx for idx, item in enumerate(indexes)}
# TODO: support time zones
@@ -1436,7 +1434,7 @@ class DateTimePattern:
return pat
def __mod__(self, other: DateTimeFormat) -> str:
- if type(other) is not DateTimeFormat:
+ if not isinstance(other, DateTimeFormat):
return NotImplemented
return self.format % other
@@ -1829,7 +1827,7 @@ def parse_pattern(pattern: str) -> DateTimePattern:
:param pattern: the formatting pattern to parse
"""
- if type(pattern) is DateTimePattern:
+ if isinstance(pattern, DateTimePattern):
return pattern
if pattern in _pattern_cache:
@@ -1849,7 +1847,7 @@ def parse_pattern(pattern: str) -> DateTimePattern:
else:
raise NotImplementedError(f"Unknown token type: {tok_type}")
- _pattern_cache[pattern] = pat = DateTimePattern(pattern, u''.join(result))
+ _pattern_cache[pattern] = pat = DateTimePattern(pattern, ''.join(result))
return pat
@@ -1884,7 +1882,7 @@ def tokenize_pattern(pattern: str) -> list[tuple[str, str | tuple[str, int]]]:
fieldchar[0] = ''
fieldnum[0] = 0
- for idx, char in enumerate(pattern.replace("''", '\0')):
+ for char in pattern.replace("''", '\0'):
if quotebuf is None:
if char == "'": # quote started
if fieldchar[0]:
diff --git a/babel/localtime/__init__.py b/babel/localtime/__init__.py
index 9d227c7..1d65fb2 100644
--- a/babel/localtime/__init__.py
+++ b/babel/localtime/__init__.py
@@ -9,9 +9,9 @@
:license: BSD, see LICENSE for more details.
"""
+import datetime
import sys
import time
-import datetime
from threading import RLock
if sys.platform == 'win32':
diff --git a/babel/localtime/_helpers.py b/babel/localtime/_helpers.py
index b7238f6..159f9a5 100644
--- a/babel/localtime/_helpers.py
+++ b/babel/localtime/_helpers.py
@@ -24,6 +24,7 @@ def _get_tzinfo(tzenv: str):
return None
+
def _get_tzinfo_or_raise(tzenv: str):
tzinfo = _get_tzinfo(tzenv)
if tzinfo is None:
diff --git a/babel/localtime/_unix.py b/babel/localtime/_unix.py
index 89b461a..eb81beb 100644
--- a/babel/localtime/_unix.py
+++ b/babel/localtime/_unix.py
@@ -1,14 +1,14 @@
+import datetime
import os
import re
-import datetime
-
from babel.localtime._helpers import (
+ _get_tzinfo,
_get_tzinfo_from_file,
_get_tzinfo_or_raise,
- _get_tzinfo,
)
+
def _tz_from_env(tzenv: str) -> datetime.tzinfo:
if tzenv[0] == ':':
tzenv = tzenv[1:]
diff --git a/babel/localtime/_win32.py b/babel/localtime/_win32.py
index 42f819a..1a52567 100644
--- a/babel/localtime/_win32.py
+++ b/babel/localtime/_win32.py
@@ -6,9 +6,10 @@ except ImportError:
winreg = None
import datetime
+from typing import Any, Dict, cast
+
from babel.core import get_global
from babel.localtime._helpers import _get_tzinfo_or_raise
-from typing import Any, Dict, cast
# When building the cldr data on windows this module gets imported.
# Because at that point there is no global.dat yet this call will
diff --git a/babel/messages/catalog.py b/babel/messages/catalog.py
index 4486bec..dead4aa 100644
--- a/babel/messages/catalog.py
+++ b/babel/messages/catalog.py
@@ -9,21 +9,20 @@
"""
from __future__ import annotations
+import datetime
import re
-
from collections import OrderedDict
-from collections.abc import Generator, Iterable, Iterator
-import datetime
+from collections.abc import Iterable, Iterator
+from copy import copy
from difflib import get_close_matches
from email import message_from_string
-from copy import copy
from typing import TYPE_CHECKING
from babel import __version__ as VERSION
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, _cmp
+from babel.util import LOCALTZ, FixedOffsetTimezone, _cmp, distinct
if TYPE_CHECKING:
from typing_extensions import TypeAlias
@@ -81,7 +80,7 @@ class Message:
def __init__(
self,
id: _MessageID,
- string: _MessageID | None = u'',
+ string: _MessageID | None = '',
locations: Iterable[tuple[str, int]] = (),
flags: Iterable[str] = (),
auto_comments: Iterable[str] = (),
@@ -108,7 +107,7 @@ class Message:
"""
self.id = id
if not string and self.pluralizable:
- string = (u'', u'')
+ string = ('', '')
self.string = string
self.locations = list(distinct(locations))
self.flags = set(flags)
@@ -234,13 +233,14 @@ class TranslationError(Exception):
translations are encountered."""
-DEFAULT_HEADER = u"""\
+DEFAULT_HEADER = """\
# Translations template for PROJECT.
# Copyright (C) YEAR ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#"""
+
def parse_separated_header(value: str) -> dict[str, str]:
# Adapted from https://peps.python.org/pep-0594/#cgi
from email.message import Message
@@ -445,7 +445,7 @@ class Catalog:
value = self._force_text(value, encoding=self.charset)
if name == 'project-id-version':
parts = value.split(' ')
- self.project = u' '.join(parts[:-1])
+ self.project = ' '.join(parts[:-1])
self.version = parts[-1]
elif name == 'report-msgid-bugs-to':
self.msgid_bugs_address = value
@@ -592,7 +592,7 @@ class Catalog:
flags = set()
if self.fuzzy:
flags |= {'fuzzy'}
- yield Message(u'', '\n'.join(buf), flags=flags)
+ yield Message('', '\n'.join(buf), flags=flags)
for key in self._messages:
yield self._messages[key]
@@ -737,7 +737,8 @@ class Catalog:
if key in self._messages:
del self._messages[key]
- def update(self,
+ def update(
+ self,
template: Catalog,
no_fuzzy_matching: bool = False,
update_header_comment: bool = False,
@@ -832,7 +833,7 @@ class Catalog:
if not isinstance(message.string, (list, tuple)):
fuzzy = True
message.string = tuple(
- [message.string] + ([u''] * (len(message.id) - 1))
+ [message.string] + ([''] * (len(message.id) - 1))
)
elif len(message.string) != self.num_plurals:
fuzzy = True
@@ -842,7 +843,7 @@ class Catalog:
message.string = message.string[0]
message.flags |= oldmsg.flags
if fuzzy:
- message.flags |= {u'fuzzy'}
+ message.flags |= {'fuzzy'}
self[message.id] = message
for message in template:
diff --git a/babel/messages/checkers.py b/babel/messages/checkers.py
index 00b84e5..38a26e8 100644
--- a/babel/messages/checkers.py
+++ b/babel/messages/checkers.py
@@ -13,8 +13,7 @@ from __future__ import annotations
from collections.abc import Callable
-from babel.messages.catalog import Catalog, Message, TranslationError, PYTHON_FORMAT
-
+from babel.messages.catalog import PYTHON_FORMAT, Catalog, Message, TranslationError
#: list of format chars that are compatible to each other
_string_format_compatibilities = [
@@ -111,7 +110,7 @@ def _validate_format(format: str, alternative: str) -> None:
def _check_positional(results: list[tuple[str, str]]) -> bool:
positional = None
- for name, char in results:
+ for name, _char in results:
if positional is None:
positional = name is None
else:
diff --git a/babel/messages/extract.py b/babel/messages/extract.py
index a426510..453742e 100644
--- a/babel/messages/extract.py
+++ b/babel/messages/extract.py
@@ -18,21 +18,29 @@
from __future__ import annotations
import ast
-from collections.abc import Callable, Collection, Generator, Iterable, Mapping, MutableSequence
import io
import os
import sys
+from collections.abc import (
+ Callable,
+ Collection,
+ Generator,
+ Iterable,
+ Mapping,
+ MutableSequence,
+)
from os.path import relpath
-from tokenize import generate_tokens, COMMENT, NAME, OP, STRING
-from typing import Any, TYPE_CHECKING
+from textwrap import dedent
+from tokenize import COMMENT, NAME, OP, STRING, generate_tokens
+from typing import TYPE_CHECKING, Any
from babel.util import parse_encoding, parse_future_flags, pathmatch
-from textwrap import dedent
if TYPE_CHECKING:
from typing import IO, Protocol
- from typing_extensions import Final, TypeAlias, TypedDict
+
from _typeshed import SupportsItems, SupportsRead, SupportsReadline
+ from typing_extensions import Final, TypeAlias, TypedDict
class _PyOptions(TypedDict, total=False):
encoding: str
@@ -82,7 +90,6 @@ DEFAULT_KEYWORDS: dict[str, _Keyword] = {
DEFAULT_MAPPING: list[tuple[str, str]] = [('**.py', 'python')]
-
def _strip_comment_tags(comments: MutableSequence[str], tags: Iterable[str]):
"""Helper function for `extract` that strips comment tags from strings
in a list of comment lines. This functions operates in-place.
@@ -652,8 +659,7 @@ def extract_javascript(
token = Token('operator', ')', token.lineno)
if options.get('parse_template_string') and not funcname and token.type == 'template_string':
- for item in parse_template_string(token.value, keywords, comment_tags, options, token.lineno):
- yield item
+ yield from parse_template_string(token.value, keywords, comment_tags, options, token.lineno)
elif token.type == 'operator' and token.value == '(':
if funcname:
@@ -786,8 +792,7 @@ def parse_template_string(
if level == 0 and expression_contents:
expression_contents = expression_contents[0:-1]
fake_file_obj = io.BytesIO(expression_contents.encode())
- for item in extract_javascript(fake_file_obj, keywords, comment_tags, options, lineno):
- yield item
+ yield from extract_javascript(fake_file_obj, keywords, comment_tags, options, lineno)
lineno += len(line_re.findall(expression_contents))
expression_contents = ''
prev_character = character
diff --git a/babel/messages/frontend.py b/babel/messages/frontend.py
index c7e921d..ab094ec 100644
--- a/babel/messages/frontend.py
+++ b/babel/messages/frontend.py
@@ -8,6 +8,7 @@
:license: BSD, see LICENSE for more details.
"""
+import datetime
import fnmatch
import logging
import optparse
@@ -18,14 +19,19 @@ import sys
import tempfile
from collections import OrderedDict
from configparser import RawConfigParser
-import datetime
from io import StringIO
+from typing import Iterable
-from babel import __version__ as VERSION
from babel import Locale, localedata
+from babel import __version__ as VERSION
from babel.core import UnknownLocaleError
-from babel.messages.catalog import Catalog, DEFAULT_HEADER
-from babel.messages.extract import DEFAULT_KEYWORDS, DEFAULT_MAPPING, check_and_call_extract_file, extract_from_dir
+from babel.messages.catalog import DEFAULT_HEADER, Catalog
+from babel.messages.extract import (
+ DEFAULT_KEYWORDS,
+ DEFAULT_MAPPING,
+ check_and_call_extract_file,
+ extract_from_dir,
+)
from babel.messages.mofile import write_mo
from babel.messages.pofile import read_po, write_po
from babel.util import LOCALTZ
@@ -38,15 +44,16 @@ try:
distutils_log = log # "distutils.log → (no replacement yet)"
try:
- from setuptools.errors import OptionError, SetupError, BaseError
+ from setuptools.errors import BaseError, OptionError, SetupError
except ImportError: # Error aliases only added in setuptools 59 (2021-11).
OptionError = SetupError = BaseError = Exception
except ImportError:
from distutils import log as distutils_log
from distutils.cmd import Command as _Command
- from distutils.errors import DistutilsOptionError as OptionError, DistutilsSetupError as SetupError, DistutilsError as BaseError
-
+ from distutils.errors import DistutilsError as BaseError
+ from distutils.errors import DistutilsOptionError as OptionError
+ from distutils.errors import DistutilsSetupError as SetupError
def listify_value(arg, split=None):
@@ -188,7 +195,7 @@ class compile_catalog(Command):
def run(self):
n_errors = 0
for domain in self.domain:
- for catalog, errors in self._run_domain(domain).items():
+ for errors in self._run_domain(domain).values():
n_errors += len(errors)
if n_errors:
self.log.error('%d errors encountered.', n_errors)
@@ -472,6 +479,27 @@ class extract_messages(Command):
else:
self.directory_filter = None
+ def _build_callback(self, path: str):
+ def callback(filename: str, method: str, options: dict):
+ if method == 'ignore':
+ return
+
+ # If we explicitly provide a full filepath, just use that.
+ # Otherwise, path will be the directory path and filename
+ # is the relative path from that dir to the file.
+ # So we can join those to get the full filepath.
+ if os.path.isfile(path):
+ filepath = path
+ else:
+ filepath = os.path.normpath(os.path.join(path, filename))
+
+ optstr = ''
+ if options:
+ opt_values = ", ".join(f'{k}="{v}"' for k, v in options.items())
+ optstr = f" ({opt_values})"
+ self.log.info('extracting messages from %s%s', filepath, optstr)
+ return callback
+
def run(self):
mappings = self._get_mappings()
with open(self.output_file, 'wb') as outfile:
@@ -483,25 +511,7 @@ class extract_messages(Command):
header_comment=(self.header_comment or DEFAULT_HEADER))
for path, method_map, options_map in mappings:
- def callback(filename, method, options):
- if method == 'ignore':
- return
-
- # If we explicitly provide a full filepath, just use that.
- # Otherwise, path will be the directory path and filename
- # is the relative path from that dir to the file.
- # So we can join those to get the full filepath.
- if os.path.isfile(path):
- filepath = path
- else:
- filepath = os.path.normpath(os.path.join(path, filename))
-
- optstr = ''
- if options:
- opt_values = ", ".join(f'{k}="{v}"' for k, v in options.items())
- optstr = f" ({opt_values})"
- self.log.info('extracting messages from %s%s', filepath, optstr)
-
+ callback = self._build_callback(path)
if os.path.isfile(path):
current_dir = os.getcwd()
extracted = check_and_call_extract_file(
@@ -842,7 +852,7 @@ class update_catalog(Command):
omit_header=self.omit_header,
ignore_obsolete=self.ignore_obsolete,
include_previous=self.previous, width=self.width)
- except:
+ except Exception:
os.remove(tmpname)
raise
@@ -937,7 +947,7 @@ class CommandLineInterface:
identifiers = localedata.locale_identifiers()
longest = max(len(identifier) for identifier in identifiers)
identifiers.sort()
- format = u'%%-%ds %%s' % (longest + 1)
+ format = '%%-%ds %%s' % (longest + 1)
for identifier in identifiers:
locale = Locale.parse(identifier)
print(format % (identifier, locale.english_name))
@@ -1105,7 +1115,7 @@ def parse_mapping(fileobj, filename=None):
return method_map, options_map
-def parse_keywords(strings=[]):
+def parse_keywords(strings: Iterable[str] = ()):
"""Parse keywords specifications from the given list of strings.
>>> kw = sorted(parse_keywords(['_', 'dgettext:2', 'dngettext:2,3', 'pgettext:1c,2']).items())
diff --git a/babel/messages/jslexer.py b/babel/messages/jslexer.py
index 07fffde..0563f62 100644
--- a/babel/messages/jslexer.py
+++ b/babel/messages/jslexer.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
"""
babel.messages.jslexer
~~~~~~~~~~~~~~~~~~~~~~
@@ -11,9 +10,8 @@
"""
from __future__ import annotations
-from collections import namedtuple
-from collections.abc import Generator, Iterator, Sequence
import re
+from collections.abc import Generator
from typing import NamedTuple
operators: list[str] = sorted([
@@ -34,11 +32,13 @@ line_join_re = re.compile(r'\\' + line_re.pattern)
uni_escape_re = re.compile(r'[a-fA-F0-9]{1,4}')
hex_escape_re = re.compile(r'[a-fA-F0-9]{1,2}')
+
class Token(NamedTuple):
type: str
value: str
lineno: int
+
_rules: list[tuple[str | None, re.Pattern[str]]] = [
(None, re.compile(r'\s+', re.UNICODE)),
(None, re.compile(r'<!--.*')),
@@ -102,7 +102,7 @@ def unquote_string(string: str) -> str:
add = result.append
pos = 0
- while 1:
+ while True:
# scan for the next escape
escape_pos = string.find('\\', pos)
if escape_pos < 0:
@@ -155,7 +155,7 @@ def unquote_string(string: str) -> str:
if pos < len(string):
add(string[pos:])
- return u''.join(result)
+ return ''.join(result)
def tokenize(source: str, jsx: bool = True, dotted: bool = True, template_string: bool = True, lineno: int = 1) -> Generator[Token, None, None]:
@@ -174,7 +174,7 @@ def tokenize(source: str, jsx: bool = True, dotted: bool = True, template_string
while pos < end:
# handle regular rules first
- for token_type, rule in rules:
+ for token_type, rule in rules: # noqa: B007
match = rule.match(source, pos)
if match is not None:
break
diff --git a/babel/messages/mofile.py b/babel/messages/mofile.py
index a96f059..0a432a7 100644
--- a/babel/messages/mofile.py
+++ b/babel/messages/mofile.py
@@ -55,7 +55,7 @@ def read_mo(fileobj: SupportsRead[bytes]) -> Catalog:
# Now put all messages from the .mo file buffer into the catalog
# dictionary
- for i in range(0, msgcount):
+ for _i in range(msgcount):
mlen, moff = unpack(ii, buf[origidx:origidx + 8])
mend = moff + mlen
tlen, toff = unpack(ii, buf[transidx:transidx + 8])
diff --git a/babel/messages/plurals.py b/babel/messages/plurals.py
index 0fdf53b..eb8de47 100644
--- a/babel/messages/plurals.py
+++ b/babel/messages/plurals.py
@@ -9,9 +9,9 @@
"""
from __future__ import annotations
-from babel.core import default_locale, Locale
from operator import itemgetter
+from babel.core import Locale, default_locale
# XXX: remove this file, duplication with babel.plural
diff --git a/babel/messages/pofile.py b/babel/messages/pofile.py
index b6d0d6e..aef8cbf 100644
--- a/babel/messages/pofile.py
+++ b/babel/messages/pofile.py
@@ -14,14 +14,15 @@ import os
import re
from collections.abc import Iterable
from typing import TYPE_CHECKING
-from babel.core import Locale
+from babel.core import Locale
from babel.messages.catalog import Catalog, Message
-from babel.util import wraptext, _cmp
+from babel.util import _cmp, wraptext
if TYPE_CHECKING:
- from _typeshed import SupportsWrite
from typing import IO, AnyStr
+
+ from _typeshed import SupportsWrite
from typing_extensions import Literal
@@ -133,7 +134,6 @@ class _NormalizedString:
return self.__cmp__(other) != 0
-
class PoFileParser:
"""Support class to read messages from a ``gettext`` PO (portable object) file
and add them to a `Catalog`
@@ -183,7 +183,7 @@ class PoFileParser:
string = ['' for _ in range(self.catalog.num_plurals)]
for idx, translation in self.translations:
if idx >= self.catalog.num_plurals:
- self._invalid_pofile(u"", self.offset, "msg has more translations than num_plurals of catalog")
+ self._invalid_pofile("", self.offset, "msg has more translations than num_plurals of catalog")
continue
string[idx] = translation.denormalize()
string = tuple(string)
@@ -319,8 +319,8 @@ class PoFileParser:
# No actual messages found, but there was some info in comments, from which
# we'll construct an empty header message
if not self.counter and (self.flags or self.user_comments or self.auto_comments):
- self.messages.append(_NormalizedString(u'""'))
- self.translations.append([0, _NormalizedString(u'""')])
+ self.messages.append(_NormalizedString('""'))
+ self.translations.append([0, _NormalizedString('""')])
self._add_message()
def _invalid_pofile(self, line, lineno, msg) -> None:
@@ -451,17 +451,17 @@ def normalize(string: str, prefix: str = '', width: int = 76) -> str:
buf = []
size = 2
while chunks:
- l = len(escape(chunks[-1])) - 2 + prefixlen
- if size + l < width:
+ length = len(escape(chunks[-1])) - 2 + prefixlen
+ if size + length < width:
buf.append(chunks.pop())
- size += l
+ size += length
else:
if not buf:
# handle long chunks by putting them on a
# separate line
buf.append(chunks.pop())
break
- lines.append(u''.join(buf))
+ lines.append(''.join(buf))
else:
lines.append(line)
else:
@@ -474,7 +474,7 @@ def normalize(string: str, prefix: str = '', width: int = 76) -> str:
if lines and not lines[-1]:
del lines[-1]
lines[-1] += '\n'
- return u'""\n' + u'\n'.join([(prefix + escape(line)) for line in lines])
+ return '""\n' + '\n'.join([(prefix + escape(line)) for line in lines])
def write_po(
@@ -585,7 +585,7 @@ def write_po(
for line in comment_header.splitlines():
lines += wraptext(line, width=width,
subsequent_indent='# ')
- comment_header = u'\n'.join(lines)
+ comment_header = '\n'.join(lines)
_write(f"{comment_header}\n")
for comment in message.user_comments:
@@ -614,11 +614,13 @@ def write_po(
locs.append(location)
_write_comment(' '.join(locs), prefix=':')
if message.flags:
- _write('#%s\n' % ', '.join([''] + sorted(message.flags)))
+ _write(f"#{', '.join(['', *sorted(message.flags)])}\n")
if message.previous_id and include_previous:
- _write_comment('msgid %s' % _normalize(message.previous_id[0]),
- prefix='|')
+ _write_comment(
+ f'msgid {_normalize(message.previous_id[0])}',
+ prefix='|',
+ )
if len(message.previous_id) > 1:
_write_comment('msgid_plural %s' % _normalize(
message.previous_id[1]
diff --git a/babel/numbers.py b/babel/numbers.py
index 5a05f91..399b70b 100644
--- a/babel/numbers.py
+++ b/babel/numbers.py
@@ -19,11 +19,11 @@
# - https://www.unicode.org/reports/tr35/ (Appendix G.6)
from __future__ import annotations
+import datetime
import decimal
import re
-from typing import TYPE_CHECKING, Any, overload
import warnings
-import datetime
+from typing import TYPE_CHECKING, Any, overload
from babel.core import Locale, default_locale, get_global
from babel.localedata import LocaleDataDict
@@ -324,7 +324,7 @@ def get_decimal_symbol(locale: Locale | str | None = LC_NUMERIC) -> str:
:param locale: the `Locale` object or locale identifier
"""
- return Locale.parse(locale).number_symbols.get('decimal', u'.')
+ return Locale.parse(locale).number_symbols.get('decimal', '.')
def get_plus_sign_symbol(locale: Locale | str | None = LC_NUMERIC) -> str:
@@ -335,7 +335,7 @@ def get_plus_sign_symbol(locale: Locale | str | None = LC_NUMERIC) -> str:
:param locale: the `Locale` object or locale identifier
"""
- return Locale.parse(locale).number_symbols.get('plusSign', u'+')
+ return Locale.parse(locale).number_symbols.get('plusSign', '+')
def get_minus_sign_symbol(locale: Locale | str | None = LC_NUMERIC) -> str:
@@ -346,7 +346,7 @@ def get_minus_sign_symbol(locale: Locale | str | None = LC_NUMERIC) -> str:
:param locale: the `Locale` object or locale identifier
"""
- return Locale.parse(locale).number_symbols.get('minusSign', u'-')
+ return Locale.parse(locale).number_symbols.get('minusSign', '-')
def get_exponential_symbol(locale: Locale | str | None = LC_NUMERIC) -> str:
@@ -357,7 +357,7 @@ def get_exponential_symbol(locale: Locale | str | None = LC_NUMERIC) -> str:
:param locale: the `Locale` object or locale identifier
"""
- return Locale.parse(locale).number_symbols.get('exponential', u'E')
+ return Locale.parse(locale).number_symbols.get('exponential', 'E')
def get_group_symbol(locale: Locale | str | None = LC_NUMERIC) -> str:
@@ -368,11 +368,11 @@ def get_group_symbol(locale: Locale | str | None = LC_NUMERIC) -> str:
:param locale: the `Locale` object or locale identifier
"""
- return Locale.parse(locale).number_symbols.get('group', u',')
+ return Locale.parse(locale).number_symbols.get('group', ',')
def format_number(number: float | decimal.Decimal | str, locale: Locale | str | None = LC_NUMERIC) -> str:
- u"""Return the given number formatted for a specific locale.
+ """Return the given number formatted for a specific locale.
>>> format_number(1099, locale='en_US') # doctest: +SKIP
u'1,099'
@@ -418,7 +418,7 @@ def format_decimal(
decimal_quantization: bool = True,
group_separator: bool = True,
) -> str:
- u"""Return the given decimal number formatted for a specific locale.
+ """Return the given decimal number formatted for a specific locale.
>>> format_decimal(1.2345, locale='en_US')
u'1.234'
@@ -473,7 +473,7 @@ def format_compact_decimal(
locale: Locale | str | None = LC_NUMERIC,
fraction_digits: int = 0,
) -> str:
- u"""Return the given decimal number formatted for a specific locale in compact form.
+ """Return the given decimal number formatted for a specific locale in compact form.
>>> format_compact_decimal(12345, format_type="short", locale='en_US')
u'12K'
@@ -555,7 +555,7 @@ def format_currency(
decimal_quantization: bool = True,
group_separator: bool = True,
) -> str:
- u"""Return formatted currency value.
+ """Return formatted currency value.
>>> format_currency(1099.98, 'USD', locale='en_US')
u'$1,099.98'
@@ -653,7 +653,7 @@ def format_currency(
try:
pattern = locale.currency_formats[format_type]
except KeyError:
- raise UnknownCurrencyFormatError(f"{format_type!r} is not a known currency format type")
+ raise UnknownCurrencyFormatError(f"{format_type!r} is not a known currency format type") from None
return pattern.apply(
number, locale, currency=currency, currency_digits=currency_digits,
@@ -711,7 +711,7 @@ def format_compact_currency(
locale: Locale | str | None = LC_NUMERIC,
fraction_digits: int = 0
) -> str:
- u"""Format a number as a currency value in compact form.
+ """Format a number as a currency value in compact form.
>>> format_compact_currency(12345, 'USD', locale='en_US')
u'$12K'
@@ -870,8 +870,8 @@ def parse_number(string: str, locale: Locale | str | None = LC_NUMERIC) -> int:
"""
try:
return int(string.replace(get_group_symbol(locale), ''))
- except ValueError:
- raise NumberFormatError(f"{string!r} is not a valid number")
+ except ValueError as ve:
+ raise NumberFormatError(f"{string!r} is not a valid number") from ve
def parse_decimal(string: str, locale: Locale | str | None = LC_NUMERIC, strict: bool = False) -> decimal.Decimal:
@@ -916,7 +916,7 @@ def parse_decimal(string: str, locale: Locale | str | None = LC_NUMERIC, strict:
decimal_symbol = get_decimal_symbol(locale)
if not strict and (
- group_symbol == u'\xa0' and # if the grouping symbol is U+00A0 NO-BREAK SPACE,
+ group_symbol == '\xa0' and # if the grouping symbol is U+00A0 NO-BREAK SPACE,
group_symbol not in string and # and the string to be parsed does not contain it,
' ' in string # but it does contain a space instead,
):
@@ -926,20 +926,20 @@ def parse_decimal(string: str, locale: Locale | str | None = LC_NUMERIC, strict:
try:
parsed = decimal.Decimal(string.replace(group_symbol, '')
.replace(decimal_symbol, '.'))
- except decimal.InvalidOperation:
- raise NumberFormatError(f"{string!r} is not a valid decimal number")
+ except decimal.InvalidOperation as exc:
+ raise NumberFormatError(f"{string!r} is not a valid decimal number") from exc
if strict and group_symbol in string:
proper = format_decimal(parsed, locale=locale, decimal_quantization=False)
if string != proper and string.rstrip('0') != (proper + decimal_symbol):
try:
parsed_alt = decimal.Decimal(string.replace(decimal_symbol, '')
.replace(group_symbol, '.'))
- except decimal.InvalidOperation:
+ except decimal.InvalidOperation as exc:
raise NumberFormatError(
f"{string!r} is not a properly formatted decimal number. "
f"Did you mean {proper!r}?",
suggestions=[proper],
- )
+ ) from exc
else:
proper_alt = format_decimal(parsed_alt, locale=locale, decimal_quantization=False)
if proper_alt == proper:
@@ -1095,7 +1095,7 @@ class NumberPattern:
scale = 0
if '%' in ''.join(self.prefix + self.suffix):
scale = 2
- elif u'‰' in ''.join(self.prefix + self.suffix):
+ elif '‰' in ''.join(self.prefix + self.suffix):
scale = 3
return scale
@@ -1222,11 +1222,11 @@ class NumberPattern:
number if self.number_pattern != '' else '',
self.suffix[is_negative]])
- if u'¤' in retval:
- retval = retval.replace(u'¤¤¤',
+ if '¤' in retval:
+ retval = retval.replace('¤¤¤',
get_currency_name(currency, value, locale))
- retval = retval.replace(u'¤¤', currency.upper())
- retval = retval.replace(u'¤', get_currency_symbol(currency, locale))
+ retval = retval.replace('¤¤', currency.upper())
+ retval = retval.replace('¤', get_currency_symbol(currency, locale))
# remove single quotes around text, except for doubled single quotes
# which are replaced with a single quote
diff --git a/babel/plural.py b/babel/plural.py
index b4f54c0..26073ff 100644
--- a/babel/plural.py
+++ b/babel/plural.py
@@ -115,7 +115,7 @@ class PluralRule:
rules = rules.items()
found = set()
self.abstract: list[tuple[str, Any]] = []
- for key, expr in sorted(list(rules)):
+ for key, expr in sorted(rules):
if key not in _plural_tags:
raise ValueError(f"unknown tag {key!r}")
elif key in found:
@@ -325,6 +325,7 @@ def cldr_modulo(a: float, b: float) -> float:
class RuleError(Exception):
"""Raised if a rule is malformed."""
+
_VARS = {
'n', # absolute value of the source number.
'i', # integer digits of n.
@@ -363,6 +364,7 @@ def tokenize_rule(s: str) -> list[tuple[str, str]]:
'Got unexpected %r' % s[pos])
return result[::-1]
+
def test_next_token(
tokens: list[tuple[str, str]],
type_: str,
@@ -519,7 +521,7 @@ class _Parser:
def _binary_compiler(tmpl):
"""Compiler factory for the `_Compiler`."""
- return lambda self, l, r: tmpl % (self.compile(l), self.compile(r))
+ return lambda self, left, right: tmpl % (self.compile(left), self.compile(right))
def _unary_compiler(tmpl):
@@ -627,7 +629,7 @@ class _UnicodeCompiler(_Compiler):
compile_mod = _binary_compiler('%s mod %s')
def compile_not(self, relation):
- return self.compile_relation(negated=True, *relation[1])
+ return self.compile_relation(*relation[1], negated=True)
def compile_relation(self, method, expr, range_list, negated=False):
ranges = []
diff --git a/babel/support.py b/babel/support.py
index a8dd230..242b492 100644
--- a/babel/support.py
+++ b/babel/support.py
@@ -16,23 +16,26 @@ import decimal
import gettext
import locale
import os
-import datetime
from collections.abc import Iterator
from typing import TYPE_CHECKING, Any, Callable
from babel.core import Locale
-
-from babel.dates import (format_date, format_datetime, format_time,
- format_timedelta, get_timezone)
-from babel.numbers import (format_compact_currency, format_compact_decimal,
- format_currency, format_decimal, format_percent,
- format_scientific)
+from babel.dates import format_date, format_datetime, format_time, format_timedelta
+from babel.numbers import (
+ format_compact_currency,
+ format_compact_decimal,
+ format_currency,
+ format_decimal,
+ format_percent,
+ format_scientific,
+)
if TYPE_CHECKING:
from typing_extensions import Literal
from babel.dates import _PredefinedTimeFormat
+
class Format:
"""Wrapper class providing the various date and number formatting functions
bound to a specific locale and time-zone.
@@ -77,6 +80,7 @@ class Format:
"""Return a date and time formatted according to the given pattern.
>>> from datetime import datetime
+ >>> from babel.dates import get_timezone
>>> fmt = Format('en_US', tzinfo=get_timezone('US/Eastern'))
>>> fmt.datetime(datetime(2007, 4, 1, 15, 30))
u'Apr 1, 2007, 11:30:00 AM'
@@ -91,6 +95,7 @@ class Format:
"""Return a time formatted according to the given pattern.
>>> from datetime import datetime
+ >>> from babel.dates import get_timezone
>>> fmt = Format('en_US', tzinfo=get_timezone('US/Eastern'))
>>> fmt.time(datetime(2007, 4, 1, 15, 30))
u'11:30:00 AM'
@@ -333,7 +338,7 @@ class LazyProxy:
return LazyProxy(
self._func,
enable_cache=self._is_cache_enabled,
- *self._args,
+ *self._args, # noqa: B026
**self._kwargs
)
@@ -342,7 +347,7 @@ class LazyProxy:
return LazyProxy(
deepcopy(self._func, memo),
enable_cache=deepcopy(self._is_cache_enabled, memo),
- *deepcopy(self._args, memo),
+ *deepcopy(self._args, memo), # noqa: B026
**deepcopy(self._kwargs, memo)
)
diff --git a/babel/units.py b/babel/units.py
index 1180bd1..0c72ee9 100644
--- a/babel/units.py
+++ b/babel/units.py
@@ -9,6 +9,7 @@ from babel.numbers import LC_NUMERIC, format_decimal
if TYPE_CHECKING:
from typing_extensions import Literal
+
class UnknownUnitError(ValueError):
def __init__(self, unit: str, locale: Locale) -> None:
ValueError.__init__(self, f"{unit} is not a known unit in {locale}")
diff --git a/babel/util.py b/babel/util.py
index d25ec53..a5403e6 100644
--- a/babel/util.py
+++ b/babel/util.py
@@ -11,19 +11,20 @@ from __future__ import annotations
import codecs
import collections
+import datetime
import os
import re
import textwrap
-from babel import localtime, dates
-
from collections.abc import Generator, Iterable
-import datetime
from typing import IO, Any, TypeVar
+from babel import dates, localtime
+
missing = object()
_T = TypeVar("_T")
+
def distinct(iterable: Iterable[_T]) -> Generator[_T, None, None]:
"""Yield all items in an iterable collection that are distinct.
@@ -43,6 +44,7 @@ def distinct(iterable: Iterable[_T]) -> Generator[_T, None, None]:
yield item
seen.add(item)
+
# Regexp to match python magic encoding line
PYTHON_MAGIC_COMMENT_re = re.compile(
br'[ \t\f]* \# .* coding[=:][ \t]*([-\w.]+)', re.VERBOSE)
diff --git a/docs/conf.py b/docs/conf.py
index c0e2389..5118f72 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -10,7 +10,8 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
-import sys, os
+import os
+import sys
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
@@ -42,8 +43,8 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
-project = u'Babel'
-copyright = u'2022, The Babel Team'
+project = 'Babel'
+copyright = '2022, The Babel Team'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -193,8 +194,8 @@ latex_elements = {
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
- ('index', 'Babel.tex', u'Babel Documentation',
- u'The Babel Team', 'manual'),
+ ('index', 'Babel.tex', 'Babel Documentation',
+ 'The Babel Team', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -223,7 +224,7 @@ latex_logo = '_static/logo.png'
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
- ('index', 'babel', u'Babel Documentation', [u'The Babel Team'], 1),
+ ('index', 'babel', 'Babel Documentation', ['The Babel Team'], 1),
]
# If true, show URL addresses after external links.
@@ -236,8 +237,8 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
- ('index_', 'Babel', u'Babel Documentation',
- u'The Babel Team', 'Babel', 'One line description of project.',
+ ('index_', 'Babel', 'Babel Documentation',
+ 'The Babel Team', 'Babel', 'One line description of project.',
'Miscellaneous'),
]
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..dbd137c
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,23 @@
+[tool.ruff]
+target-version = "py37"
+select = [
+ "B",
+ "C",
+ "E",
+ "F",
+ "I",
+ "SIM300",
+ "UP",
+]
+ignore = [
+ "C901", # Complexity
+ "E501", # Line length
+ "E731", # Do not assign a lambda expression (we use them on purpose)
+ "E741", # Ambiguous variable name
+ "UP012", # "utf-8" is on purpose
+]
+extend-exclude = [
+ "tests/messages/data",
+]
+[tool.ruff.per-file-ignores]
+"scripts/import_cldr.py" = ["E402"]
diff --git a/scripts/download_import_cldr.py b/scripts/download_import_cldr.py
index 57995b5..ab455ac 100755
--- a/scripts/download_import_cldr.py
+++ b/scripts/download_import_cldr.py
@@ -1,15 +1,14 @@
#!/usr/bin/env python3
import contextlib
+import hashlib
import os
-import sys
import shutil
-import hashlib
-import zipfile
import subprocess
+import sys
+import zipfile
from urllib.request import urlretrieve
-
URL = 'http://unicode.org/Public/cldr/41/cldr-common-41.0.zip'
FILENAME = 'cldr-common-41.0.zip'
# Via https://unicode.org/Public/cldr/41/hashes/SHASUM512
@@ -38,7 +37,7 @@ def is_good_file(filename):
return False
h = hashlib.sha512()
with open(filename, 'rb') as f:
- while 1:
+ while True:
blk = f.read(BLKSIZE)
if not blk:
break
diff --git a/scripts/dump_data.py b/scripts/dump_data.py
index e419050..041a410 100755
--- a/scripts/dump_data.py
+++ b/scripts/dump_data.py
@@ -14,7 +14,7 @@
from optparse import OptionParser
from pprint import pprint
-from babel.localedata import load, LocaleDataDict
+from babel.localedata import LocaleDataDict, load
def main():
diff --git a/scripts/dump_global.py b/scripts/dump_global.py
index 6696415..3fc95b6 100755
--- a/scripts/dump_global.py
+++ b/scripts/dump_global.py
@@ -11,10 +11,11 @@
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://babel.edgewall.org/log/.
-import cPickle as pickle
import os
-from pprint import pprint
import sys
+from pprint import pprint
+
+import cPickle as pickle
import babel
diff --git a/scripts/generate_authors.py b/scripts/generate_authors.py
index e2e3add..64c0af8 100644
--- a/scripts/generate_authors.py
+++ b/scripts/generate_authors.py
@@ -1,8 +1,7 @@
+import os
from collections import Counter
from subprocess import check_output
-import os
-
root_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
diff --git a/scripts/import_cldr.py b/scripts/import_cldr.py
index 5de707c..5630ba8 100755
--- a/scripts/import_cldr.py
+++ b/scripts/import_cldr.py
@@ -12,13 +12,12 @@
# history and logs, available at http://babel.edgewall.org/log/.
import collections
-from optparse import OptionParser
+import logging
import os
import pickle
import re
import sys
-import logging
-
+from optparse import OptionParser
from xml.etree import ElementTree
# Make sure we're using Babel source, and not some previously installed version
@@ -44,7 +43,7 @@ def _text(elem):
for child in elem:
buf.append(_text(child))
buf.append(elem.tail or '')
- return u''.join(filter(None, buf)).strip()
+ return ''.join(filter(None, buf)).strip()
NAME_RE = re.compile(r"^\w+$")
@@ -130,7 +129,7 @@ def _time_to_seconds_past_midnight(time_expr):
return None
if time_expr.count(":") == 1:
time_expr += ":00"
- hour, minute, second = [int(p, 10) for p in time_expr.split(":")]
+ hour, minute, second = (int(p, 10) for p in time_expr.split(":"))
return hour * 60 * 60 + minute * 60 + second
@@ -991,6 +990,5 @@ def parse_measurement_systems(data, tree):
_import_type_text(measurement_systems, measurement_system, type=type)
-
if __name__ == '__main__':
main()
diff --git a/setup.py b/setup.py
index db63216..df6ad8b 100755
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,7 @@
import subprocess
import sys
-from setuptools import setup, Command
+from setuptools import Command, setup
try:
from babel import __version__
diff --git a/tests/conftest.py b/tests/conftest.py
index 0506a83..67e3ce9 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,4 +1,5 @@
import os
+
import pytest
try:
diff --git a/tests/messages/test_catalog.py b/tests/messages/test_catalog.py
index e9b15a8..273c83f 100644
--- a/tests/messages/test_catalog.py
+++ b/tests/messages/test_catalog.py
@@ -15,7 +15,7 @@ import datetime
import unittest
from io import StringIO
-from babel.dates import format_datetime, UTC
+from babel.dates import UTC, format_datetime
from babel.messages import catalog, pofile
from babel.util import FixedOffsetTimezone
@@ -89,34 +89,34 @@ class CatalogTestCase(unittest.TestCase):
def test_update_message_changed_to_plural(self):
cat = catalog.Catalog()
- cat.add(u'foo', u'Voh')
+ cat.add('foo', 'Voh')
tmpl = catalog.Catalog()
- tmpl.add((u'foo', u'foos'))
+ tmpl.add(('foo', 'foos'))
cat.update(tmpl)
assert cat['foo'].string == ('Voh', '')
assert cat['foo'].fuzzy
def test_update_message_changed_to_simple(self):
cat = catalog.Catalog()
- cat.add(u'foo' u'foos', (u'Voh', u'Vöhs'))
+ cat.add('foo' 'foos', ('Voh', 'Vöhs'))
tmpl = catalog.Catalog()
- tmpl.add(u'foo')
+ tmpl.add('foo')
cat.update(tmpl)
assert cat['foo'].string == 'Voh'
assert cat['foo'].fuzzy
def test_update_message_updates_comments(self):
cat = catalog.Catalog()
- cat[u'foo'] = catalog.Message('foo', locations=[('main.py', 5)])
+ cat['foo'] = catalog.Message('foo', locations=[('main.py', 5)])
assert cat['foo'].auto_comments == []
assert cat['foo'].user_comments == []
# Update cat[u'foo'] with a new location and a comment
- cat[u'foo'] = catalog.Message('foo', locations=[('main.py', 7)],
- user_comments=['Foo Bar comment 1'])
+ cat['foo'] = catalog.Message('foo', locations=[('main.py', 7)],
+ user_comments=['Foo Bar comment 1'])
assert cat['foo'].user_comments == ['Foo Bar comment 1']
# now add yet another location with another comment
- cat[u'foo'] = catalog.Message('foo', locations=[('main.py', 9)],
- auto_comments=['Foo Bar comment 2'])
+ cat['foo'] = catalog.Message('foo', locations=[('main.py', 9)],
+ auto_comments=['Foo Bar comment 2'])
assert cat['foo'].auto_comments == ['Foo Bar comment 2']
def test_update_fuzzy_matching_with_case_change(self):
@@ -404,21 +404,21 @@ def test_catalog_plural_forms():
def test_catalog_setitem():
cat = catalog.Catalog()
- cat[u'foo'] = catalog.Message(u'foo')
- assert cat[u'foo'].id == 'foo'
+ cat['foo'] = catalog.Message('foo')
+ assert cat['foo'].id == 'foo'
cat = catalog.Catalog()
- cat[u'foo'] = catalog.Message(u'foo', locations=[('main.py', 1)])
- assert cat[u'foo'].locations == [('main.py', 1)]
- cat[u'foo'] = catalog.Message(u'foo', locations=[('utils.py', 5)])
- assert cat[u'foo'].locations == [('main.py', 1), ('utils.py', 5)]
+ cat['foo'] = catalog.Message('foo', locations=[('main.py', 1)])
+ assert cat['foo'].locations == [('main.py', 1)]
+ cat['foo'] = catalog.Message('foo', locations=[('utils.py', 5)])
+ assert cat['foo'].locations == [('main.py', 1), ('utils.py', 5)]
def test_catalog_add():
cat = catalog.Catalog()
- foo = cat.add(u'foo')
+ foo = cat.add('foo')
assert foo.id == 'foo'
- assert cat[u'foo'] is foo
+ assert cat['foo'] is foo
def test_catalog_update():
@@ -427,9 +427,9 @@ def test_catalog_update():
template.add('blue', locations=[('main.py', 100)])
template.add(('salad', 'salads'), locations=[('util.py', 42)])
cat = catalog.Catalog(locale='de_DE')
- cat.add('blue', u'blau', locations=[('main.py', 98)])
- cat.add('head', u'Kopf', locations=[('util.py', 33)])
- cat.add(('salad', 'salads'), (u'Salat', u'Salate'),
+ cat.add('blue', 'blau', locations=[('main.py', 98)])
+ cat.add('head', 'Kopf', locations=[('util.py', 33)])
+ cat.add(('salad', 'salads'), ('Salat', 'Salate'),
locations=[('util.py', 38)])
cat.update(template)
@@ -440,11 +440,11 @@ def test_catalog_update():
assert msg1.locations == [('main.py', 99)]
msg2 = cat['blue']
- assert msg2.string == u'blau'
+ assert msg2.string == 'blau'
assert msg2.locations == [('main.py', 100)]
msg3 = cat['salad']
- assert msg3.string == (u'Salat', u'Salate')
+ assert msg3.string == ('Salat', 'Salate')
assert msg3.locations == [('util.py', 42)]
assert 'head' not in cat
diff --git a/tests/messages/test_extract.py b/tests/messages/test_extract.py
index 3873191..7a0df8e 100644
--- a/tests/messages/test_extract.py
+++ b/tests/messages/test_extract.py
@@ -41,14 +41,14 @@ msg10 = dngettext(getDomain(), 'Page', 'Pages', 3)
assert messages == [
(1, '_', None, []),
(2, 'ungettext', (None, None, None), []),
- (3, 'ungettext', (u'Babel', None, None), []),
- (4, 'ungettext', (None, u'Babels', None), []),
- (5, 'ungettext', (u'bunny', u'bunnies', None), []),
- (6, 'ungettext', (None, u'bunnies', None), []),
+ (3, 'ungettext', ('Babel', None, None), []),
+ (4, 'ungettext', (None, 'Babels', None), []),
+ (5, 'ungettext', ('bunny', 'bunnies', None), []),
+ (6, 'ungettext', (None, 'bunnies', None), []),
(7, '_', None, []),
- (8, 'gettext', u'Rabbit', []),
- (9, 'dgettext', (u'wiki', None), []),
- (10, 'dngettext', (None, u'Page', u'Pages', None), []),
+ (8, 'gettext', 'Rabbit', []),
+ (9, 'dgettext', ('wiki', None), []),
+ (10, 'dngettext', (None, 'Page', 'Pages', None), []),
]
def test_extract_default_encoding_ascii(self):
@@ -60,7 +60,7 @@ msg10 = dngettext(getDomain(), 'Page', 'Pages', 3)
assert messages == [(1, '_', 'a', [])]
def test_extract_default_encoding_utf8(self):
- buf = BytesIO(u'_("☃")'.encode('UTF-8'))
+ buf = BytesIO('_("☃")'.encode('UTF-8'))
messages = list(extract.extract_python(
buf, list(extract.DEFAULT_KEYWORDS), [], {},
))
@@ -351,7 +351,7 @@ msg = _('Bonjour à tous')
assert messages[0][3] == ['NOTE: hello']
def test_utf8_message_with_magic_comment(self):
- buf = BytesIO(u"""# -*- coding: utf-8 -*-
+ buf = BytesIO("""# -*- coding: utf-8 -*-
# NOTE: hello
msg = _('Bonjour à tous')
""".encode('utf-8'))
@@ -360,7 +360,7 @@ msg = _('Bonjour à tous')
assert messages[0][3] == ['NOTE: hello']
def test_utf8_message_with_utf8_bom(self):
- buf = BytesIO(codecs.BOM_UTF8 + u"""
+ buf = BytesIO(codecs.BOM_UTF8 + """
# NOTE: hello
msg = _('Bonjour à tous')
""".encode('utf-8'))
@@ -369,7 +369,7 @@ msg = _('Bonjour à tous')
assert messages[0][3] == ['NOTE: hello']
def test_utf8_message_with_utf8_bom_and_magic_comment(self):
- buf = BytesIO(codecs.BOM_UTF8 + u"""# -*- coding: utf-8 -*-
+ buf = BytesIO(codecs.BOM_UTF8 + """# -*- coding: utf-8 -*-
# NOTE: hello
msg = _('Bonjour à tous')
""".encode('utf-8'))
@@ -378,7 +378,7 @@ msg = _('Bonjour à tous')
assert messages[0][3] == ['NOTE: hello']
def test_utf8_bom_with_latin_magic_comment_fails(self):
- buf = BytesIO(codecs.BOM_UTF8 + u"""# -*- coding: latin-1 -*-
+ buf = BytesIO(codecs.BOM_UTF8 + """# -*- coding: latin-1 -*-
# NOTE: hello
msg = _('Bonjour à tous')
""".encode('utf-8'))
@@ -386,7 +386,7 @@ msg = _('Bonjour à tous')
list(extract.extract_python(buf, ('_',), ['NOTE:'], {}))
def test_utf8_raw_strings_match_unicode_strings(self):
- buf = BytesIO(codecs.BOM_UTF8 + u"""
+ buf = BytesIO(codecs.BOM_UTF8 + """
msg = _('Bonjour à tous')
msgu = _(u'Bonjour à tous')
""".encode('utf-8'))
@@ -527,7 +527,7 @@ nbsp = _('\xa0')
""")
messages = list(extract.extract('python', buf,
extract.DEFAULT_KEYWORDS, [], {}))
- assert messages[0][1] == u'\xa0'
+ assert messages[0][1] == '\xa0'
def test_f_strings(self):
buf = BytesIO(br"""
@@ -542,10 +542,10 @@ t4 = _(f'spameggs {t1}') # should not be extracted
""")
messages = list(extract.extract('python', buf, extract.DEFAULT_KEYWORDS, [], {}))
assert len(messages) == 4
- assert messages[0][1] == u'foobar'
- assert messages[1][1] == u'spameggsfeast'
- assert messages[2][1] == u'spameggskerroshampurilainen'
- assert messages[3][1] == u'whoa! a flying shark... hello'
+ assert messages[0][1] == 'foobar'
+ assert messages[1][1] == 'spameggsfeast'
+ assert messages[2][1] == 'spameggskerroshampurilainen'
+ assert messages[3][1] == 'whoa! a flying shark... hello'
def test_f_strings_non_utf8(self):
buf = BytesIO(b"""
@@ -554,4 +554,4 @@ t2 = _(f'\xe5\xe4\xf6' f'\xc5\xc4\xd6')
""")
messages = list(extract.extract('python', buf, extract.DEFAULT_KEYWORDS, [], {}))
assert len(messages) == 1
- assert messages[0][1] == u'åäöÅÄÖ'
+ assert messages[0][1] == 'åäöÅÄÖ'
diff --git a/tests/messages/test_frontend.py b/tests/messages/test_frontend.py
index e91d02b..e540e71 100644
--- a/tests/messages/test_frontend.py
+++ b/tests/messages/test_frontend.py
@@ -9,26 +9,38 @@
# 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 shlex
-from datetime import datetime
-from freezegun import freeze_time
-from io import StringIO
-from setuptools import Distribution
import logging
import os
+import shlex
import shutil
import sys
import time
import unittest
+from datetime import datetime
+from io import StringIO
import pytest
+from freezegun import freeze_time
+from setuptools import Distribution
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, OptionError, BaseError
-from babel.util import LOCALTZ
+from babel.messages import Catalog, frontend
+from babel.messages.frontend import (
+ BaseError,
+ CommandLineInterface,
+ OptionError,
+ extract_messages,
+ update_catalog,
+)
from babel.messages.pofile import read_po, write_po
+from babel.util import LOCALTZ
+
+TEST_PROJECT_DISTRIBUTION_DATA = {
+ "name": "TestProject",
+ "version": "0.1",
+ "packages": ["project"],
+}
this_dir = os.path.abspath(os.path.dirname(__file__))
data_dir = os.path.join(this_dir, 'data')
@@ -47,11 +59,7 @@ class CompileCatalogTestCase(unittest.TestCase):
self.olddir = os.getcwd()
os.chdir(data_dir)
- self.dist = Distribution(dict(
- name='TestProject',
- version='0.1',
- packages=['project']
- ))
+ self.dist = Distribution(TEST_PROJECT_DISTRIBUTION_DATA)
self.cmd = frontend.compile_catalog(self.dist)
self.cmd.initialize_options()
@@ -77,11 +85,7 @@ class ExtractMessagesTestCase(unittest.TestCase):
self.olddir = os.getcwd()
os.chdir(data_dir)
- self.dist = Distribution(dict(
- name='TestProject',
- version='0.1',
- packages=['project']
- ))
+ self.dist = Distribution(TEST_PROJECT_DISTRIBUTION_DATA)
self.cmd = frontend.extract_messages(self.dist)
self.cmd.initialize_options()
@@ -350,11 +354,7 @@ class InitCatalogTestCase(unittest.TestCase):
self.olddir = os.getcwd()
os.chdir(data_dir)
- self.dist = Distribution(dict(
- name='TestProject',
- version='0.1',
- packages=['project']
- ))
+ self.dist = Distribution(TEST_PROJECT_DISTRIBUTION_DATA)
self.cmd = frontend.init_catalog(self.dist)
self.cmd.initialize_options()
diff --git a/tests/messages/test_js_extract.py b/tests/messages/test_js_extract.py
index 95985c0..82f5379 100644
--- a/tests/messages/test_js_extract.py
+++ b/tests/messages/test_js_extract.py
@@ -1,5 +1,7 @@
from io import BytesIO
+
import pytest
+
from babel.messages import extract
@@ -35,32 +37,32 @@ msg10 = dngettext(domain, 'Page', 'Pages', 3)
list(extract.extract('javascript', buf, extract.DEFAULT_KEYWORDS, [],
{}))
assert messages == [
- (5, (u'bunny', u'bunnies'), [], None),
- (8, u'Rabbit', [], None),
- (10, (u'Page', u'Pages'), [], None)
+ (5, ('bunny', 'bunnies'), [], None),
+ (8, 'Rabbit', [], None),
+ (10, ('Page', 'Pages'), [], None)
]
def test_message_with_line_comment():
- buf = BytesIO(u"""\
+ buf = BytesIO("""\
// NOTE: hello
msg = _('Bonjour à tous')
""".encode('utf-8'))
messages = list(extract.extract_javascript(buf, ('_',), ['NOTE:'], {}))
- assert messages[0][2] == u'Bonjour à tous'
- assert messages[0][3] == [u'NOTE: hello']
+ assert messages[0][2] == 'Bonjour à tous'
+ assert messages[0][3] == ['NOTE: hello']
def test_message_with_multiline_comment():
- buf = BytesIO(u"""\
+ buf = BytesIO("""\
/* NOTE: hello
and bonjour
and servus */
msg = _('Bonjour à tous')
""".encode('utf-8'))
messages = list(extract.extract_javascript(buf, ('_',), ['NOTE:'], {}))
- assert messages[0][2] == u'Bonjour à tous'
- assert messages[0][3] == [u'NOTE: hello', 'and bonjour', ' and servus']
+ assert messages[0][2] == 'Bonjour à tous'
+ assert messages[0][3] == ['NOTE: hello', 'and bonjour', ' and servus']
def test_ignore_function_definitions():
@@ -91,11 +93,11 @@ bar()
_('no comment here')
""")
messages = list(extract.extract_javascript(buf, ('_',), ['NOTE:'], {}))
- assert messages[0][2] == u'Something'
- assert messages[0][3] == [u'NOTE: this will']
- assert messages[1][2] == u'Something else'
- assert messages[1][3] == [u'NOTE: this will show up', 'too.']
- assert messages[2][2] == u'no comment here'
+ assert messages[0][2] == 'Something'
+ assert messages[0][3] == ['NOTE: this will']
+ assert messages[1][2] == 'Something else'
+ assert messages[1][3] == ['NOTE: this will show up', 'too.']
+ assert messages[2][2] == 'no comment here'
assert messages[2][3] == []
diff --git a/tests/messages/test_jslexer.py b/tests/messages/test_jslexer.py
index bd6322e..3889f0b 100644
--- a/tests/messages/test_jslexer.py
+++ b/tests/messages/test_jslexer.py
@@ -3,9 +3,9 @@ from babel.messages import jslexer
def test_unquote():
assert jslexer.unquote_string('""') == ''
- assert jslexer.unquote_string(r'"h\u00ebllo"') == u"hëllo"
- assert jslexer.unquote_string(r'"h\xebllo"') == u"hëllo"
- assert jslexer.unquote_string(r'"\xebb"') == u"ëb"
+ assert jslexer.unquote_string(r'"h\u00ebllo"') == "hëllo"
+ assert jslexer.unquote_string(r'"h\xebllo"') == "hëllo"
+ assert jslexer.unquote_string(r'"\xebb"') == "ëb"
def test_dollar_in_identifier():
diff --git a/tests/messages/test_mofile.py b/tests/messages/test_mofile.py
index 6e026a8..6a702ed 100644
--- a/tests/messages/test_mofile.py
+++ b/tests/messages/test_mofile.py
@@ -14,7 +14,7 @@ import os
import unittest
from io import BytesIO
-from babel.messages import mofile, Catalog
+from babel.messages import Catalog, mofile
from babel.support import Translations
@@ -42,12 +42,12 @@ class WriteMoTestCase(unittest.TestCase):
# can be applied to all subsequent messages by GNUTranslations
# (ensuring all messages are safely converted to unicode)
catalog = Catalog(locale='en_US')
- catalog.add(u'', '''\
+ catalog.add('', '''\
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n''')
- catalog.add(u'foo', 'Voh')
- catalog.add((u'There is', u'There are'), (u'Es gibt', u'Es gibt'))
- catalog.add(u'Fizz', '')
+ catalog.add('foo', 'Voh')
+ catalog.add(('There is', 'There are'), ('Es gibt', 'Es gibt'))
+ catalog.add('Fizz', '')
catalog.add(('Fuzz', 'Fuzzes'), ('', ''))
buf = BytesIO()
mofile.write_mo(buf, catalog)
@@ -67,18 +67,18 @@ class WriteMoTestCase(unittest.TestCase):
def test_empty_translation_with_fallback(self):
catalog1 = Catalog(locale='fr_FR')
- catalog1.add(u'', '''\
+ catalog1.add('', '''\
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n''')
- catalog1.add(u'Fuzz', '')
+ catalog1.add('Fuzz', '')
buf1 = BytesIO()
mofile.write_mo(buf1, catalog1)
buf1.seek(0)
catalog2 = Catalog(locale='fr')
- catalog2.add(u'', '''\
+ catalog2.add('', '''\
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n''')
- catalog2.add(u'Fuzz', 'Flou')
+ catalog2.add('Fuzz', 'Flou')
buf2 = BytesIO()
mofile.write_mo(buf2, catalog2)
buf2.seek(0)
diff --git a/tests/messages/test_pofile.py b/tests/messages/test_pofile.py
index a72368b..f668ea0 100644
--- a/tests/messages/test_pofile.py
+++ b/tests/messages/test_pofile.py
@@ -10,16 +10,18 @@
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://babel.edgewall.org/log/.
-from datetime import datetime
import unittest
+from datetime import datetime
from io import BytesIO, StringIO
+
import pytest
from babel.core import Locale
-from babel.messages.catalog import Catalog, Message
from babel.messages import pofile
+from babel.messages.catalog import Catalog, Message
from babel.util import FixedOffsetTimezone
+
class ReadPoTestCase(unittest.TestCase):
def test_preserve_locale(self):
@@ -49,7 +51,7 @@ msgstr "Voh"''')
assert catalog.domain == 'mydomain'
def test_applies_specified_encoding_during_read(self):
- buf = BytesIO(u'''
+ buf = BytesIO('''
msgid ""
msgstr ""
"Project-Id-Version: 3.15\\n"
@@ -204,7 +206,7 @@ msgstr "Bahr"
''')
catalog = pofile.read_po(buf)
assert len(catalog.obsolete) == 1
- message = catalog.obsolete[u'foofoo']
+ message = catalog.obsolete['foofoo']
assert message.id == 'foofoo'
assert message.string == 'VohVooooh'
assert message.user_comments == ['This is an obsolete message']
@@ -225,7 +227,7 @@ msgstr "Bahr"
''')
catalog = pofile.read_po(buf)
assert len(catalog) == 1
- message = catalog[u'bar']
+ message = catalog['bar']
assert message.id == 'bar'
assert message.string == 'Bahr'
assert message.user_comments == ['This message is not obsolete']
@@ -247,7 +249,7 @@ msgstr "Bahr"
''')
catalog = pofile.read_po(buf)
assert len(catalog) == 1
- message = catalog[u'bar']
+ message = catalog['bar']
assert message.id == 'bar'
assert message.string == 'Bahr'
assert message.user_comments == ['This message is not obsolete']
@@ -296,7 +298,7 @@ msgstr "Bahr"
catalog = pofile.read_po(buf)
assert len(catalog) == 2
assert len(catalog.obsolete) == 1
- message = catalog.obsolete[u"foo"]
+ message = catalog.obsolete["foo"]
assert message.context == 'other'
assert message.string == 'Voh'
@@ -484,7 +486,7 @@ msgstr[2] "Vohs [text]"
def test_invalid_pofile_with_abort_flag(self):
parser = pofile.PoFileParser(None, abort_invalid=True)
lineno = 10
- line = u'Algo esta mal'
+ line = 'Algo esta mal'
msg = 'invalid file'
with pytest.raises(pofile.PoFileError):
parser._invalid_pofile(line, lineno, msg)
@@ -494,8 +496,8 @@ class WritePoTestCase(unittest.TestCase):
def test_join_locations(self):
catalog = Catalog()
- catalog.add(u'foo', locations=[('main.py', 1)])
- catalog.add(u'foo', locations=[('utils.py', 3)])
+ catalog.add('foo', locations=[('main.py', 1)])
+ catalog.add('foo', locations=[('utils.py', 3)])
buf = BytesIO()
pofile.write_po(buf, catalog, omit_header=True)
assert buf.getvalue().strip() == b'''#: main.py:1 utils.py:3
@@ -504,17 +506,17 @@ msgstr ""'''
def test_write_po_file_with_specified_charset(self):
catalog = Catalog(charset='iso-8859-1')
- catalog.add('foo', u'äöü', locations=[('main.py', 1)])
+ catalog.add('foo', 'äöü', locations=[('main.py', 1)])
buf = BytesIO()
pofile.write_po(buf, catalog, omit_header=False)
po_file = buf.getvalue().strip()
assert b'"Content-Type: text/plain; charset=iso-8859-1\\n"' in po_file
- assert u'msgstr "äöü"'.encode('iso-8859-1') in po_file
+ assert 'msgstr "äöü"'.encode('iso-8859-1') in po_file
def test_duplicate_comments(self):
catalog = Catalog()
- catalog.add(u'foo', auto_comments=['A comment'])
- catalog.add(u'foo', auto_comments=['A comment'])
+ catalog.add('foo', auto_comments=['A comment'])
+ catalog.add('foo', auto_comments=['A comment'])
buf = BytesIO()
pofile.write_po(buf, catalog, omit_header=True)
assert buf.getvalue().strip() == b'''#. A comment
@@ -577,10 +579,10 @@ msgstr ""'''
def test_wrap_locations_with_hyphens(self):
catalog = Catalog()
- catalog.add(u'foo', locations=[
+ catalog.add('foo', locations=[
('doupy/templates/base/navmenu.inc.html.py', 60)
])
- catalog.add(u'foo', locations=[
+ catalog.add('foo', locations=[
('doupy/templates/job-offers/helpers.html', 22)
])
buf = BytesIO()
@@ -623,9 +625,9 @@ msgstr ""
def test_pot_with_translator_comments(self):
catalog = Catalog()
- catalog.add(u'foo', locations=[('main.py', 1)],
+ catalog.add('foo', locations=[('main.py', 1)],
auto_comments=['Comment About `foo`'])
- catalog.add(u'bar', locations=[('utils.py', 3)],
+ catalog.add('bar', locations=[('utils.py', 3)],
user_comments=['Comment About `bar` with',
'multiple lines.'])
buf = BytesIO()
@@ -643,8 +645,8 @@ msgstr ""'''
def test_po_with_obsolete_message(self):
catalog = Catalog()
- catalog.add(u'foo', u'Voh', locations=[('main.py', 1)])
- catalog.obsolete['bar'] = Message(u'bar', u'Bahr',
+ catalog.add('foo', 'Voh', locations=[('main.py', 1)])
+ catalog.obsolete['bar'] = Message('bar', 'Bahr',
locations=[('utils.py', 3)],
user_comments=['User comment'])
buf = BytesIO()
@@ -659,7 +661,7 @@ msgstr "Voh"
def test_po_with_multiline_obsolete_message(self):
catalog = Catalog()
- catalog.add(u'foo', u'Voh', locations=[('main.py', 1)])
+ catalog.add('foo', 'Voh', locations=[('main.py', 1)])
msgid = r"""Here's a message that covers
multiple lines, and should still be handled
correctly.
@@ -687,8 +689,8 @@ msgstr "Voh"
def test_po_with_obsolete_message_ignored(self):
catalog = Catalog()
- catalog.add(u'foo', u'Voh', locations=[('main.py', 1)])
- catalog.obsolete['bar'] = Message(u'bar', u'Bahr',
+ catalog.add('foo', 'Voh', locations=[('main.py', 1)])
+ catalog.obsolete['bar'] = Message('bar', 'Bahr',
locations=[('utils.py', 3)],
user_comments=['User comment'])
buf = BytesIO()
@@ -699,8 +701,8 @@ msgstr "Voh"'''
def test_po_with_previous_msgid(self):
catalog = Catalog()
- catalog.add(u'foo', u'Voh', locations=[('main.py', 1)],
- previous_id=u'fo')
+ catalog.add('foo', 'Voh', locations=[('main.py', 1)],
+ previous_id='fo')
buf = BytesIO()
pofile.write_po(buf, catalog, omit_header=True, include_previous=True)
assert buf.getvalue().strip() == b'''#: main.py:1
@@ -710,8 +712,8 @@ msgstr "Voh"'''
def test_po_with_previous_msgid_plural(self):
catalog = Catalog()
- catalog.add((u'foo', u'foos'), (u'Voh', u'Voeh'),
- locations=[('main.py', 1)], previous_id=(u'fo', u'fos'))
+ catalog.add(('foo', 'foos'), ('Voh', 'Voeh'),
+ locations=[('main.py', 1)], previous_id=('fo', 'fos'))
buf = BytesIO()
pofile.write_po(buf, catalog, omit_header=True, include_previous=True)
assert buf.getvalue().strip() == b'''#: main.py:1
@@ -724,10 +726,10 @@ msgstr[1] "Voeh"'''
def test_sorted_po(self):
catalog = Catalog()
- catalog.add(u'bar', locations=[('utils.py', 3)],
+ catalog.add('bar', locations=[('utils.py', 3)],
user_comments=['Comment About `bar` with',
'multiple lines.'])
- catalog.add((u'foo', u'foos'), (u'Voh', u'Voeh'),
+ catalog.add(('foo', 'foos'), ('Voh', 'Voeh'),
locations=[('main.py', 1)])
buf = BytesIO()
pofile.write_po(buf, catalog, sort_output=True)
@@ -748,12 +750,12 @@ msgstr[1] "Voeh"''' in value
def test_sorted_po_context(self):
catalog = Catalog()
- catalog.add((u'foo', u'foos'), (u'Voh', u'Voeh'),
+ catalog.add(('foo', 'foos'), ('Voh', 'Voeh'),
locations=[('main.py', 1)],
context='there')
- catalog.add((u'foo', u'foos'), (u'Voh', u'Voeh'),
+ catalog.add(('foo', 'foos'), ('Voh', 'Voeh'),
locations=[('main.py', 1)])
- catalog.add((u'foo', u'foos'), (u'Voh', u'Voeh'),
+ catalog.add(('foo', 'foos'), ('Voh', 'Voeh'),
locations=[('main.py', 1)],
context='here')
buf = BytesIO()
@@ -783,8 +785,8 @@ msgstr[1] "Voeh"''' in value
def test_file_sorted_po(self):
catalog = Catalog()
- catalog.add(u'bar', locations=[('utils.py', 3)])
- catalog.add((u'foo', u'foos'), (u'Voh', u'Voeh'), locations=[('main.py', 1)])
+ catalog.add('bar', locations=[('utils.py', 3)])
+ catalog.add(('foo', 'foos'), ('Voh', 'Voeh'), locations=[('main.py', 1)])
buf = BytesIO()
pofile.write_po(buf, catalog, sort_by_file=True)
value = buf.getvalue().strip()
@@ -792,7 +794,7 @@ msgstr[1] "Voeh"''' in value
def test_file_with_no_lineno(self):
catalog = Catalog()
- catalog.add(u'bar', locations=[('utils.py', None)],
+ catalog.add('bar', locations=[('utils.py', None)],
user_comments=['Comment About `bar` with',
'multiple lines.'])
buf = BytesIO()
@@ -820,8 +822,8 @@ msgstr ""''')
def test_include_lineno(self):
catalog = Catalog()
- catalog.add(u'foo', locations=[('main.py', 1)])
- catalog.add(u'foo', locations=[('utils.py', 3)])
+ catalog.add('foo', locations=[('main.py', 1)])
+ catalog.add('foo', locations=[('utils.py', 3)])
buf = BytesIO()
pofile.write_po(buf, catalog, omit_header=True, include_lineno=True)
assert buf.getvalue().strip() == b'''#: main.py:1 utils.py:3
@@ -830,9 +832,9 @@ msgstr ""'''
def test_no_include_lineno(self):
catalog = Catalog()
- catalog.add(u'foo', locations=[('main.py', 1)])
- catalog.add(u'foo', locations=[('main.py', 2)])
- catalog.add(u'foo', locations=[('utils.py', 3)])
+ catalog.add('foo', locations=[('main.py', 1)])
+ catalog.add('foo', locations=[('main.py', 2)])
+ catalog.add('foo', locations=[('utils.py', 3)])
buf = BytesIO()
pofile.write_po(buf, catalog, omit_header=True, include_lineno=False)
assert buf.getvalue().strip() == b'''#: main.py utils.py
@@ -843,8 +845,8 @@ msgstr ""'''
class PofileFunctionsTestCase(unittest.TestCase):
def test_unescape(self):
- escaped = u'"Say:\\n \\"hello, world!\\"\\n"'
- unescaped = u'Say:\n "hello, world!"\n'
+ escaped = '"Say:\\n \\"hello, world!\\"\\n"'
+ unescaped = 'Say:\n "hello, world!"\n'
assert unescaped != escaped
assert unescaped == pofile.unescape(escaped)
@@ -856,7 +858,7 @@ class PofileFunctionsTestCase(unittest.TestCase):
# handle irregular multi-line msgstr (no "" as first line)
# gracefully (#171)
msgstr = '"multi-line\\n"\n" translation"'
- expected_denormalized = u'multi-line\n translation'
+ expected_denormalized = 'multi-line\n translation'
assert expected_denormalized == pofile.denormalize(msgstr)
assert expected_denormalized == pofile.denormalize(f'""\n{msgstr}')
diff --git a/tests/test_core.py b/tests/test_core.py
index 605bf5c..d315018 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -13,20 +13,19 @@
import pytest
from babel import core
-from babel.core import default_locale, Locale
+from babel.core import Locale, default_locale
def test_locale_provides_access_to_cldr_locale_data():
locale = Locale('en', 'US')
- assert u'English (United States)' == locale.display_name
- assert u'.' == locale.number_symbols['decimal']
+ assert locale.display_name == 'English (United States)'
+ assert locale.number_symbols['decimal'] == '.'
def test_locale_repr():
assert repr(Locale('en', 'US')) == "Locale('en', territory='US')"
- assert ("Locale('de', territory='DE')" == repr(Locale('de', 'DE')))
- assert ("Locale('zh', territory='CN', script='Hans')" ==
- repr(Locale('zh', 'CN', script='Hans')))
+ assert (repr(Locale('de', 'DE')) == "Locale('de', territory='DE')")
+ assert (repr(Locale('zh', 'CN', script='Hans')) == "Locale('zh', territory='CN', script='Hans')")
def test_locale_comparison():
@@ -97,36 +96,36 @@ class TestLocaleClass:
assert (de_DE.language, de_DE.territory) == ('de', 'DE')
def test_parse(self):
- l = Locale.parse('de-DE', sep='-')
- assert l.display_name == 'Deutsch (Deutschland)'
+ locale = Locale.parse('de-DE', sep='-')
+ assert locale.display_name == 'Deutsch (Deutschland)'
- de_DE = Locale.parse(l)
+ de_DE = Locale.parse(locale)
assert (de_DE.language, de_DE.territory) == ('de', 'DE')
def test_parse_likely_subtags(self):
- l = Locale.parse('zh-TW', sep='-')
- assert l.language == 'zh'
- assert l.territory == 'TW'
- assert l.script == 'Hant'
-
- l = Locale.parse('zh_CN')
- assert l.language == 'zh'
- assert l.territory == 'CN'
- assert l.script == 'Hans'
-
- l = Locale.parse('zh_SG')
- assert l.language == 'zh'
- assert l.territory == 'SG'
- assert l.script == 'Hans'
-
- l = Locale.parse('und_AT')
- assert l.language == 'de'
- assert l.territory == 'AT'
-
- l = Locale.parse('und_UK')
- assert l.language == 'en'
- assert l.territory == 'GB'
- assert l.script is None
+ locale = Locale.parse('zh-TW', sep='-')
+ assert locale.language == 'zh'
+ assert locale.territory == 'TW'
+ assert locale.script == 'Hant'
+
+ locale = Locale.parse('zh_CN')
+ assert locale.language == 'zh'
+ assert locale.territory == 'CN'
+ assert locale.script == 'Hans'
+
+ locale = Locale.parse('zh_SG')
+ assert locale.language == 'zh'
+ assert locale.territory == 'SG'
+ assert locale.script == 'Hans'
+
+ locale = Locale.parse('und_AT')
+ assert locale.language == 'de'
+ assert locale.territory == 'AT'
+
+ locale = Locale.parse('und_UK')
+ assert locale.language == 'en'
+ assert locale.territory == 'GB'
+ assert locale.script is None
def test_get_display_name(self):
zh_CN = Locale('zh', 'CN', script='Hans')
@@ -170,9 +169,9 @@ class TestLocaleClass:
def test_currency_formats_property(self):
assert (Locale('en', 'US').currency_formats['standard'].pattern ==
- u'\xa4#,##0.00')
+ '\xa4#,##0.00')
assert (Locale('en', 'US').currency_formats['accounting'].pattern ==
- u'\xa4#,##0.00;(\xa4#,##0.00)')
+ '\xa4#,##0.00;(\xa4#,##0.00)')
def test_percent_formats_property(self):
assert Locale('en', 'US').percent_formats[None].pattern == '#,##0%'
@@ -200,7 +199,7 @@ class TestLocaleClass:
time_zones = Locale('en', 'US').time_zones
assert (time_zones['Europe/London']['long']['daylight'] ==
'British Summer Time')
- assert time_zones['America/St_Johns']['city'] == u'St. John\u2019s'
+ assert time_zones['America/St_Johns']['city'] == 'St. John\u2019s'
def test_meta_zones_property(self):
meta_zones = Locale('en', 'US').meta_zones
@@ -209,7 +208,7 @@ class TestLocaleClass:
def test_zone_formats_property(self):
assert Locale('en', 'US').zone_formats['fallback'] == '%(1)s (%(0)s)'
- assert Locale('pt', 'BR').zone_formats['region'] == u'Hor\xe1rio %s'
+ assert Locale('pt', 'BR').zone_formats['region'] == 'Hor\xe1rio %s'
def test_first_week_day_property(self):
assert Locale('de', 'DE').first_week_day == 0
@@ -233,12 +232,12 @@ class TestLocaleClass:
assert Locale('fr', 'FR').time_formats['long'].pattern == 'HH:mm:ss z'
def test_datetime_formats_property(self):
- assert Locale('en').datetime_formats['full'] == u"{1} 'at' {0}"
- assert Locale('th').datetime_formats['medium'] == u'{1} {0}'
+ assert Locale('en').datetime_formats['full'] == "{1} 'at' {0}"
+ assert Locale('th').datetime_formats['medium'] == '{1} {0}'
def test_datetime_skeleton_property(self):
- assert Locale('en').datetime_skeletons['Md'].pattern == u"M/d"
- assert Locale('th').datetime_skeletons['Md'].pattern == u'd/M'
+ assert Locale('en').datetime_skeletons['Md'].pattern == "M/d"
+ assert Locale('th').datetime_skeletons['Md'].pattern == 'd/M'
def test_plural_form_property(self):
assert Locale('en').plural_form(1) == 'one'
@@ -322,7 +321,7 @@ def test_issue_601_no_language_name_but_has_variant():
# Instead, it's better to return None altogether, as we can't reliably format
# part of a language name.
- assert Locale.parse('fi_FI').get_display_name('kw_GB') == None
+ assert Locale.parse('fi_FI').get_display_name('kw_GB') is None
def test_issue_814():
diff --git a/tests/test_date_intervals.py b/tests/test_date_intervals.py
index 8e84a9e..5565854 100644
--- a/tests/test_date_intervals.py
+++ b/tests/test_date_intervals.py
@@ -46,8 +46,8 @@ def test_format_interval_12_hour():
def test_format_interval_invalid_skeleton():
t1 = TEST_DATE
t2 = TEST_DATE + datetime.timedelta(days=1)
- assert dates.format_interval(t1, t2, "mumumu", fuzzy=False, locale="fi") == u"8.1.2016\u20139.1.2016"
- assert dates.format_interval(t1, t2, fuzzy=False, locale="fi") == u"8.1.2016\u20139.1.2016"
+ assert dates.format_interval(t1, t2, "mumumu", fuzzy=False, locale="fi") == "8.1.2016\u20139.1.2016"
+ assert dates.format_interval(t1, t2, fuzzy=False, locale="fi") == "8.1.2016\u20139.1.2016"
def test_issue_825():
diff --git a/tests/test_dates.py b/tests/test_dates.py
index a4fb9c5..0c8bd17 100644
--- a/tests/test_dates.py
+++ b/tests/test_dates.py
@@ -16,7 +16,7 @@ from datetime import date, datetime, time, timedelta
import freezegun
import pytest
-from babel import dates, Locale
+from babel import Locale, dates
from babel.dates import NO_INHERITANCE_MARKER, _localize
from babel.util import FixedOffsetTimezone
@@ -68,7 +68,7 @@ class DateTimeFormatTestCase:
assert dates.DateTimeFormat(d, locale='en_US')['w'] == '53'
def test_week_of_year_de_first_us_last_with_year(self):
- d = date(2018,12,31)
+ d = date(2018, 12, 31)
fmt = dates.DateTimeFormat(d, locale='de_DE')
assert fmt['w'] == '1'
assert fmt['YYYY'] == '2019'
@@ -213,20 +213,20 @@ class DateTimeFormatTestCase:
def test_timezone_walltime_long(self, timezone_getter):
tz = timezone_getter('Europe/Paris')
t = time(15, 30, tzinfo=tz)
- assert dates.DateTimeFormat(t, locale='fr_FR')['vvvv'] == u'heure d’Europe centrale'
+ assert dates.DateTimeFormat(t, locale='fr_FR')['vvvv'] == 'heure d’Europe centrale'
def test_hour_formatting(self):
- l = 'en_US'
+ locale = 'en_US'
t = time(0, 0, 0)
- assert dates.format_time(t, 'h a', locale=l) == '12 AM'
- assert dates.format_time(t, 'H', locale=l) == '0'
- assert dates.format_time(t, 'k', locale=l) == '24'
- assert dates.format_time(t, 'K a', locale=l) == '0 AM'
+ assert dates.format_time(t, 'h a', locale=locale) == '12 AM'
+ assert dates.format_time(t, 'H', locale=locale) == '0'
+ assert dates.format_time(t, 'k', locale=locale) == '24'
+ assert dates.format_time(t, 'K a', locale=locale) == '0 AM'
t = time(12, 0, 0)
- assert dates.format_time(t, 'h a', locale=l) == '12 PM'
- assert dates.format_time(t, 'H', locale=l) == '12'
- assert dates.format_time(t, 'k', locale=l) == '12'
- assert dates.format_time(t, 'K a', locale=l) == '0 PM'
+ assert dates.format_time(t, 'h a', locale=locale) == '12 PM'
+ assert dates.format_time(t, 'H', locale=locale) == '12'
+ assert dates.format_time(t, 'k', locale=locale) == '12'
+ assert dates.format_time(t, 'K a', locale=locale) == '0 PM'
class FormatDateTestCase:
@@ -252,75 +252,75 @@ class FormatDatetimeTestCase:
d = datetime(2012, 4, 1, 15, 30, 29, tzinfo=UTC)
epoch = float(calendar.timegm(d.timetuple()))
formatted_string = dates.format_datetime(epoch, format='long', locale='en_US')
- assert formatted_string == u'April 1, 2012 at 3:30:29 PM UTC'
+ assert formatted_string == 'April 1, 2012 at 3:30:29 PM UTC'
def test_timezone_formats_los_angeles(self, timezone_getter):
tz = timezone_getter('America/Los_Angeles')
dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35))
- assert dates.format_datetime(dt, 'z', locale='en') == u'PST'
- assert dates.format_datetime(dt, 'zz', locale='en') == u'PST'
- assert dates.format_datetime(dt, 'zzz', locale='en') == u'PST'
- assert dates.format_datetime(dt, 'zzzz', locale='en') == u'Pacific Standard Time'
- assert dates.format_datetime(dt, 'Z', locale='en') == u'-0800'
- assert dates.format_datetime(dt, 'ZZ', locale='en') == u'-0800'
- assert dates.format_datetime(dt, 'ZZZ', locale='en') == u'-0800'
- assert dates.format_datetime(dt, 'ZZZZ', locale='en') == u'GMT-08:00'
- assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == u'-08:00'
- assert dates.format_datetime(dt, 'OOOO', locale='en') == u'GMT-08:00'
- assert dates.format_datetime(dt, 'VV', locale='en') == u'America/Los_Angeles'
- assert dates.format_datetime(dt, 'VVV', locale='en') == u'Los Angeles'
- assert dates.format_datetime(dt, 'X', locale='en') == u'-08'
- assert dates.format_datetime(dt, 'XX', locale='en') == u'-0800'
- assert dates.format_datetime(dt, 'XXX', locale='en') == u'-08:00'
- assert dates.format_datetime(dt, 'XXXX', locale='en') == u'-0800'
- assert dates.format_datetime(dt, 'XXXXX', locale='en') == u'-08:00'
- assert dates.format_datetime(dt, 'x', locale='en') == u'-08'
- assert dates.format_datetime(dt, 'xx', locale='en') == u'-0800'
- assert dates.format_datetime(dt, 'xxx', locale='en') == u'-08:00'
- assert dates.format_datetime(dt, 'xxxx', locale='en') == u'-0800'
- assert dates.format_datetime(dt, 'xxxxx', locale='en') == u'-08:00'
+ assert dates.format_datetime(dt, 'z', locale='en') == 'PST'
+ assert dates.format_datetime(dt, 'zz', locale='en') == 'PST'
+ assert dates.format_datetime(dt, 'zzz', locale='en') == 'PST'
+ assert dates.format_datetime(dt, 'zzzz', locale='en') == 'Pacific Standard Time'
+ assert dates.format_datetime(dt, 'Z', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'ZZ', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'ZZZ', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT-08:00'
+ assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == '-08:00'
+ assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT-08:00'
+ assert dates.format_datetime(dt, 'VV', locale='en') == 'America/Los_Angeles'
+ assert dates.format_datetime(dt, 'VVV', locale='en') == 'Los Angeles'
+ assert dates.format_datetime(dt, 'X', locale='en') == '-08'
+ assert dates.format_datetime(dt, 'XX', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'XXX', locale='en') == '-08:00'
+ assert dates.format_datetime(dt, 'XXXX', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'XXXXX', locale='en') == '-08:00'
+ assert dates.format_datetime(dt, 'x', locale='en') == '-08'
+ assert dates.format_datetime(dt, 'xx', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'xxx', locale='en') == '-08:00'
+ assert dates.format_datetime(dt, 'xxxx', locale='en') == '-0800'
+ assert dates.format_datetime(dt, 'xxxxx', locale='en') == '-08:00'
def test_timezone_formats_utc(self, timezone_getter):
tz = timezone_getter('UTC')
dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35))
- assert dates.format_datetime(dt, 'Z', locale='en') == u'+0000'
- assert dates.format_datetime(dt, 'ZZ', locale='en') == u'+0000'
- assert dates.format_datetime(dt, 'ZZZ', locale='en') == u'+0000'
- assert dates.format_datetime(dt, 'ZZZZ', locale='en') == u'GMT+00:00'
- assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == u'Z'
- assert dates.format_datetime(dt, 'OOOO', locale='en') == u'GMT+00:00'
- assert dates.format_datetime(dt, 'VV', locale='en') == u'Etc/UTC'
- assert dates.format_datetime(dt, 'VVV', locale='en') == u'UTC'
- assert dates.format_datetime(dt, 'X', locale='en') == u'Z'
- assert dates.format_datetime(dt, 'XX', locale='en') == u'Z'
- assert dates.format_datetime(dt, 'XXX', locale='en') == u'Z'
- assert dates.format_datetime(dt, 'XXXX', locale='en') == u'Z'
- assert dates.format_datetime(dt, 'XXXXX', locale='en') == u'Z'
- assert dates.format_datetime(dt, 'x', locale='en') == u'+00'
- assert dates.format_datetime(dt, 'xx', locale='en') == u'+0000'
- assert dates.format_datetime(dt, 'xxx', locale='en') == u'+00:00'
- assert dates.format_datetime(dt, 'xxxx', locale='en') == u'+0000'
- assert dates.format_datetime(dt, 'xxxxx', locale='en') == u'+00:00'
+ assert dates.format_datetime(dt, 'Z', locale='en') == '+0000'
+ assert dates.format_datetime(dt, 'ZZ', locale='en') == '+0000'
+ assert dates.format_datetime(dt, 'ZZZ', locale='en') == '+0000'
+ assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT+00:00'
+ assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT+00:00'
+ assert dates.format_datetime(dt, 'VV', locale='en') == 'Etc/UTC'
+ assert dates.format_datetime(dt, 'VVV', locale='en') == 'UTC'
+ assert dates.format_datetime(dt, 'X', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'XX', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'XXX', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'XXXX', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'XXXXX', locale='en') == 'Z'
+ assert dates.format_datetime(dt, 'x', locale='en') == '+00'
+ assert dates.format_datetime(dt, 'xx', locale='en') == '+0000'
+ assert dates.format_datetime(dt, 'xxx', locale='en') == '+00:00'
+ assert dates.format_datetime(dt, 'xxxx', locale='en') == '+0000'
+ assert dates.format_datetime(dt, 'xxxxx', locale='en') == '+00:00'
def test_timezone_formats_kolkata(self, timezone_getter):
tz = timezone_getter('Asia/Kolkata')
dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35))
- assert dates.format_datetime(dt, 'zzzz', locale='en') == u'India Standard Time'
- assert dates.format_datetime(dt, 'ZZZZ', locale='en') == u'GMT+05:30'
- assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == u'+05:30'
- assert dates.format_datetime(dt, 'OOOO', locale='en') == u'GMT+05:30'
- assert dates.format_datetime(dt, 'VV', locale='en') == u'Asia/Calcutta'
- assert dates.format_datetime(dt, 'VVV', locale='en') == u'Kolkata'
- assert dates.format_datetime(dt, 'X', locale='en') == u'+0530'
- assert dates.format_datetime(dt, 'XX', locale='en') == u'+0530'
- assert dates.format_datetime(dt, 'XXX', locale='en') == u'+05:30'
- assert dates.format_datetime(dt, 'XXXX', locale='en') == u'+0530'
- assert dates.format_datetime(dt, 'XXXXX', locale='en') == u'+05:30'
- assert dates.format_datetime(dt, 'x', locale='en') == u'+0530'
- assert dates.format_datetime(dt, 'xx', locale='en') == u'+0530'
- assert dates.format_datetime(dt, 'xxx', locale='en') == u'+05:30'
- assert dates.format_datetime(dt, 'xxxx', locale='en') == u'+0530'
- assert dates.format_datetime(dt, 'xxxxx', locale='en') == u'+05:30'
+ assert dates.format_datetime(dt, 'zzzz', locale='en') == 'India Standard Time'
+ assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT+05:30'
+ assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == '+05:30'
+ assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT+05:30'
+ assert dates.format_datetime(dt, 'VV', locale='en') == 'Asia/Calcutta'
+ assert dates.format_datetime(dt, 'VVV', locale='en') == 'Kolkata'
+ assert dates.format_datetime(dt, 'X', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'XX', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'XXX', locale='en') == '+05:30'
+ assert dates.format_datetime(dt, 'XXXX', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'XXXXX', locale='en') == '+05:30'
+ assert dates.format_datetime(dt, 'x', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'xx', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'xxx', locale='en') == '+05:30'
+ assert dates.format_datetime(dt, 'xxxx', locale='en') == '+0530'
+ assert dates.format_datetime(dt, 'xxxxx', locale='en') == '+05:30'
class FormatTimeTestCase:
@@ -337,7 +337,7 @@ class FormatTimeTestCase:
tz = timezone_getter('UTC')
d = _localize(tz, datetime(2012, 4, 1, 15, 30, 29))
epoch = float(calendar.timegm(d.timetuple()))
- assert dates.format_time(epoch, format='long', locale='en_US') == u'3:30:29 PM UTC'
+ assert dates.format_time(epoch, format='long', locale='en_US') == '3:30:29 PM UTC'
def test_with_date_fields_in_pattern(self):
with pytest.raises(AttributeError):
@@ -398,122 +398,122 @@ class TimeZoneAdjustTestCase:
def test_get_period_names():
- assert dates.get_period_names(locale='en_US')['am'] == u'AM'
+ assert dates.get_period_names(locale='en_US')['am'] == 'AM'
def test_get_day_names():
- assert dates.get_day_names('wide', locale='en_US')[1] == u'Tuesday'
- assert dates.get_day_names('short', locale='en_US')[1] == u'Tu'
- assert dates.get_day_names('abbreviated', locale='es')[1] == u'mar'
+ assert dates.get_day_names('wide', locale='en_US')[1] == 'Tuesday'
+ assert dates.get_day_names('short', locale='en_US')[1] == 'Tu'
+ assert dates.get_day_names('abbreviated', locale='es')[1] == 'mar'
de = dates.get_day_names('narrow', context='stand-alone', locale='de_DE')
- assert de[1] == u'D'
+ assert de[1] == 'D'
def test_get_month_names():
- assert dates.get_month_names('wide', locale='en_US')[1] == u'January'
- assert dates.get_month_names('abbreviated', locale='es')[1] == u'ene'
+ assert dates.get_month_names('wide', locale='en_US')[1] == 'January'
+ assert dates.get_month_names('abbreviated', locale='es')[1] == 'ene'
de = dates.get_month_names('narrow', context='stand-alone', locale='de_DE')
- assert de[1] == u'J'
+ assert de[1] == 'J'
def test_get_quarter_names():
- assert dates.get_quarter_names('wide', locale='en_US')[1] == u'1st quarter'
- assert dates.get_quarter_names('abbreviated', locale='de_DE')[1] == u'Q1'
- assert dates.get_quarter_names('narrow', locale='de_DE')[1] == u'1'
+ assert dates.get_quarter_names('wide', locale='en_US')[1] == '1st quarter'
+ assert dates.get_quarter_names('abbreviated', locale='de_DE')[1] == 'Q1'
+ assert dates.get_quarter_names('narrow', locale='de_DE')[1] == '1'
def test_get_era_names():
- assert dates.get_era_names('wide', locale='en_US')[1] == u'Anno Domini'
- assert dates.get_era_names('abbreviated', locale='de_DE')[1] == u'n. Chr.'
+ assert dates.get_era_names('wide', locale='en_US')[1] == 'Anno Domini'
+ assert dates.get_era_names('abbreviated', locale='de_DE')[1] == 'n. Chr.'
def test_get_date_format():
us = dates.get_date_format(locale='en_US')
- assert us.pattern == u'MMM d, y'
+ assert us.pattern == 'MMM d, y'
de = dates.get_date_format('full', locale='de_DE')
- assert de.pattern == u'EEEE, d. MMMM y'
+ assert de.pattern == 'EEEE, d. MMMM y'
def test_get_datetime_format():
- assert dates.get_datetime_format(locale='en_US') == u'{1}, {0}'
+ assert dates.get_datetime_format(locale='en_US') == '{1}, {0}'
def test_get_time_format():
- assert dates.get_time_format(locale='en_US').pattern == u'h:mm:ss a'
+ assert dates.get_time_format(locale='en_US').pattern == 'h:mm:ss a'
assert (dates.get_time_format('full', locale='de_DE').pattern ==
- u'HH:mm:ss zzzz')
+ 'HH:mm:ss zzzz')
def test_get_timezone_gmt(timezone_getter):
dt = datetime(2007, 4, 1, 15, 30)
- assert dates.get_timezone_gmt(dt, locale='en') == u'GMT+00:00'
+ assert dates.get_timezone_gmt(dt, locale='en') == 'GMT+00:00'
assert dates.get_timezone_gmt(dt, locale='en', return_z=True) == 'Z'
- assert dates.get_timezone_gmt(dt, locale='en', width='iso8601_short') == u'+00'
+ assert dates.get_timezone_gmt(dt, locale='en', width='iso8601_short') == '+00'
tz = timezone_getter('America/Los_Angeles')
dt = _localize(tz, datetime(2007, 4, 1, 15, 30))
- assert dates.get_timezone_gmt(dt, locale='en') == u'GMT-07:00'
- assert dates.get_timezone_gmt(dt, 'short', locale='en') == u'-0700'
- assert dates.get_timezone_gmt(dt, locale='en', width='iso8601_short') == u'-07'
- assert dates.get_timezone_gmt(dt, 'long', locale='fr_FR') == u'UTC-07:00'
+ assert dates.get_timezone_gmt(dt, locale='en') == 'GMT-07:00'
+ assert dates.get_timezone_gmt(dt, 'short', locale='en') == '-0700'
+ assert dates.get_timezone_gmt(dt, locale='en', width='iso8601_short') == '-07'
+ assert dates.get_timezone_gmt(dt, 'long', locale='fr_FR') == 'UTC-07:00'
def test_get_timezone_location(timezone_getter):
tz = timezone_getter('America/St_Johns')
assert (dates.get_timezone_location(tz, locale='de_DE') ==
- u"Kanada (St. John\u2019s) Zeit")
+ "Kanada (St. John\u2019s) Zeit")
assert (dates.get_timezone_location(tz, locale='en') ==
- u'Canada (St. John’s) Time')
+ 'Canada (St. John’s) Time')
assert (dates.get_timezone_location(tz, locale='en', return_city=True) ==
- u'St. John’s')
+ 'St. John’s')
tz = timezone_getter('America/Mexico_City')
assert (dates.get_timezone_location(tz, locale='de_DE') ==
- u'Mexiko (Mexiko-Stadt) Zeit')
+ 'Mexiko (Mexiko-Stadt) Zeit')
tz = timezone_getter('Europe/Berlin')
assert (dates.get_timezone_location(tz, locale='de_DE') ==
- u'Deutschland (Berlin) Zeit')
+ 'Deutschland (Berlin) Zeit')
@pytest.mark.parametrize(
"tzname, params, expected",
[
- ("America/Los_Angeles", {"locale": "en_US"}, u"Pacific Time"),
- ("America/Los_Angeles", {"width": "short", "locale": "en_US"}, u"PT"),
- ("Europe/Berlin", {"locale": "de_DE"}, u"Mitteleurop\xe4ische Zeit"),
- ("Europe/Berlin", {"locale": "pt_BR"}, u"Hor\xe1rio da Europa Central"),
- ("America/St_Johns", {"locale": "de_DE"}, u"Neufundland-Zeit"),
+ ("America/Los_Angeles", {"locale": "en_US"}, "Pacific Time"),
+ ("America/Los_Angeles", {"width": "short", "locale": "en_US"}, "PT"),
+ ("Europe/Berlin", {"locale": "de_DE"}, "Mitteleurop\xe4ische Zeit"),
+ ("Europe/Berlin", {"locale": "pt_BR"}, "Hor\xe1rio da Europa Central"),
+ ("America/St_Johns", {"locale": "de_DE"}, "Neufundland-Zeit"),
(
"America/Los_Angeles",
{"locale": "en", "width": "short", "zone_variant": "generic"},
- u"PT",
+ "PT",
),
(
"America/Los_Angeles",
{"locale": "en", "width": "short", "zone_variant": "standard"},
- u"PST",
+ "PST",
),
(
"America/Los_Angeles",
{"locale": "en", "width": "short", "zone_variant": "daylight"},
- u"PDT",
+ "PDT",
),
(
"America/Los_Angeles",
{"locale": "en", "width": "long", "zone_variant": "generic"},
- u"Pacific Time",
+ "Pacific Time",
),
(
"America/Los_Angeles",
{"locale": "en", "width": "long", "zone_variant": "standard"},
- u"Pacific Standard Time",
+ "Pacific Standard Time",
),
(
"America/Los_Angeles",
{"locale": "en", "width": "long", "zone_variant": "daylight"},
- u"Pacific Daylight Time",
+ "Pacific Daylight Time",
),
- ("Europe/Berlin", {"locale": "en_US"}, u"Central European Time"),
+ ("Europe/Berlin", {"locale": "en_US"}, "Central European Time"),
],
)
def test_get_timezone_name_tzinfo(timezone_getter, tzname, params, expected):
@@ -525,13 +525,13 @@ def test_get_timezone_name_tzinfo(timezone_getter, tzname, params, expected):
@pytest.mark.parametrize(
"tzname, params, expected",
[
- ("America/Los_Angeles", {"locale": "en_US"}, u"Pacific Standard Time"),
+ ("America/Los_Angeles", {"locale": "en_US"}, "Pacific Standard Time"),
(
"America/Los_Angeles",
{"locale": "en_US", "return_zone": True},
- u"America/Los_Angeles",
+ "America/Los_Angeles",
),
- ("America/Los_Angeles", {"width": "short", "locale": "en_US"}, u"PST"),
+ ("America/Los_Angeles", {"width": "short", "locale": "en_US"}, "PST"),
],
)
def test_get_timezone_name_time_pytz(timezone_getter, tzname, params, expected):
@@ -554,40 +554,42 @@ def test_get_timezone_name_misc(timezone_getter):
def test_format_date():
d = date(2007, 4, 1)
- assert dates.format_date(d, locale='en_US') == u'Apr 1, 2007'
+ assert dates.format_date(d, locale='en_US') == 'Apr 1, 2007'
assert (dates.format_date(d, format='full', locale='de_DE') ==
- u'Sonntag, 1. April 2007')
+ 'Sonntag, 1. April 2007')
assert (dates.format_date(d, "EEE, MMM d, ''yy", locale='en') ==
- u"Sun, Apr 1, '07")
+ "Sun, Apr 1, '07")
def test_format_datetime(timezone_getter):
dt = datetime(2007, 4, 1, 15, 30)
assert (dates.format_datetime(dt, locale='en_US') ==
- u'Apr 1, 2007, 3:30:00 PM')
+ 'Apr 1, 2007, 3:30:00 PM')
full = dates.format_datetime(
dt, 'full',
tzinfo=timezone_getter('Europe/Paris'),
locale='fr_FR'
)
- assert full == (u'dimanche 1 avril 2007 à 17:30:00 heure '
- u'd\u2019\xe9t\xe9 d\u2019Europe centrale')
+ assert full == (
+ 'dimanche 1 avril 2007 à 17:30:00 heure '
+ 'd\u2019\xe9t\xe9 d\u2019Europe centrale'
+ )
custom = dates.format_datetime(
dt, "yyyy.MM.dd G 'at' HH:mm:ss zzz",
tzinfo=timezone_getter('US/Eastern'),
locale='en'
)
- assert custom == u'2007.04.01 AD at 11:30:00 EDT'
+ assert custom == '2007.04.01 AD at 11:30:00 EDT'
def test_format_time(timezone_getter):
t = time(15, 30)
- assert dates.format_time(t, locale='en_US') == u'3:30:00 PM'
- assert dates.format_time(t, format='short', locale='de_DE') == u'15:30'
+ assert dates.format_time(t, locale='en_US') == '3:30:00 PM'
+ assert dates.format_time(t, format='short', locale='de_DE') == '15:30'
assert (dates.format_time(t, "hh 'o''clock' a", locale='en') ==
- u"03 o'clock PM")
+ "03 o'clock PM")
paris = timezone_getter('Europe/Paris')
eastern = timezone_getter('US/Eastern')
@@ -597,41 +599,41 @@ def test_format_time(timezone_getter):
assert fr == '15:30:00 heure d’été d’Europe centrale'
custom = dates.format_time(t, "hh 'o''clock' a, zzzz", tzinfo=eastern, locale='en')
- assert custom == u"09 o'clock AM, Eastern Daylight Time"
+ assert custom == "09 o'clock AM, Eastern Daylight Time"
t = time(15, 30)
paris = dates.format_time(t, format='full', tzinfo=paris, locale='fr_FR')
assert paris == '15:30:00 heure normale d’Europe centrale'
us_east = dates.format_time(t, format='full', tzinfo=eastern, locale='en_US')
- assert us_east == u'3:30:00 PM Eastern Standard Time'
+ assert us_east == '3:30:00 PM Eastern Standard Time'
def test_format_skeleton(timezone_getter):
dt = datetime(2007, 4, 1, 15, 30)
- assert (dates.format_skeleton('yMEd', dt, locale='en_US') == u'Sun, 4/1/2007')
- assert (dates.format_skeleton('yMEd', dt, locale='th') == u'อา. 1/4/2007')
+ assert (dates.format_skeleton('yMEd', dt, locale='en_US') == 'Sun, 4/1/2007')
+ assert (dates.format_skeleton('yMEd', dt, locale='th') == 'อา. 1/4/2007')
- assert (dates.format_skeleton('EHm', dt, locale='en') == u'Sun 15:30')
- assert (dates.format_skeleton('EHm', dt, tzinfo=timezone_getter('Asia/Bangkok'), locale='th') == u'อา. 22:30 น.')
+ assert (dates.format_skeleton('EHm', dt, locale='en') == 'Sun 15:30')
+ assert (dates.format_skeleton('EHm', dt, tzinfo=timezone_getter('Asia/Bangkok'), locale='th') == 'อา. 22:30 น.')
def test_format_timedelta():
assert (dates.format_timedelta(timedelta(weeks=12), locale='en_US')
- == u'3 months')
+ == '3 months')
assert (dates.format_timedelta(timedelta(seconds=1), locale='es')
- == u'1 segundo')
+ == '1 segundo')
assert (dates.format_timedelta(timedelta(hours=3), granularity='day',
locale='en_US')
- == u'1 day')
+ == '1 day')
assert (dates.format_timedelta(timedelta(hours=23), threshold=0.9,
locale='en_US')
- == u'1 day')
+ == '1 day')
assert (dates.format_timedelta(timedelta(hours=23), threshold=1.1,
locale='en_US')
- == u'23 hours')
+ == '23 hours')
def test_parse_date():
@@ -679,24 +681,24 @@ def test_datetime_format_get_week_number():
def test_parse_pattern():
- assert dates.parse_pattern("MMMMd").format == u'%(MMMM)s%(d)s'
+ assert dates.parse_pattern("MMMMd").format == '%(MMMM)s%(d)s'
assert (dates.parse_pattern("MMM d, yyyy").format ==
- u'%(MMM)s %(d)s, %(yyyy)s')
+ '%(MMM)s %(d)s, %(yyyy)s')
assert (dates.parse_pattern("H:mm' Uhr 'z").format ==
- u'%(H)s:%(mm)s Uhr %(z)s')
- assert dates.parse_pattern("hh' o''clock'").format == u"%(hh)s o'clock"
+ '%(H)s:%(mm)s Uhr %(z)s')
+ assert dates.parse_pattern("hh' o''clock'").format == "%(hh)s o'clock"
def test_lithuanian_long_format():
assert (
dates.format_date(date(2015, 12, 10), locale='lt_LT', format='long') ==
- u'2015 m. gruodžio 10 d.'
+ '2015 m. gruodžio 10 d.'
)
def test_zh_TW_format():
# Refs GitHub issue #378
- assert dates.format_time(datetime(2016, 4, 8, 12, 34, 56), locale='zh_TW') == u'中午12:34:56'
+ assert dates.format_time(datetime(2016, 4, 8, 12, 34, 56), locale='zh_TW') == '中午12:34:56'
def test_format_current_moment():
@@ -727,8 +729,8 @@ def test_no_inherit_metazone_formatting(timezone_getter):
def test_russian_week_numbering():
# See https://github.com/python-babel/babel/issues/485
v = date(2017, 1, 1)
- assert dates.format_date(v, format='YYYY-ww',locale='ru_RU') == '2016-52' # This would have returned 2017-01 prior to CLDR 32
- assert dates.format_date(v, format='YYYY-ww',locale='de_DE') == '2016-52'
+ assert dates.format_date(v, format='YYYY-ww', locale='ru_RU') == '2016-52' # This would have returned 2017-01 prior to CLDR 32
+ assert dates.format_date(v, format='YYYY-ww', locale='de_DE') == '2016-52'
def test_en_gb_first_weekday():
diff --git a/tests/test_day_periods.py b/tests/test_day_periods.py
index 414c0f6..9b51e1d 100644
--- a/tests/test_day_periods.py
+++ b/tests/test_day_periods.py
@@ -1,8 +1,9 @@
from datetime import time
-import babel.dates as dates
import pytest
+import babel.dates as dates
+
@pytest.mark.parametrize("locale, time, expected_period_id", [
("de", time(7, 42), "morning1"), # (from, before)
diff --git a/tests/test_lists.py b/tests/test_lists.py
index e51f18b..ca9c6ab 100644
--- a/tests/test_lists.py
+++ b/tests/test_lists.py
@@ -6,11 +6,11 @@ from babel import lists
def test_format_list():
for list, locale, expected in [
([], 'en', ''),
- ([u'string'], 'en', u'string'),
- (['string1', 'string2'], 'en', u'string1 and string2'),
- (['string1', 'string2', 'string3'], 'en', u'string1, string2, and string3'),
- (['string1', 'string2', 'string3'], 'zh', u'string1、string2和string3'),
- (['string1', 'string2', 'string3', 'string4'], 'ne', u'string1,string2, string3 र string4'),
+ (['string'], 'en', 'string'),
+ (['string1', 'string2'], 'en', 'string1 and string2'),
+ (['string1', 'string2', 'string3'], 'en', 'string1, string2, and string3'),
+ (['string1', 'string2', 'string3'], 'zh', 'string1、string2和string3'),
+ (['string1', 'string2', 'string3', 'string4'], 'ne', 'string1,string2, string3 र string4'),
]:
assert lists.format_list(list, locale=locale) == expected
diff --git a/tests/test_localedata.py b/tests/test_localedata.py
index 7bfe9c6..913922e 100644
--- a/tests/test_localedata.py
+++ b/tests/test_localedata.py
@@ -12,15 +12,15 @@
import os
import pickle
+import random
import sys
import tempfile
import unittest
-import random
from operator import methodcaller
import pytest
-from babel import localedata, Locale, UnknownLocaleError
+from babel import Locale, UnknownLocaleError, localedata
class MergeResolveTestCase(unittest.TestCase):
@@ -70,8 +70,8 @@ def test_merge():
def test_locale_identification():
- for l in localedata.locale_identifiers():
- assert localedata.exists(l)
+ for locale in localedata.locale_identifiers():
+ assert localedata.exists(locale)
def test_unique_ids():
@@ -84,9 +84,9 @@ def test_unique_ids():
def test_mixedcased_locale():
- for l in localedata.locale_identifiers():
+ for locale in localedata.locale_identifiers():
locale_id = ''.join([
- methodcaller(random.choice(['lower', 'upper']))(c) for c in l])
+ methodcaller(random.choice(['lower', 'upper']))(c) for c in locale])
assert localedata.exists(locale_id)
@@ -94,19 +94,18 @@ def test_locale_argument_acceptance():
# Testing None input.
normalized_locale = localedata.normalize_locale(None)
assert normalized_locale is None
- locale_exist = localedata.exists(None)
- assert locale_exist == False
+ assert not localedata.exists(None)
- # # Testing list input.
+ # Testing list input.
normalized_locale = localedata.normalize_locale(['en_us', None])
assert normalized_locale is None
- locale_exist = localedata.exists(['en_us', None])
- assert locale_exist == False
+ assert not localedata.exists(['en_us', None])
def test_locale_identifiers_cache(monkeypatch):
original_listdir = localedata.os.listdir
listdir_calls = []
+
def listdir_spy(*args):
rv = original_listdir(*args)
listdir_calls.append((args, rv))
diff --git a/tests/test_numbers.py b/tests/test_numbers.py
index 0939562..04a1865 100644
--- a/tests/test_numbers.py
+++ b/tests/test_numbers.py
@@ -12,14 +12,21 @@
import decimal
import unittest
-import pytest
-
from datetime import date
+import pytest
+
from babel import localedata, numbers
from babel.numbers import (
- list_currencies, validate_currency, UnknownCurrencyError, is_currency, normalize_currency,
- get_currency_precision, get_decimal_precision, get_currency_unit_pattern)
+ UnknownCurrencyError,
+ get_currency_precision,
+ get_currency_unit_pattern,
+ get_decimal_precision,
+ is_currency,
+ list_currencies,
+ normalize_currency,
+ validate_currency,
+)
class FormatDecimalTestCase(unittest.TestCase):
@@ -31,7 +38,7 @@ class FormatDecimalTestCase(unittest.TestCase):
# regression test for #183, fraction digits were not correctly cut
# if the input was a float value and the value had more than 7
# significant digits
- assert numbers.format_decimal(12345678.051, '#,##0.00', locale='en_US') == u'12,345,678.05'
+ assert numbers.format_decimal(12345678.051, '#,##0.00', locale='en_US') == '12,345,678.05'
def test_subpatterns(self):
assert numbers.format_decimal((- 12345), '#,##0.##;-#', locale='en_US') == '-12,345'
@@ -108,57 +115,58 @@ class FormatDecimalTestCase(unittest.TestCase):
assert numbers.format_decimal(29567.12, locale='en_US', group_separator=False) == '29567.12'
assert numbers.format_decimal(29567.12, locale='fr_CA', group_separator=False) == '29567,12'
assert numbers.format_decimal(29567.12, locale='pt_BR', group_separator=False) == '29567,12'
- assert numbers.format_currency(1099.98, 'USD', locale='en_US', group_separator=False) == u'$1099.98'
- assert numbers.format_currency(101299.98, 'EUR', locale='fr_CA', group_separator=False) == u'101299,98\xa0€'
+ assert numbers.format_currency(1099.98, 'USD', locale='en_US', group_separator=False) == '$1099.98'
+ assert numbers.format_currency(101299.98, 'EUR', locale='fr_CA', group_separator=False) == '101299,98\xa0€'
assert numbers.format_currency(101299.98, 'EUR', locale='en_US', group_separator=False, format_type='name') == '101299.98 euros'
- assert numbers.format_percent(251234.1234, locale='sv_SE', group_separator=False) == u'25123412\xa0%'
+ assert numbers.format_percent(251234.1234, locale='sv_SE', group_separator=False) == '25123412\xa0%'
- assert numbers.format_decimal(29567.12, locale='en_US', group_separator=True) == u'29,567.12'
- assert numbers.format_decimal(29567.12, locale='fr_CA', group_separator=True) == u'29\xa0567,12'
- assert numbers.format_decimal(29567.12, locale='pt_BR', group_separator=True) == u'29.567,12'
- assert numbers.format_currency(1099.98, 'USD', locale='en_US', group_separator=True) == u'$1,099.98'
- assert numbers.format_currency(101299.98, 'EUR', locale='fr_CA', group_separator=True) == u'101\xa0299,98\xa0€'
- assert numbers.format_currency(101299.98, 'EUR', locale='en_US', group_separator=True, format_type='name') == u'101,299.98 euros'
- assert numbers.format_percent(251234.1234, locale='sv_SE', group_separator=True) == u'25\xa0123\xa0412\xa0%'
+ assert numbers.format_decimal(29567.12, locale='en_US', group_separator=True) == '29,567.12'
+ assert numbers.format_decimal(29567.12, locale='fr_CA', group_separator=True) == '29\xa0567,12'
+ assert numbers.format_decimal(29567.12, locale='pt_BR', group_separator=True) == '29.567,12'
+ assert numbers.format_currency(1099.98, 'USD', locale='en_US', group_separator=True) == '$1,099.98'
+ assert numbers.format_currency(101299.98, 'EUR', locale='fr_CA', group_separator=True) == '101\xa0299,98\xa0€'
+ assert numbers.format_currency(101299.98, 'EUR', locale='en_US', group_separator=True, format_type='name') == '101,299.98 euros'
+ assert numbers.format_percent(251234.1234, locale='sv_SE', group_separator=True) == '25\xa0123\xa0412\xa0%'
def test_compact(self):
- assert numbers.format_compact_decimal(1, locale='en_US', format_type="short") == u'1'
- assert numbers.format_compact_decimal(999, locale='en_US', format_type="short") == u'999'
- assert numbers.format_compact_decimal(1000, locale='en_US', format_type="short") == u'1K'
- assert numbers.format_compact_decimal(9000, locale='en_US', format_type="short") == u'9K'
- assert numbers.format_compact_decimal(9123, locale='en_US', format_type="short", fraction_digits=2) == u'9.12K'
- assert numbers.format_compact_decimal(10000, locale='en_US', format_type="short") == u'10K'
- assert numbers.format_compact_decimal(10000, locale='en_US', format_type="short", fraction_digits=2) == u'10K'
- assert numbers.format_compact_decimal(1000000, locale='en_US', format_type="short") == u'1M'
- assert numbers.format_compact_decimal(9000999, locale='en_US', format_type="short") == u'9M'
- assert numbers.format_compact_decimal(9000900099, locale='en_US', format_type="short", fraction_digits=5) == u'9.0009B'
- assert numbers.format_compact_decimal(1, locale='en_US', format_type="long") == u'1'
- assert numbers.format_compact_decimal(999, locale='en_US', format_type="long") == u'999'
- assert numbers.format_compact_decimal(1000, locale='en_US', format_type="long") == u'1 thousand'
- assert numbers.format_compact_decimal(9000, locale='en_US', format_type="long") == u'9 thousand'
- assert numbers.format_compact_decimal(9000, locale='en_US', format_type="long", fraction_digits=2) == u'9 thousand'
- assert numbers.format_compact_decimal(10000, locale='en_US', format_type="long") == u'10 thousand'
- assert numbers.format_compact_decimal(10000, locale='en_US', format_type="long", fraction_digits=2) == u'10 thousand'
- assert numbers.format_compact_decimal(1000000, locale='en_US', format_type="long") == u'1 million'
- assert numbers.format_compact_decimal(9999999, locale='en_US', format_type="long") == u'10 million'
- assert numbers.format_compact_decimal(9999999999, locale='en_US', format_type="long", fraction_digits=5) == u'10 billion'
- assert numbers.format_compact_decimal(1, locale='ja_JP', format_type="short") == u'1'
- assert numbers.format_compact_decimal(999, locale='ja_JP', format_type="short") == u'999'
- assert numbers.format_compact_decimal(1000, locale='ja_JP', format_type="short") == u'1000'
- assert numbers.format_compact_decimal(9123, locale='ja_JP', format_type="short") == u'9123'
- assert numbers.format_compact_decimal(10000, locale='ja_JP', format_type="short") == u'1万'
- assert numbers.format_compact_decimal(1234567, locale='ja_JP', format_type="long") == u'123万'
- assert numbers.format_compact_decimal(-1, locale='en_US', format_type="short") == u'-1'
- assert numbers.format_compact_decimal(-1234, locale='en_US', format_type="short", fraction_digits=2) == u'-1.23K'
- assert numbers.format_compact_decimal(-123456789, format_type='short', locale='en_US') == u'-123M'
- assert numbers.format_compact_decimal(-123456789, format_type='long', locale='en_US') == u'-123 million'
- assert numbers.format_compact_decimal(2345678, locale='mk', format_type='long') == u'2 милиони'
- assert numbers.format_compact_decimal(21000000, locale='mk', format_type='long') == u'21 милион'
- assert numbers.format_compact_decimal(21345, locale="gv", format_type="short") == u'21K'
- assert numbers.format_compact_decimal(1000, locale='it', format_type='long') == u'mille'
- assert numbers.format_compact_decimal(1234, locale='it', format_type='long') == u'1 mila'
- assert numbers.format_compact_decimal(1000, locale='fr', format_type='long') == u'mille'
- assert numbers.format_compact_decimal(1234, locale='fr', format_type='long') == u'1 millier'
+ assert numbers.format_compact_decimal(1, locale='en_US', format_type="short") == '1'
+ assert numbers.format_compact_decimal(999, locale='en_US', format_type="short") == '999'
+ assert numbers.format_compact_decimal(1000, locale='en_US', format_type="short") == '1K'
+ assert numbers.format_compact_decimal(9000, locale='en_US', format_type="short") == '9K'
+ assert numbers.format_compact_decimal(9123, locale='en_US', format_type="short", fraction_digits=2) == '9.12K'
+ assert numbers.format_compact_decimal(10000, locale='en_US', format_type="short") == '10K'
+ assert numbers.format_compact_decimal(10000, locale='en_US', format_type="short", fraction_digits=2) == '10K'
+ assert numbers.format_compact_decimal(1000000, locale='en_US', format_type="short") == '1M'
+ assert numbers.format_compact_decimal(9000999, locale='en_US', format_type="short") == '9M'
+ assert numbers.format_compact_decimal(9000900099, locale='en_US', format_type="short", fraction_digits=5) == '9.0009B'
+ assert numbers.format_compact_decimal(1, locale='en_US', format_type="long") == '1'
+ assert numbers.format_compact_decimal(999, locale='en_US', format_type="long") == '999'
+ assert numbers.format_compact_decimal(1000, locale='en_US', format_type="long") == '1 thousand'
+ assert numbers.format_compact_decimal(9000, locale='en_US', format_type="long") == '9 thousand'
+ assert numbers.format_compact_decimal(9000, locale='en_US', format_type="long", fraction_digits=2) == '9 thousand'
+ assert numbers.format_compact_decimal(10000, locale='en_US', format_type="long") == '10 thousand'
+ assert numbers.format_compact_decimal(10000, locale='en_US', format_type="long", fraction_digits=2) == '10 thousand'
+ assert numbers.format_compact_decimal(1000000, locale='en_US', format_type="long") == '1 million'
+ assert numbers.format_compact_decimal(9999999, locale='en_US', format_type="long") == '10 million'
+ assert numbers.format_compact_decimal(9999999999, locale='en_US', format_type="long", fraction_digits=5) == '10 billion'
+ assert numbers.format_compact_decimal(1, locale='ja_JP', format_type="short") == '1'
+ assert numbers.format_compact_decimal(999, locale='ja_JP', format_type="short") == '999'
+ assert numbers.format_compact_decimal(1000, locale='ja_JP', format_type="short") == '1000'
+ assert numbers.format_compact_decimal(9123, locale='ja_JP', format_type="short") == '9123'
+ assert numbers.format_compact_decimal(10000, locale='ja_JP', format_type="short") == '1万'
+ assert numbers.format_compact_decimal(1234567, locale='ja_JP', format_type="long") == '123万'
+ assert numbers.format_compact_decimal(-1, locale='en_US', format_type="short") == '-1'
+ assert numbers.format_compact_decimal(-1234, locale='en_US', format_type="short", fraction_digits=2) == '-1.23K'
+ assert numbers.format_compact_decimal(-123456789, format_type='short', locale='en_US') == '-123M'
+ assert numbers.format_compact_decimal(-123456789, format_type='long', locale='en_US') == '-123 million'
+ assert numbers.format_compact_decimal(2345678, locale='mk', format_type='long') == '2 милиони'
+ assert numbers.format_compact_decimal(21000000, locale='mk', format_type='long') == '21 милион'
+ assert numbers.format_compact_decimal(21345, locale="gv", format_type="short") == '21K'
+ assert numbers.format_compact_decimal(1000, locale='it', format_type='long') == 'mille'
+ assert numbers.format_compact_decimal(1234, locale='it', format_type='long') == '1 mila'
+ assert numbers.format_compact_decimal(1000, locale='fr', format_type='long') == 'mille'
+ assert numbers.format_compact_decimal(1234, locale='fr', format_type='long') == '1 millier'
+
class NumberParsingTestCase(unittest.TestCase):
@@ -224,15 +232,15 @@ def test_validate_currency():
def test_is_currency():
- assert is_currency('EUR') == True
- assert is_currency('eUr') == False
- assert is_currency('FUU') == False
- assert is_currency('') == False
- assert is_currency(None) == False
- assert is_currency(' EUR ') == False
- assert is_currency(' ') == False
- assert is_currency([]) == False
- assert is_currency(set()) == False
+ assert is_currency('EUR')
+ assert not is_currency('eUr')
+ assert not is_currency('FUU')
+ assert not is_currency('')
+ assert not is_currency(None)
+ assert not is_currency(' EUR ')
+ assert not is_currency(' ')
+ assert not is_currency([])
+ assert not is_currency(set())
def test_normalize_currency():
@@ -248,12 +256,12 @@ def test_normalize_currency():
def test_get_currency_name():
- assert numbers.get_currency_name('USD', locale='en_US') == u'US Dollar'
- assert numbers.get_currency_name('USD', count=2, locale='en_US') == u'US dollars'
+ assert numbers.get_currency_name('USD', locale='en_US') == 'US Dollar'
+ assert numbers.get_currency_name('USD', count=2, locale='en_US') == 'US dollars'
def test_get_currency_symbol():
- assert numbers.get_currency_symbol('USD', 'en_US') == u'$'
+ assert numbers.get_currency_symbol('USD', 'en_US') == '$'
def test_get_currency_precision():
@@ -294,24 +302,24 @@ def test_get_territory_currencies():
def test_get_decimal_symbol():
- assert numbers.get_decimal_symbol('en_US') == u'.'
+ assert numbers.get_decimal_symbol('en_US') == '.'
def test_get_plus_sign_symbol():
- assert numbers.get_plus_sign_symbol('en_US') == u'+'
+ assert numbers.get_plus_sign_symbol('en_US') == '+'
def test_get_minus_sign_symbol():
- assert numbers.get_minus_sign_symbol('en_US') == u'-'
- assert numbers.get_minus_sign_symbol('nl_NL') == u'-'
+ assert numbers.get_minus_sign_symbol('en_US') == '-'
+ assert numbers.get_minus_sign_symbol('nl_NL') == '-'
def test_get_exponential_symbol():
- assert numbers.get_exponential_symbol('en_US') == u'E'
+ assert numbers.get_exponential_symbol('en_US') == 'E'
def test_get_group_symbol():
- assert numbers.get_group_symbol('en_US') == u','
+ assert numbers.get_group_symbol('en_US') == ','
def test_decimal_precision():
@@ -321,18 +329,18 @@ def test_decimal_precision():
def test_format_decimal():
- assert numbers.format_decimal(1099, locale='en_US') == u'1,099'
- assert numbers.format_decimal(1099, locale='de_DE') == u'1.099'
- assert numbers.format_decimal(1.2345, locale='en_US') == u'1.234'
- assert numbers.format_decimal(1.2346, locale='en_US') == u'1.235'
- assert numbers.format_decimal(-1.2346, locale='en_US') == u'-1.235'
- assert numbers.format_decimal(1.2345, locale='sv_SE') == u'1,234'
- assert numbers.format_decimal(1.2345, locale='de') == u'1,234'
- assert numbers.format_decimal(12345.5, locale='en_US') == u'12,345.5'
- assert numbers.format_decimal(0001.2345000, locale='en_US') == u'1.234'
- assert numbers.format_decimal(-0001.2346000, locale='en_US') == u'-1.235'
- assert numbers.format_decimal(0000000.5, locale='en_US') == u'0.5'
- assert numbers.format_decimal(000, locale='en_US') == u'0'
+ assert numbers.format_decimal(1099, locale='en_US') == '1,099'
+ assert numbers.format_decimal(1099, locale='de_DE') == '1.099'
+ assert numbers.format_decimal(1.2345, locale='en_US') == '1.234'
+ assert numbers.format_decimal(1.2346, locale='en_US') == '1.235'
+ assert numbers.format_decimal(-1.2346, locale='en_US') == '-1.235'
+ assert numbers.format_decimal(1.2345, locale='sv_SE') == '1,234'
+ assert numbers.format_decimal(1.2345, locale='de') == '1,234'
+ assert numbers.format_decimal(12345.5, locale='en_US') == '12,345.5'
+ assert numbers.format_decimal(0001.2345000, locale='en_US') == '1.234'
+ assert numbers.format_decimal(-0001.2346000, locale='en_US') == '-1.235'
+ assert numbers.format_decimal(0000000.5, locale='en_US') == '0.5'
+ assert numbers.format_decimal(000, locale='en_US') == '0'
@pytest.mark.parametrize('input_value, expected_value', [
@@ -372,43 +380,43 @@ def test_format_decimal_quantization():
def test_format_currency():
assert (numbers.format_currency(1099.98, 'USD', locale='en_US')
- == u'$1,099.98')
+ == '$1,099.98')
assert (numbers.format_currency(0, 'USD', locale='en_US')
- == u'$0.00')
+ == '$0.00')
assert (numbers.format_currency(1099.98, 'USD', locale='es_CO')
- == u'US$\xa01.099,98')
+ == 'US$\xa01.099,98')
assert (numbers.format_currency(1099.98, 'EUR', locale='de_DE')
- == u'1.099,98\xa0\u20ac')
- assert (numbers.format_currency(1099.98, 'EUR', u'\xa4\xa4 #,##0.00',
+ == '1.099,98\xa0\u20ac')
+ assert (numbers.format_currency(1099.98, 'EUR', '\xa4\xa4 #,##0.00',
locale='en_US')
- == u'EUR 1,099.98')
+ == 'EUR 1,099.98')
assert (numbers.format_currency(1099.98, 'EUR', locale='nl_NL')
!= numbers.format_currency(-1099.98, 'EUR', locale='nl_NL'))
assert (numbers.format_currency(1099.98, 'USD', format=None,
locale='en_US')
- == u'$1,099.98')
+ == '$1,099.98')
assert (numbers.format_currency(1, 'USD', locale='es_AR')
- == u'US$\xa01,00') # one
+ == 'US$\xa01,00') # one
assert (numbers.format_currency(1000000, 'USD', locale='es_AR')
- == u'US$\xa01.000.000,00') # many
+ == 'US$\xa01.000.000,00') # many
assert (numbers.format_currency(0, 'USD', locale='es_AR')
- == u'US$\xa00,00') # other
+ == 'US$\xa00,00') # other
def test_format_currency_format_type():
assert (numbers.format_currency(1099.98, 'USD', locale='en_US',
format_type="standard")
- == u'$1,099.98')
+ == '$1,099.98')
assert (numbers.format_currency(0, 'USD', locale='en_US',
format_type="standard")
- == u'$0.00')
+ == '$0.00')
assert (numbers.format_currency(1099.98, 'USD', locale='en_US',
format_type="accounting")
- == u'$1,099.98')
+ == '$1,099.98')
assert (numbers.format_currency(0, 'USD', locale='en_US',
format_type="accounting")
- == u'$0.00')
+ == '$0.00')
with pytest.raises(numbers.UnknownCurrencyFormatError) as excinfo:
numbers.format_currency(1099.98, 'USD', locale='en_US',
@@ -416,27 +424,27 @@ def test_format_currency_format_type():
assert excinfo.value.args[0] == "'unknown' is not a known currency format type"
assert (numbers.format_currency(1099.98, 'JPY', locale='en_US')
- == u'\xa51,100')
- assert (numbers.format_currency(1099.98, 'COP', u'#,##0.00', locale='es_ES')
- == u'1.099,98')
+ == '\xa51,100')
+ assert (numbers.format_currency(1099.98, 'COP', '#,##0.00', locale='es_ES')
+ == '1.099,98')
assert (numbers.format_currency(1099.98, 'JPY', locale='en_US',
currency_digits=False)
- == u'\xa51,099.98')
- assert (numbers.format_currency(1099.98, 'COP', u'#,##0.00', locale='es_ES',
+ == '\xa51,099.98')
+ assert (numbers.format_currency(1099.98, 'COP', '#,##0.00', locale='es_ES',
currency_digits=False)
- == u'1.099,98')
+ == '1.099,98')
def test_format_compact_currency():
- assert numbers.format_compact_currency(1, 'USD', locale='en_US', format_type="short") == u'$1'
- assert numbers.format_compact_currency(999, 'USD', locale='en_US', format_type="short") == u'$999'
- assert numbers.format_compact_currency(123456789, 'USD', locale='en_US', format_type="short") == u'$123M'
- assert numbers.format_compact_currency(123456789, 'USD', locale='en_US', fraction_digits=2, format_type="short") == u'$123.46M'
- assert numbers.format_compact_currency(-123456789, 'USD', locale='en_US', fraction_digits=2, format_type="short") == u'-$123.46M'
- assert numbers.format_compact_currency(1, 'JPY', locale='ja_JP', format_type="short") == u'¥1'
- assert numbers.format_compact_currency(1234, 'JPY', locale='ja_JP', format_type="short") == u'¥1234'
- assert numbers.format_compact_currency(123456, 'JPY', locale='ja_JP', format_type="short") == u'¥12万'
- assert numbers.format_compact_currency(123456, 'JPY', locale='ja_JP', format_type="short", fraction_digits=2) == u'¥12.35万'
+ assert numbers.format_compact_currency(1, 'USD', locale='en_US', format_type="short") == '$1'
+ assert numbers.format_compact_currency(999, 'USD', locale='en_US', format_type="short") == '$999'
+ assert numbers.format_compact_currency(123456789, 'USD', locale='en_US', format_type="short") == '$123M'
+ assert numbers.format_compact_currency(123456789, 'USD', locale='en_US', fraction_digits=2, format_type="short") == '$123.46M'
+ assert numbers.format_compact_currency(-123456789, 'USD', locale='en_US', fraction_digits=2, format_type="short") == '-$123.46M'
+ assert numbers.format_compact_currency(1, 'JPY', locale='ja_JP', format_type="short") == '¥1'
+ assert numbers.format_compact_currency(1234, 'JPY', locale='ja_JP', format_type="short") == '¥1234'
+ assert numbers.format_compact_currency(123456, 'JPY', locale='ja_JP', format_type="short") == '¥12万'
+ assert numbers.format_compact_currency(123456, 'JPY', locale='ja_JP', format_type="short", fraction_digits=2) == '¥12.35万'
assert numbers.format_compact_currency(123, 'EUR', locale='yav', format_type="short") == '123\xa0€'
assert numbers.format_compact_currency(12345, 'EUR', locale='yav', format_type="short") == '12K\xa0€'
assert numbers.format_compact_currency(123456789, 'EUR', locale='de_DE', fraction_digits=1) == '123,5\xa0Mio.\xa0€'
@@ -444,8 +452,7 @@ def test_format_compact_currency():
def test_format_compact_currency_invalid_format_type():
with pytest.raises(numbers.UnknownCurrencyFormatError):
- numbers.format_compact_currency(1099.98, 'USD', locale='en_US',
- format_type='unknown')
+ numbers.format_compact_currency(1099.98, 'USD', locale='en_US', format_type='unknown')
@pytest.mark.parametrize('input_value, expected_value', [
@@ -485,30 +492,30 @@ def test_format_currency_quantization():
def test_format_currency_long_display_name():
assert (numbers.format_currency(1099.98, 'USD', locale='en_US', format_type='name')
- == u'1,099.98 US dollars')
+ == '1,099.98 US dollars')
assert (numbers.format_currency(1.00, 'USD', locale='en_US', format_type='name')
- == u'1.00 US dollar')
+ == '1.00 US dollar')
assert (numbers.format_currency(1.00, 'EUR', locale='en_US', format_type='name')
- == u'1.00 euro')
+ == '1.00 euro')
assert (numbers.format_currency(2, 'EUR', locale='en_US', format_type='name')
- == u'2.00 euros')
+ == '2.00 euros')
# This tests that '{1} {0}' unitPatterns are found:
assert (numbers.format_currency(1, 'USD', locale='sw', format_type='name')
- == u'dola ya Marekani 1.00')
+ == 'dola ya Marekani 1.00')
# This tests unicode chars:
assert (numbers.format_currency(1099.98, 'USD', locale='es_GT', format_type='name')
- == u'dólares estadounidenses 1,099.98')
+ == 'dólares estadounidenses 1,099.98')
# Test for completely unknown currency, should fallback to currency code
assert (numbers.format_currency(1099.98, 'XAB', locale='en_US', format_type='name')
- == u'1,099.98 XAB')
+ == '1,099.98 XAB')
# Test for finding different unit patterns depending on count
assert (numbers.format_currency(1, 'USD', locale='ro', format_type='name')
- == u'1,00 dolar american')
+ == '1,00 dolar american')
assert (numbers.format_currency(2, 'USD', locale='ro', format_type='name')
- == u'2,00 dolari americani')
+ == '2,00 dolari americani')
assert (numbers.format_currency(100, 'USD', locale='ro', format_type='name')
- == u'100,00 de dolari americani')
+ == '100,00 de dolari americani')
def test_format_currency_long_display_name_all():
@@ -530,15 +537,15 @@ def test_format_currency_long_display_name_custom_format():
def test_format_percent():
- assert numbers.format_percent(0.34, locale='en_US') == u'34%'
- assert numbers.format_percent(0, locale='en_US') == u'0%'
- assert numbers.format_percent(0.34, u'##0%', locale='en_US') == u'34%'
- assert numbers.format_percent(34, u'##0', locale='en_US') == u'34'
- assert numbers.format_percent(25.1234, locale='en_US') == u'2,512%'
+ assert numbers.format_percent(0.34, locale='en_US') == '34%'
+ assert numbers.format_percent(0, locale='en_US') == '0%'
+ assert numbers.format_percent(0.34, '##0%', locale='en_US') == '34%'
+ assert numbers.format_percent(34, '##0', locale='en_US') == '34'
+ assert numbers.format_percent(25.1234, locale='en_US') == '2,512%'
assert (numbers.format_percent(25.1234, locale='sv_SE')
- == u'2\xa0512\xa0%')
- assert (numbers.format_percent(25.1234, u'#,##0\u2030', locale='en_US')
- == u'25,123\u2030')
+ == '2\xa0512\xa0%')
+ assert (numbers.format_percent(25.1234, '#,##0\u2030', locale='en_US')
+ == '25,123\u2030')
@pytest.mark.parametrize('input_value, expected_value', [
@@ -576,25 +583,25 @@ def test_format_percent_quantization():
def test_format_scientific():
- assert numbers.format_scientific(10000, locale='en_US') == u'1E4'
- assert numbers.format_scientific(4234567, u'#.#E0', locale='en_US') == u'4.2E6'
- assert numbers.format_scientific(4234567, u'0E0000', locale='en_US') == u'4.234567E0006'
- assert numbers.format_scientific(4234567, u'##0E00', locale='en_US') == u'4.234567E06'
- assert numbers.format_scientific(4234567, u'##00E00', locale='en_US') == u'42.34567E05'
- assert numbers.format_scientific(4234567, u'0,000E00', locale='en_US') == u'4,234.567E03'
- assert numbers.format_scientific(4234567, u'##0.#####E00', locale='en_US') == u'4.23457E06'
- assert numbers.format_scientific(4234567, u'##0.##E00', locale='en_US') == u'4.23E06'
- assert numbers.format_scientific(42, u'00000.000000E0000', locale='en_US') == u'42000.000000E-0003'
+ assert numbers.format_scientific(10000, locale='en_US') == '1E4'
+ assert numbers.format_scientific(4234567, '#.#E0', locale='en_US') == '4.2E6'
+ assert numbers.format_scientific(4234567, '0E0000', locale='en_US') == '4.234567E0006'
+ assert numbers.format_scientific(4234567, '##0E00', locale='en_US') == '4.234567E06'
+ assert numbers.format_scientific(4234567, '##00E00', locale='en_US') == '42.34567E05'
+ assert numbers.format_scientific(4234567, '0,000E00', locale='en_US') == '4,234.567E03'
+ assert numbers.format_scientific(4234567, '##0.#####E00', locale='en_US') == '4.23457E06'
+ assert numbers.format_scientific(4234567, '##0.##E00', locale='en_US') == '4.23E06'
+ assert numbers.format_scientific(42, '00000.000000E0000', locale='en_US') == '42000.000000E-0003'
def test_default_scientific_format():
""" Check the scientific format method auto-correct the rendering pattern
in case of a missing fractional part.
"""
- assert numbers.format_scientific(12345, locale='en_US') == u'1.2345E4'
- assert numbers.format_scientific(12345.678, locale='en_US') == u'1.2345678E4'
- assert numbers.format_scientific(12345, u'#E0', locale='en_US') == u'1.2345E4'
- assert numbers.format_scientific(12345.678, u'#E0', locale='en_US') == u'1.2345678E4'
+ assert numbers.format_scientific(12345, locale='en_US') == '1.2345E4'
+ assert numbers.format_scientific(12345.678, locale='en_US') == '1.2345678E4'
+ assert numbers.format_scientific(12345, '#E0', locale='en_US') == '1.2345E4'
+ assert numbers.format_scientific(12345.678, '#E0', locale='en_US') == '1.2345678E4'
@pytest.mark.parametrize('input_value, expected_value', [
@@ -660,18 +667,18 @@ def test_parse_grouping():
def test_parse_pattern():
# Original pattern is preserved
- np = numbers.parse_pattern(u'¤#,##0.00')
- assert np.pattern == u'¤#,##0.00'
+ np = numbers.parse_pattern('¤#,##0.00')
+ assert np.pattern == '¤#,##0.00'
- np = numbers.parse_pattern(u'¤#,##0.00;(¤#,##0.00)')
- assert np.pattern == u'¤#,##0.00;(¤#,##0.00)'
+ np = numbers.parse_pattern('¤#,##0.00;(¤#,##0.00)')
+ assert np.pattern == '¤#,##0.00;(¤#,##0.00)'
# Given a NumberPattern object, we don't return a new instance.
# However, we don't cache NumberPattern objects, so calling
# parse_pattern with the same format string will create new
# instances
- np1 = numbers.parse_pattern(u'¤ #,##0.00')
- np2 = numbers.parse_pattern(u'¤ #,##0.00')
+ np1 = numbers.parse_pattern('¤ #,##0.00')
+ np2 = numbers.parse_pattern('¤ #,##0.00')
assert np1 is not np2
assert np1 is numbers.parse_pattern(np1)
@@ -679,19 +686,19 @@ def test_parse_pattern():
def test_parse_pattern_negative():
# No negative format specified
- np = numbers.parse_pattern(u'¤#,##0.00')
- assert np.prefix == (u'¤', u'-¤')
- assert np.suffix == (u'', u'')
+ np = numbers.parse_pattern('¤#,##0.00')
+ assert np.prefix == ('¤', '-¤')
+ assert np.suffix == ('', '')
# Negative format is specified
- np = numbers.parse_pattern(u'¤#,##0.00;(¤#,##0.00)')
- assert np.prefix == (u'¤', u'(¤')
- assert np.suffix == (u'', u')')
+ np = numbers.parse_pattern('¤#,##0.00;(¤#,##0.00)')
+ assert np.prefix == ('¤', '(¤')
+ assert np.suffix == ('', ')')
# Negative sign is a suffix
- np = numbers.parse_pattern(u'¤ #,##0.00;¤ #,##0.00-')
- assert np.prefix == (u'¤ ', u'¤ ')
- assert np.suffix == (u'', u'-')
+ np = numbers.parse_pattern('¤ #,##0.00;¤ #,##0.00-')
+ assert np.prefix == ('¤ ', '¤ ')
+ assert np.suffix == ('', '-')
def test_numberpattern_repr():
@@ -699,7 +706,7 @@ def test_numberpattern_repr():
# This implementation looks a bit funny, but that's cause strings are
# repr'd differently in Python 2 vs 3 and this test runs under both.
- format = u'¤#,##0.00;(¤#,##0.00)'
+ format = '¤#,##0.00;(¤#,##0.00)'
np = numbers.parse_pattern(format)
assert repr(format) in repr(np)
diff --git a/tests/test_plural.py b/tests/test_plural.py
index 16601cf..e1e5ead 100644
--- a/tests/test_plural.py
+++ b/tests/test_plural.py
@@ -11,9 +11,10 @@
# history and logs, available at http://babel.edgewall.org/log/.
import decimal
import unittest
+
import pytest
-from babel import plural, localedata
+from babel import localedata, plural
EPSILON = decimal.Decimal("0.0001")
diff --git a/tests/test_smoke.py b/tests/test_smoke.py
index aed676a..c916845 100644
--- a/tests/test_smoke.py
+++ b/tests/test_smoke.py
@@ -4,11 +4,12 @@ looking at improving test coverage. They just verify that basic
operations don't fail due to odd corner cases on any locale that
we ship.
"""
-import decimal
import datetime
+import decimal
+
import pytest
-from babel import Locale, units, dates, numbers
+from babel import Locale, dates, numbers, units
NUMBERS = (
decimal.Decimal("-33.76"), # Negative Decimal
diff --git a/tests/test_support.py b/tests/test_support.py
index 3ca0be3..0b7cba0 100644
--- a/tests/test_support.py
+++ b/tests/test_support.py
@@ -13,20 +13,21 @@
import inspect
import os
import shutil
+import sys
import tempfile
import unittest
-import pytest
-import sys
from datetime import date, datetime, timedelta
from io import BytesIO
+import pytest
+
from babel import support
from babel.messages import Catalog
from babel.messages.mofile import write_mo
-
SKIP_LGETTEXT = sys.version_info >= (3, 8)
+
@pytest.mark.usefixtures("os_environ")
class TranslationsTestCase(unittest.TestCase):
@@ -71,9 +72,9 @@ class TranslationsTestCase(unittest.TestCase):
'foo'))
def test_upgettext(self):
- self.assertEqualTypeToo(u'Voh', self.translations.ugettext('foo'))
- self.assertEqualTypeToo(u'VohCTX', self.translations.upgettext('foo',
- 'foo'))
+ self.assertEqualTypeToo('Voh', self.translations.ugettext('foo'))
+ self.assertEqualTypeToo('VohCTX', self.translations.upgettext('foo',
+ 'foo'))
@pytest.mark.skipif(SKIP_LGETTEXT, reason="lgettext is deprecated")
def test_lpgettext(self):
@@ -94,14 +95,14 @@ class TranslationsTestCase(unittest.TestCase):
'foos1', 2))
def test_unpgettext(self):
- self.assertEqualTypeToo(u'Voh1',
+ self.assertEqualTypeToo('Voh1',
self.translations.ungettext('foo1', 'foos1', 1))
- self.assertEqualTypeToo(u'Vohs1',
+ self.assertEqualTypeToo('Vohs1',
self.translations.ungettext('foo1', 'foos1', 2))
- self.assertEqualTypeToo(u'VohCTX1',
+ self.assertEqualTypeToo('VohCTX1',
self.translations.unpgettext('foo', 'foo1',
'foos1', 1))
- self.assertEqualTypeToo(u'VohsCTX1',
+ self.assertEqualTypeToo('VohsCTX1',
self.translations.unpgettext('foo', 'foo1',
'foos1', 2))
@@ -126,9 +127,9 @@ class TranslationsTestCase(unittest.TestCase):
def test_dupgettext(self):
self.assertEqualTypeToo(
- u'VohD', self.translations.dugettext('messages1', 'foo'))
+ 'VohD', self.translations.dugettext('messages1', 'foo'))
self.assertEqualTypeToo(
- u'VohCTXD', self.translations.dupgettext('messages1', 'foo', 'foo'))
+ 'VohCTXD', self.translations.dupgettext('messages1', 'foo', 'foo'))
@pytest.mark.skipif(SKIP_LGETTEXT, reason="lgettext is deprecated")
def test_ldpgettext(self):
@@ -151,15 +152,15 @@ class TranslationsTestCase(unittest.TestCase):
def test_dunpgettext(self):
self.assertEqualTypeToo(
- u'VohD1', self.translations.dungettext('messages1', 'foo1', 'foos1', 1))
+ 'VohD1', self.translations.dungettext('messages1', 'foo1', 'foos1', 1))
self.assertEqualTypeToo(
- u'VohsD1', self.translations.dungettext('messages1', 'foo1', 'foos1', 2))
+ 'VohsD1', self.translations.dungettext('messages1', 'foo1', 'foos1', 2))
self.assertEqualTypeToo(
- u'VohCTXD1', self.translations.dunpgettext('messages1', 'foo', 'foo1',
- 'foos1', 1))
+ 'VohCTXD1', self.translations.dunpgettext('messages1', 'foo', 'foo1',
+ 'foos1', 1))
self.assertEqualTypeToo(
- u'VohsCTXD1', self.translations.dunpgettext('messages1', 'foo', 'foo1',
- 'foos1', 2))
+ 'VohsCTXD1', self.translations.dunpgettext('messages1', 'foo', 'foo1',
+ 'foos1', 2))
@pytest.mark.skipif(SKIP_LGETTEXT, reason="lgettext is deprecated")
def test_ldnpgettext(self):
@@ -219,9 +220,9 @@ class NullTranslationsTestCase(unittest.TestCase):
def test_same_return_values(self):
data = {
- 'message': u'foo', 'domain': u'domain', 'context': 'tests',
- 'singular': u'bar', 'plural': u'baz', 'num': 1,
- 'msgid1': u'bar', 'msgid2': u'baz', 'n': 1,
+ 'message': 'foo', 'domain': 'domain', 'context': 'tests',
+ 'singular': 'bar', 'plural': 'baz', 'num': 1,
+ 'msgid1': 'bar', 'msgid2': 'baz', 'n': 1,
}
for name in self.method_names():
method = getattr(self.translations, name)
@@ -346,21 +347,20 @@ def test_lazy_proxy():
return f"Hello, {name}!"
lazy_greeting = support.LazyProxy(greeting, name='Joe')
- assert str(lazy_greeting) == u"Hello, Joe!"
- assert u' ' + lazy_greeting == u' Hello, Joe!'
- assert u'(%s)' % lazy_greeting == u'(Hello, Joe!)'
+ assert str(lazy_greeting) == "Hello, Joe!"
+ assert ' ' + lazy_greeting == ' Hello, Joe!'
+ assert '(%s)' % lazy_greeting == '(Hello, Joe!)'
assert f"[{lazy_greeting}]" == "[Hello, Joe!]"
- greetings = [
+ greetings = sorted([
support.LazyProxy(greeting, 'world'),
support.LazyProxy(greeting, 'Joe'),
support.LazyProxy(greeting, 'universe'),
- ]
- greetings.sort()
+ ])
assert [str(g) for g in greetings] == [
- u"Hello, Joe!",
- u"Hello, universe!",
- u"Hello, world!",
+ "Hello, Joe!",
+ "Hello, universe!",
+ "Hello, world!",
]
diff --git a/tests/test_util.py b/tests/test_util.py
index d78aee7..ae861dd 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -11,6 +11,7 @@
# history and logs, available at http://babel.edgewall.org/log/.
import __future__
+
import unittest
from io import BytesIO
@@ -21,11 +22,12 @@ from babel.util import parse_future_flags
class _FF:
- division = __future__.division.compiler_flag
- print_function = __future__.print_function.compiler_flag
- with_statement = __future__.with_statement.compiler_flag
+ division = __future__.division.compiler_flag
+ print_function = __future__.print_function.compiler_flag
+ with_statement = __future__.with_statement.compiler_flag
unicode_literals = __future__.unicode_literals.compiler_flag
+
def test_distinct():
assert list(util.distinct([1, 2, 1, 3, 4, 4])) == [1, 2, 3, 4]
assert list(util.distinct('foobar')) == ['f', 'o', 'b', 'a', 'r']
@@ -47,7 +49,7 @@ def test_pathmatch():
class FixedOffsetTimezoneTestCase(unittest.TestCase):
def test_zone_negative_offset(self):
- assert util.FixedOffsetTimezone((-60)).zone == 'Etc/GMT-60'
+ assert util.FixedOffsetTimezone(-60).zone == 'Etc/GMT-60'
def test_zone_zero_offset(self):
assert util.FixedOffsetTimezone(0).zone == 'Etc/GMT+0'
@@ -56,19 +58,20 @@ class FixedOffsetTimezoneTestCase(unittest.TestCase):
assert util.FixedOffsetTimezone(330).zone == 'Etc/GMT+330'
-parse_encoding = lambda s: util.parse_encoding(BytesIO(s.encode('utf-8')))
+def parse_encoding(s):
+ return util.parse_encoding(BytesIO(s.encode('utf-8')))
def test_parse_encoding_defined():
- assert parse_encoding(u'# coding: utf-8') == 'utf-8'
+ assert parse_encoding('# coding: utf-8') == 'utf-8'
def test_parse_encoding_undefined():
- assert parse_encoding(u'') is None
+ assert parse_encoding('') is None
def test_parse_encoding_non_ascii():
- assert parse_encoding(u'K\xf6ln') is None
+ assert parse_encoding('K\xf6ln') is None
@pytest.mark.parametrize('source, result', [