Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

More fixes and modernization #960

Merged
merged 2 commits into from Jan 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 7 additions & 7 deletions babel/core.py
Expand Up @@ -1175,20 +1175,20 @@ def parse_locale(identifier: str, sep: str = '_') -> tuple[str, str | None, str
raise ValueError(f"expected only letters, got {lang!r}")

script = territory = variant = None
if parts:
if len(parts[0]) == 4 and parts[0].isalpha():
script = parts.pop(0).title()
if parts and len(parts[0]) == 4 and parts[0].isalpha():
script = parts.pop(0).title()

if parts:
if len(parts[0]) == 2 and parts[0].isalpha():
territory = parts.pop(0).upper()
elif len(parts[0]) == 3 and parts[0].isdigit():
territory = parts.pop(0)

if parts:
if len(parts[0]) == 4 and parts[0][0].isdigit() or \
len(parts[0]) >= 5 and parts[0][0].isalpha():
variant = parts.pop().upper()
if parts and (
len(parts[0]) == 4 and parts[0][0].isdigit() or
len(parts[0]) >= 5 and parts[0][0].isalpha()
):
variant = parts.pop().upper()

if parts:
raise ValueError(f"{identifier!r} is not a valid locale identifier")
Expand Down
49 changes: 17 additions & 32 deletions babel/dates.py
Expand Up @@ -93,10 +93,7 @@ def _get_dt_and_tzinfo(dt_or_tzinfo: _DtOrTzinfo) -> tuple[datetime.datetime | N
tzinfo = UTC
elif isinstance(dt_or_tzinfo, (datetime.datetime, datetime.time)):
dt = _get_datetime(dt_or_tzinfo)
if dt.tzinfo is not None:
tzinfo = dt.tzinfo
else:
tzinfo = UTC
tzinfo = dt.tzinfo if dt.tzinfo is not None else UTC
else:
dt = None
tzinfo = dt_or_tzinfo
Expand Down Expand Up @@ -151,7 +148,7 @@ def _get_datetime(instant: _Instant) -> datetime.datetime:
"""
if instant is None:
return datetime.datetime.utcnow()
elif isinstance(instant, int) or isinstance(instant, float):
elif isinstance(instant, (int, float)):
return datetime.datetime.utcfromtimestamp(instant)
elif isinstance(instant, datetime.time):
return datetime.datetime.combine(datetime.date.today(), instant)
Expand Down Expand Up @@ -732,10 +729,7 @@ def get_timezone_name(
zone_variant = 'generic'
else:
dst = tzinfo.dst(dt)
if dst:
zone_variant = 'daylight'
else:
zone_variant = 'standard'
zone_variant = "daylight" if dst else "standard"
else:
if zone_variant not in ('generic', 'standard', 'daylight'):
raise ValueError('Invalid zone variation')
Expand All @@ -746,9 +740,8 @@ def get_timezone_name(
return zone
info = locale.time_zones.get(zone, {})
# Try explicitly translated zone names first
if width in info:
if zone_variant in info[width]:
return info[width][zone_variant]
if width in info and zone_variant in info[width]:
return info[width][zone_variant]

metazone = get_global('meta_zones').get(zone)
if metazone:
Expand Down Expand Up @@ -1205,15 +1198,14 @@ def format_interval(
# > single date using availableFormats, and return.

for field in PATTERN_CHAR_ORDER: # These are in largest-to-smallest order
if field in skel_formats:
if start_fmt.extract(field) != end_fmt.extract(field):
# > If there is a match, use the pieces of the corresponding pattern to
# > format the start and end datetime, as above.
return "".join(
parse_pattern(pattern).apply(instant, locale)
for pattern, instant
in zip(skel_formats[field], (start, end))
)
if field in skel_formats and start_fmt.extract(field) != end_fmt.extract(field):
# > If there is a match, use the pieces of the corresponding pattern to
# > format the start and end datetime, as above.
return "".join(
parse_pattern(pattern).apply(instant, locale)
for pattern, instant
in zip(skel_formats[field], (start, end))
)

# > Otherwise, format the start and end datetime using the fallback pattern.

Expand Down Expand Up @@ -1352,10 +1344,7 @@ def parse_date(
# names, both in the requested locale, and english

year = numbers[indexes['Y']]
if len(year) == 2:
year = 2000 + int(year)
else:
year = int(year)
year = 2000 + int(year) if len(year) == 2 else int(year)
month = int(numbers[indexes['M']])
day = int(numbers[indexes['D']])
if month > 12:
Expand Down Expand Up @@ -1402,9 +1391,8 @@ def parse_time(
# Check if the format specifies a period to be used;
# if it does, look for 'pm' to figure out an offset.
hour_offset = 0
if 'a' in format_str:
if 'pm' in string.lower():
hour_offset = 12
if 'a' in format_str and 'pm' in string.lower():
hour_offset = 12

# Parse up to three numbers from the string.
minute = second = 0
Expand Down Expand Up @@ -1607,10 +1595,7 @@ def format_weekday(self, char: str = 'E', num: int = 4) -> str:
num = 3
weekday = self.value.weekday()
width = {3: 'abbreviated', 4: 'wide', 5: 'narrow', 6: 'short'}[num]
if char == 'c':
context = 'stand-alone'
else:
context = 'format'
context = "stand-alone" if char == "c" else "format"
return get_day_names(width, context, self.locale)[weekday]

def format_day_of_year(self, num: int) -> str:
Expand Down
5 changes: 1 addition & 4 deletions babel/localedata.py
Expand Up @@ -136,10 +136,7 @@ def load(name: os.PathLike[str] | str, merge_inherited: bool = True) -> dict[str
parent = get_global('parent_exceptions').get(name)
if not parent:
parts = name.split('_')
if len(parts) == 1:
parent = 'root'
else:
parent = '_'.join(parts[:-1])
parent = "root" if len(parts) == 1 else "_".join(parts[:-1])
data = load(parent).copy()
filename = resolve_locale_filename(name)
with open(filename, 'rb') as fileobj:
Expand Down
5 changes: 1 addition & 4 deletions babel/localtime/_fallback.py
Expand Up @@ -12,10 +12,7 @@
import time

STDOFFSET = datetime.timedelta(seconds=-time.timezone)
if time.daylight:
DSTOFFSET = datetime.timedelta(seconds=-time.altzone)
else:
DSTOFFSET = STDOFFSET
DSTOFFSET = datetime.timedelta(seconds=-time.altzone) if time.daylight else STDOFFSET

DSTDIFF = DSTOFFSET - STDOFFSET
ZERO = datetime.timedelta(0)
Expand Down
12 changes: 3 additions & 9 deletions babel/messages/extract.py
Expand Up @@ -276,7 +276,7 @@ def check_and_call_extract_file(
options=options,
strip_comment_tags=strip_comment_tags
):
yield (filename, ) + message_tuple
yield (filename, *message_tuple)

break

Expand Down Expand Up @@ -400,10 +400,7 @@ def extract(
options=options or {})

for lineno, funcname, messages, comments in results:
if funcname:
spec = keywords[funcname] or (1,)
else:
spec = (1,)
spec = keywords[funcname] or (1,) if funcname else (1,)
if not isinstance(messages, (list, tuple)):
messages = [messages]
if not messages:
Expand Down Expand Up @@ -540,10 +537,7 @@ def extract_python(
else:
messages.append(None)

if len(messages) > 1:
messages = tuple(messages)
else:
messages = messages[0]
messages = tuple(messages) if len(messages) > 1 else messages[0]
# Comments don't apply unless they immediately
# precede the message
if translator_comments and \
Expand Down
21 changes: 7 additions & 14 deletions babel/messages/frontend.py
Expand Up @@ -412,10 +412,7 @@ def finalize_options(self):
'input-dirs and input-paths are mutually exclusive'
)

if self.no_default_keywords:
keywords = {}
else:
keywords = DEFAULT_KEYWORDS.copy()
keywords = {} if self.no_default_keywords else DEFAULT_KEYWORDS.copy()

keywords.update(parse_keywords(listify_value(self.keywords)))

Expand Down Expand Up @@ -945,12 +942,10 @@ def run(self, argv=None):
self._configure_logging(options.loglevel)
if options.list_locales:
identifiers = localedata.locale_identifiers()
longest = max(len(identifier) for identifier in identifiers)
identifiers.sort()
format = '%%-%ds %%s' % (longest + 1)
for identifier in identifiers:
id_width = max(len(identifier) for identifier in identifiers) + 1
for identifier in sorted(identifiers):
locale = Locale.parse(identifier)
print(format % (identifier, locale.english_name))
print(f"{identifier:<{id_width}} {locale.english_name}")
return 0

if not args:
Expand Down Expand Up @@ -982,11 +977,9 @@ def _configure_logging(self, loglevel):
def _help(self):
print(self.parser.format_help())
print("commands:")
longest = max(len(command) for command in self.commands)
format = " %%-%ds %%s" % max(8, longest + 1)
commands = sorted(self.commands.items())
for name, description in commands:
print(format % (name, description))
cmd_width = max(8, max(len(command) for command in self.commands) + 1)
for name, description in sorted(self.commands.items()):
print(f" {name:<{cmd_width}} {description}")

def _configure_command(self, cmdname, argv):
"""
Expand Down
10 changes: 2 additions & 8 deletions babel/messages/pofile.py
Expand Up @@ -189,10 +189,7 @@ def _add_message(self) -> None:
string = tuple(string)
else:
string = self.translations[0][1].denormalize()
if self.context:
msgctxt = self.context.denormalize()
else:
msgctxt = None
msgctxt = self.context.denormalize() if self.context else None
message = Message(msgid, string, list(self.locations), set(self.flags),
self.auto_comments, self.user_comments, lineno=self.offset + 1,
context=msgctxt)
Expand Down Expand Up @@ -543,10 +540,7 @@ def _write(text):
def _write_comment(comment, prefix=''):
# xgettext always wraps comments even if --no-wrap is passed;
# provide the same behaviour
if width and width > 0:
_width = width
else:
_width = 76
_width = width if width and width > 0 else 76
for line in wraptext(comment, _width):
_write(f"#{prefix} {line.strip()}\n")

Expand Down
11 changes: 3 additions & 8 deletions babel/numbers.py
Expand Up @@ -696,10 +696,7 @@ def _format_currency_long_name(
# Step 2.

# Correct number to numeric type, important for looking up plural rules:
if isinstance(number, str):
number_n = float(number)
else:
number_n = number
number_n = float(number) if isinstance(number, str) else number

# Step 3.
unit_pattern = get_currency_unit_pattern(currency, count=number_n, locale=locale)
Expand Down Expand Up @@ -1032,10 +1029,8 @@ def _match_number(pattern):
number, exp = number.split('E', 1)
else:
exp = None
if '@' in number:
if '.' in number and '0' in number:
raise ValueError('Significant digit patterns can not contain '
'"@" or "0"')
if '@' in number and '.' in number and '0' in number:
raise ValueError('Significant digit patterns can not contain "@" or "0"')
if '.' in number:
integer, fraction = number.rsplit('.', 1)
else:
Expand Down
2 changes: 1 addition & 1 deletion babel/plural.py
Expand Up @@ -334,7 +334,7 @@ class RuleError(Exception):
'f', # visible fraction digits in n, with trailing zeros.*
't', # visible fraction digits in n, without trailing zeros.*
'c', # compact decimal exponent value: exponent of the power of 10 used in compact decimal formatting.
'e', # currently, synonym for ‘c’. however, may be redefined in the future.
'e', # currently, synonym for `c`. however, may be redefined in the future.
}

_RULES: list[tuple[str | None, re.Pattern[str]]] = [
Expand Down
5 changes: 1 addition & 4 deletions babel/support.py
Expand Up @@ -542,10 +542,7 @@ def unpgettext(self, context: str, singular: str, plural: str, num: int) -> str:
except KeyError:
if self._fallback:
return self._fallback.unpgettext(context, singular, plural, num)
if num == 1:
tmsg = str(singular)
else:
tmsg = str(plural)
tmsg = str(singular) if num == 1 else str(plural)
return tmsg

def dpgettext(self, domain: str, context: str, message: str) -> str | object:
Expand Down