From 1a3e264b2a11ac75b068a8e2e9b5cc932d225957 Mon Sep 17 00:00:00 2001 From: Draper <27962761+Drapersniper@users.noreply.github.com> Date: Mon, 3 Aug 2020 14:17:05 +0100 Subject: [PATCH] Make `humanize_list()` use babel. (#2982) * Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now `[p]bankset maxbal` can be used to set the maximum bank balance Signed-off-by: Guy * Migrates ``humanize_list`` over to babel, and uses the existing `get_babel_locale` function to get a valid locale based on bot locale. Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com> * Migrates ``humanize_list`` over to babel, and uses the existing `get_babel_locale` function to get a valid locale based on bot locale. Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com> * Fixes docs Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com> * Add reference to Babel's `format_list` * Add Babel to intersphinx * remove towncrier entry * Migrates ``humanize_list`` over to babel, and uses the existing `get_babel_locale` function to get a valid locale based on bot locale. Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com> * Fixes docs Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com> * Add reference to Babel's `format_list` * Fix order, make the parameters keyword-only Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com> --- redbot/core/utils/chat_formatting.py | 61 ++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/redbot/core/utils/chat_formatting.py b/redbot/core/utils/chat_formatting.py index 04d4db65f..f4fff6435 100644 --- a/redbot/core/utils/chat_formatting.py +++ b/redbot/core/utils/chat_formatting.py @@ -1,13 +1,13 @@ -import itertools import datetime -from typing import Sequence, Iterator, List, Optional, Union, SupportsInt +import itertools from io import BytesIO - +from typing import Iterator, List, Optional, Sequence, SupportsInt, Union import discord +from babel.lists import format_list as babel_list from babel.numbers import format_decimal -from redbot.core.i18n import Translator, get_babel_regional_format +from redbot.core.i18n import Translator, get_babel_locale, get_babel_regional_format _ = Translator("UtilsChatFormatting", __file__) @@ -352,21 +352,50 @@ def escape(text: str, *, mass_mentions: bool = False, formatting: bool = False) return text -def humanize_list(items: Sequence[str]) -> str: - """Get comma-separted list, with the last element joined with *and*. - - This uses an Oxford comma, because without one, items containing - the word *and* would make the output difficult to interpret. +def humanize_list( + items: Sequence[str], *, locale: Optional[str] = None, style: str = "standard" +) -> str: + """Get comma-separated list, with the last element joined with *and*. Parameters ---------- items : Sequence[str] The items of the list to join together. + locale : Optional[str] + The locale to convert, if not specified it defaults to the bot's locale. + style : str + The style to format the list with. + + Note: Not all styles are necessarily available in all locales, + see documentation of `babel.lists.format_list` for more details. + + standard + A typical 'and' list for arbitrary placeholders. + eg. "January, February, and March" + standard-short + A short version of a 'and' list, suitable for use with short or + abbreviated placeholder values. + eg. "Jan., Feb., and Mar." + or + A typical 'or' list for arbitrary placeholders. + eg. "January, February, or March" + or-short + A short version of an 'or' list. + eg. "Jan., Feb., or Mar." + unit + A list suitable for wide units. + eg. "3 feet, 7 inches" + unit-short + A list suitable for short units + eg. "3 ft, 7 in" + unit-narrow + A list suitable for narrow units, where space on the screen is very limited. + eg. "3′ 7″" Raises ------ - IndexError - An empty sequence was passed + ValueError + The locale does not support the specified style. Examples -------- @@ -380,14 +409,12 @@ def humanize_list(items: Sequence[str]) -> str: 'One, Two, and Three' >>> humanize_list(['One']) 'One' + >>> humanize_list(['omena', 'peruna', 'aplari'], style='or', locale='fi') + 'omena, peruna tai aplari' """ - if len(items) == 1: - return items[0] - try: - return ", ".join(items[:-1]) + _(", and ") + items[-1] - except IndexError: - raise IndexError("Cannot humanize empty sequence") from None + + return babel_list(items, style=style, locale=get_babel_locale(locale)) def format_perms_list(perms: discord.Permissions) -> str: