--- /srv/rebuilderd/tmp/rebuilderdRlK6Y1/inputs/python-humanfriendly-doc_10.0-6_all.deb +++ /srv/rebuilderd/tmp/rebuilderdRlK6Y1/out/python-humanfriendly-doc_10.0-6_all.deb ├── file list │ @@ -1,3 +1,3 @@ │ -rw-r--r-- 0 0 0 4 2024-10-07 21:26:10.000000 debian-binary │ -rw-r--r-- 0 0 0 1656 2024-10-07 21:26:10.000000 control.tar.xz │ --rw-r--r-- 0 0 0 380072 2024-10-07 21:26:10.000000 data.tar.xz │ +-rw-r--r-- 0 0 0 379232 2024-10-07 21:26:10.000000 data.tar.xz ├── control.tar.xz │ ├── control.tar │ │ ├── ./control │ │ │ @@ -1,13 +1,13 @@ │ │ │ Package: python-humanfriendly-doc │ │ │ Source: humanfriendly │ │ │ Version: 10.0-6 │ │ │ Architecture: all │ │ │ Maintainer: Debian Python Team │ │ │ -Installed-Size: 1391 │ │ │ +Installed-Size: 1354 │ │ │ Depends: libjs-sphinxdoc (>= 7.4) │ │ │ Section: doc │ │ │ Priority: optional │ │ │ Multi-Arch: foreign │ │ │ Homepage: https://humanfriendly.readthedocs.io │ │ │ Description: Python3 library to make user friendly text interfaces - Documentation │ │ │ A Python3 library that can be used to make text interfaces more user friendly. │ │ ├── ./md5sums │ │ │ ├── ./md5sums │ │ │ │┄ Files differ ├── data.tar.xz │ ├── data.tar │ │ ├── file list │ │ │ @@ -23,20 +23,20 @@ │ │ │ -rw-r--r-- 0 root (0) root (0) 15094 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/_static/basic.css │ │ │ -rw-r--r-- 0 root (0) root (0) 327 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/_static/documentation_options.js │ │ │ -rw-r--r-- 0 root (0) root (0) 286 2024-08-23 06:32:51.000000 ./usr/share/doc/python-humanfriendly-doc/html/_static/file.png │ │ │ -rw-r--r-- 0 root (0) root (0) 90 2024-08-23 06:32:51.000000 ./usr/share/doc/python-humanfriendly-doc/html/_static/minus.png │ │ │ -rw-r--r-- 0 root (0) root (0) 4243 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/_static/nature.css │ │ │ -rw-r--r-- 0 root (0) root (0) 90 2024-08-23 06:32:51.000000 ./usr/share/doc/python-humanfriendly-doc/html/_static/plus.png │ │ │ -rw-r--r-- 0 root (0) root (0) 4929 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/_static/pygments.css │ │ │ --rw-r--r-- 0 root (0) root (0) 739862 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/api.html │ │ │ --rw-r--r-- 0 root (0) root (0) 23496 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/changelog.html.gz │ │ │ +-rw-r--r-- 0 root (0) root (0) 702314 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/api.html │ │ │ +-rw-r--r-- 0 root (0) root (0) 23397 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/changelog.html.gz │ │ │ -rw-r--r-- 0 root (0) root (0) 54510 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/genindex.html │ │ │ -rw-r--r-- 0 root (0) root (0) 99268 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/index.html │ │ │ -rw-r--r-- 0 root (0) root (0) 2749 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/objects.inv │ │ │ -rw-r--r-- 0 root (0) root (0) 6618 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/py-modindex.html │ │ │ -rw-r--r-- 0 root (0) root (0) 19882 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/readme.html │ │ │ -rw-r--r-- 0 root (0) root (0) 3379 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/search.html │ │ │ --rw-r--r-- 0 root (0) root (0) 92110 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/searchindex.js │ │ │ +-rw-r--r-- 0 root (0) root (0) 92120 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/searchindex.js │ │ │ lrwxrwxrwx 0 root (0) root (0) 0 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/_static/doctools.js -> ../../../../javascript/sphinxdoc/1.0/doctools.js │ │ │ lrwxrwxrwx 0 root (0) root (0) 0 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/_static/language_data.js -> ../../../../javascript/sphinxdoc/1.0/language_data.js │ │ │ lrwxrwxrwx 0 root (0) root (0) 0 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/_static/searchtools.js -> ../../../../javascript/sphinxdoc/1.0/searchtools.js │ │ │ lrwxrwxrwx 0 root (0) root (0) 0 2024-10-07 21:26:10.000000 ./usr/share/doc/python-humanfriendly-doc/html/_static/sphinx_highlight.js -> ../../../../javascript/sphinxdoc/1.0/sphinx_highlight.js │ │ ├── ./usr/share/doc/python-humanfriendly-doc/html/api.html │ │ │ @@ -85,15 +85,15 @@ │ │ │ │ │ │
│ │ │

humanfriendly

│ │ │

The main module of the humanfriendly package.

│ │ │
│ │ │

Note

│ │ │

Deprecated names

│ │ │ -

The following aliases exist to preserve backwards compatibility, however a DeprecationWarning is triggered when they are accessed, because these aliases will be removed in a future release.

│ │ │ +

The following aliases exist to preserve backwards compatibility, however a DeprecationWarning is triggered when they are accessed, because these aliases will be removed in a future release.

│ │ │
│ │ │
│ │ │ humanfriendly.format_table
│ │ │

Alias for humanfriendly.tables.format_pretty_table.

│ │ │
│ │ │ │ │ │
│ │ │ @@ -367,43 +367,43 @@ │ │ │
│ │ │ __init__(start_time=None, resumable=False)
│ │ │

Remember the time when the Timer was created.

│ │ │
│ │ │
Parameters:
│ │ │
    │ │ │
  • start_time – The start time (a float, defaults to the current time).

  • │ │ │ -
  • resumable – Create a resumable timer (defaults to False).

  • │ │ │ +
  • resumable – Create a resumable timer (defaults to False).

  • │ │ │
│ │ │
│ │ │
│ │ │ -

When start_time is given Timer uses time.time() as a │ │ │ +

When start_time is given Timer uses time.time() as a │ │ │ clock source, otherwise it uses humanfriendly.compat.monotonic().

│ │ │
│ │ │ │ │ │
│ │ │
│ │ │ __enter__()
│ │ │

Start or resume counting elapsed time.

│ │ │
│ │ │
Returns:
│ │ │

The Timer object.

│ │ │
│ │ │
Raises:
│ │ │ -

ValueError when the timer isn’t resumable.

│ │ │ +

ValueError when the timer isn’t resumable.

│ │ │
│ │ │
│ │ │
│ │ │ │ │ │
│ │ │
│ │ │ __exit__(exc_type=None, exc_value=None, traceback=None)
│ │ │

Stop counting elapsed time.

│ │ │
│ │ │
Raises:
│ │ │ -

ValueError when the timer isn’t resumable.

│ │ │ +

ValueError when the timer isn’t resumable.

│ │ │
│ │ │
│ │ │
│ │ │ │ │ │
│ │ │
│ │ │ sleep(seconds)
│ │ │ @@ -412,19 +412,19 @@ │ │ │
Parameters:
│ │ │

seconds – The number of seconds to sleep (an │ │ │ integer or floating point number).

│ │ │
│ │ │
│ │ │

This method sleeps for the given number of seconds minus the │ │ │ elapsed_time. If the resulting duration is negative │ │ │ -time.sleep() will still be called, but the argument │ │ │ +time.sleep() will still be called, but the argument │ │ │ given to it will be the number 0 (negative numbers cause │ │ │ -time.sleep() to raise an exception).

│ │ │ +time.sleep() to raise an exception).

│ │ │

The use case for this is to initialize a Timer inside │ │ │ -the body of a for or while loop and call │ │ │ +the body of a for or while loop and call │ │ │ Timer.sleep() at the end of the loop body to rate limit │ │ │ whatever it is that is being done inside the loop body.

│ │ │

For posterity: Although the implementation of sleep() only │ │ │ requires a single line of code I’ve added it to humanfriendly │ │ │ anyway because now that I’ve thought about how to tackle this once I │ │ │ never want to have to think about it again :-P (unless I find ways to │ │ │ improve this).

│ │ │ @@ -454,26 +454,26 @@ │ │ │
│ │ │ humanfriendly.coerce_boolean(value)
│ │ │

Coerce any value to a boolean.

│ │ │
│ │ │
Parameters:
│ │ │

value

Any Python value. If the value is a string:

│ │ │
    │ │ │ -
  • The strings ‘1’, ‘yes’, ‘true’ and ‘on’ are coerced to True.

  • │ │ │ -
  • The strings ‘0’, ‘no’, ‘false’ and ‘off’ are coerced to False.

  • │ │ │ +
  • The strings ‘1’, ‘yes’, ‘true’ and ‘on’ are coerced to True.

  • │ │ │ +
  • The strings ‘0’, ‘no’, ‘false’ and ‘off’ are coerced to False.

  • │ │ │
  • Other strings raise an exception.

  • │ │ │
│ │ │ -

Other Python values are coerced using bool.

│ │ │ +

Other Python values are coerced using bool.

│ │ │

│ │ │
│ │ │
Returns:
│ │ │

A proper boolean value.

│ │ │
│ │ │
Raises:
│ │ │ -

exceptions.ValueError when the value is a string but │ │ │ +

exceptions.ValueError when the value is a string but │ │ │ cannot be coerced with certainty.

│ │ │
│ │ │
│ │ │
│ │ │ │ │ │
│ │ │
│ │ │ @@ -487,47 +487,47 @@ │ │ │
  • flags – The flags used to compile the pattern (an integer).

  • │ │ │ │ │ │ │ │ │
    Returns:
    │ │ │

    A compiled regular expression.

    │ │ │
    │ │ │
    Raises:
    │ │ │ -

    ValueError when value isn’t a string │ │ │ +

    ValueError when value isn’t a string │ │ │ and also isn’t a compiled regular expression.

    │ │ │
    │ │ │
    │ │ │ │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.coerce_seconds(value)
    │ │ │

    Coerce a value to the number of seconds.

    │ │ │
    │ │ │
    Parameters:
    │ │ │ -

    value – An int, float or │ │ │ -datetime.timedelta object.

    │ │ │ +

    value – An int, float or │ │ │ +datetime.timedelta object.

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    An int or float value.

    │ │ │ +

    An int or float value.

    │ │ │
    │ │ │
    │ │ │ -

    When value is a datetime.timedelta object the │ │ │ -total_seconds() method is called.

    │ │ │ +

    When value is a datetime.timedelta object the │ │ │ +total_seconds() method is called.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.format_length(num_metres, keep_width=False)
    │ │ │

    Format a metre count as a human readable length.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • num_metres – The length to format in metres (float / integer).

    • │ │ │ -
    • keep_widthTrue if trailing zeros should not be stripped, │ │ │ -False if they can be stripped.

    • │ │ │ +
    • keep_widthTrue if trailing zeros should not be stripped, │ │ │ +False if they can be stripped.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The corresponding human readable length (a string).

    │ │ │
    │ │ │
    │ │ │

    This function supports ranges from nanometres to kilometres.

    │ │ │ @@ -550,16 +550,16 @@ │ │ │
    │ │ │
    │ │ │ humanfriendly.format_number(number, num_decimals=2)
    │ │ │

    Format a number as a string including thousands separators.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │ -
    • number – The number to format (a number like an int, │ │ │ -long or float).

    • │ │ │ +
    • number – The number to format (a number like an int, │ │ │ +long or float).

    • │ │ │
    • num_decimals – The number of decimals to render (2 by default). If no │ │ │ decimal places are required to represent the number │ │ │ they will be omitted regardless of this argument.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The formatted number (a string).

    │ │ │ @@ -612,18 +612,18 @@ │ │ │
    │ │ │ humanfriendly.format_size(num_bytes, keep_width=False, binary=False)
    │ │ │

    Format a byte count as a human readable file size.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • num_bytes – The size to format in bytes (an integer).

    • │ │ │ -
    • keep_widthTrue if trailing zeros should not be stripped, │ │ │ -False if they can be stripped.

    • │ │ │ -
    • binaryTrue to use binary multiples of bytes (base-2), │ │ │ -False to use decimal multiples of bytes (base-10).

    • │ │ │ +
    • keep_widthTrue if trailing zeros should not be stripped, │ │ │ +False if they can be stripped.

    • │ │ │ +
    • binaryTrue to use binary multiples of bytes (base-2), │ │ │ +False to use decimal multiples of bytes (base-10).

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The corresponding human readable file size (a string).

    │ │ │
    │ │ │
    │ │ │

    This function knows how to format sizes in bytes, kilobytes, megabytes, │ │ │ @@ -649,17 +649,17 @@ │ │ │

    │ │ │ humanfriendly.format_timespan(num_seconds, detailed=False, max_units=3)
    │ │ │

    Format a timespan in seconds as a human readable string.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • num_seconds – Any value accepted by coerce_seconds().

    • │ │ │ -
    • detailed – If True milliseconds are represented separately │ │ │ +

    • detailed – If True milliseconds are represented separately │ │ │ instead of being represented as fractional seconds │ │ │ -(defaults to False).

    • │ │ │ +(defaults to False).

      │ │ │
    • max_units – The maximum number of units to show in the formatted time │ │ │ span (an integer, defaults to three).

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The formatted timespan as a string.

    │ │ │
    │ │ │ @@ -706,15 +706,15 @@ │ │ │
  • YYYY-MM-DD

  • │ │ │
  • YYYY-MM-DD HH:MM:SS

  • │ │ │ │ │ │
    │ │ │

    Note

    │ │ │

    If you want to parse date/time strings with a fixed, known │ │ │ format and parse_date() isn’t useful to you, consider │ │ │ -time.strptime() or datetime.datetime.strptime(), │ │ │ +time.strptime() or datetime.datetime.strptime(), │ │ │ both of which are included in the Python standard library. │ │ │ Alternatively for more complex tasks consider using the date/time │ │ │ parsing module in the dateutil package.

    │ │ │
    │ │ │

    Examples:

    │ │ │
    >>> from humanfriendly import parse_date
    │ │ │  >>> parse_date('2013-06-17')
    │ │ │ @@ -726,15 +726,15 @@
    │ │ │  

    Here’s how you convert the result to a number (Unix time):

    │ │ │
    >>> from humanfriendly import parse_date
    │ │ │  >>> from time import mktime
    │ │ │  >>> mktime(parse_date('2013-06-17 02:47:42') + (-1, -1, -1))
    │ │ │  1371430062.0
    │ │ │  
    │ │ │
    │ │ │ -

    And here’s how you convert it to a datetime.datetime object:

    │ │ │ +

    And here’s how you convert it to a datetime.datetime object:

    │ │ │
    >>> from humanfriendly import parse_date
    │ │ │  >>> from datetime import datetime
    │ │ │  >>> datetime(*parse_date('2013-06-17 02:47:42'))
    │ │ │  datetime.datetime(2013, 6, 17, 2, 47, 42)
    │ │ │  
    │ │ │
    │ │ │

    Here’s an example that combines format_timespan() and │ │ │ @@ -779,17 +779,17 @@ │ │ │

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.parse_path(pathname)
    │ │ │

    Convert a human friendly pathname to an absolute pathname.

    │ │ │ -

    Expands leading tildes using os.path.expanduser() and │ │ │ -environment variables using os.path.expandvars() and makes the │ │ │ -resulting pathname absolute using os.path.abspath().

    │ │ │ +

    Expands leading tildes using os.path.expanduser() and │ │ │ +environment variables using os.path.expandvars() and makes the │ │ │ +resulting pathname absolute using os.path.abspath().

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    pathname – A human friendly pathname (a string).

    │ │ │
    │ │ │
    Returns:
    │ │ │

    An absolute pathname (a string).

    │ │ │
    │ │ │ @@ -800,16 +800,16 @@ │ │ │
    │ │ │ humanfriendly.parse_size(size, binary=False)
    │ │ │

    Parse a human readable data size and return the number of bytes.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • size – The human readable file size to parse (a string).

    • │ │ │ -
    • binaryTrue to use binary multiples of bytes (base-2) for │ │ │ -ambiguous unit symbols and names, False to use │ │ │ +

    • binaryTrue to use binary multiples of bytes (base-2) for │ │ │ +ambiguous unit symbols and names, False to use │ │ │ decimal multiples of bytes (base-10).

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The corresponding size in bytes (an integer).

    │ │ │
    │ │ │
    Raises:
    │ │ │ @@ -892,16 +892,16 @@ │ │ │
    │ │ │ humanfriendly.round_number(count, keep_width=False)
    │ │ │

    Round a floating point number to two decimal places in a human friendly format.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • count – The number to format.

    • │ │ │ -
    • keep_widthTrue if trailing zeros should not be stripped, │ │ │ -False if they can be stripped.

    • │ │ │ +
    • keep_widthTrue if trailing zeros should not be stripped, │ │ │ +False if they can be stripped.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The formatted number as a string. If no decimal places are │ │ │ required to represent the number, they will be omitted.

    │ │ │
    │ │ │
    │ │ │ @@ -958,16 +958,16 @@ │ │ │ humanfriendly.concatenate(items, conjunction='and', serial_comma=False) │ │ │

    Concatenate a list of items in a human friendly way.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • items – A sequence of strings.

    • │ │ │
    • conjunction – The word to use before the last item (a string, defaults to “and”).

    • │ │ │ -
    • serial_commaTrue to use a serial comma, False otherwise │ │ │ -(defaults to False).

    • │ │ │ +
    • serial_commaTrue to use a serial comma, False otherwise │ │ │ +(defaults to False).

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    A single string.

    │ │ │
    │ │ │
    │ │ │
    >>> from humanfriendly.text import concatenate
    │ │ │ @@ -978,15 +978,15 @@
    │ │ │  
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.dedent(text, *args, **kw)
    │ │ │

    Dedent a string (remove common leading whitespace from all lines).

    │ │ │

    Removes common leading whitespace from all lines in the string using │ │ │ -textwrap.dedent(), removes leading and trailing empty lines using │ │ │ +textwrap.dedent(), removes leading and trailing empty lines using │ │ │ trim_empty_lines() and interpolates any arguments using │ │ │ format().

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text to dedent (a string).

    • │ │ │
    • args – Any positional arguments are interpolated using format().

    • │ │ │ @@ -1016,37 +1016,37 @@ │ │ │
    • aliases – Each keyword argument defines an alias. The values │ │ │ are expected to be “dotted paths” (strings).

    • │ │ │
    │ │ │
    │ │ │
    │ │ │

    The behavior of this function depends on whether the Sphinx documentation │ │ │ generator is active, because the use of DeprecationProxy to shadow the │ │ │ -real module in sys.modules has the unintended side effect of │ │ │ +real module in sys.modules has the unintended side effect of │ │ │ breaking autodoc support for :data: members (module variables).

    │ │ │

    To avoid breaking Sphinx the proxy object is omitted and instead the │ │ │ aliased names are injected into the original module namespace, to make sure │ │ │ that imports can be satisfied when the documentation is being rendered.

    │ │ │

    If you run into cyclic dependencies caused by define_aliases() when │ │ │ running Sphinx, you can try moving the call to define_aliases() to │ │ │ the bottom of the Python module you’re working on.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.format(text, *args, **kw)
    │ │ │ -

    Format a string using the string formatting operator and/or str.format().

    │ │ │ +

    Format a string using the string formatting operator and/or str.format().

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text to format (a string).

    • │ │ │
    • args – Any positional arguments are interpolated into the text using │ │ │ the string formatting operator (%). If no positional │ │ │ arguments are given no interpolation is done.

    • │ │ │
    • kw – Any keyword arguments are interpolated into the text using the │ │ │ -str.format() function. If no keyword arguments are given │ │ │ +str.format() function. If no keyword arguments are given │ │ │ no interpolation is done.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The text with any positional and/or keyword arguments │ │ │ interpolated (a string).

    │ │ │
    │ │ │ @@ -1074,15 +1074,15 @@ │ │ │ the magic number is 42 │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ the magic numbers are 12 and 42 │ │ │
    │ │ │ │ │ │ │ │ │
  • When you interpolate a single value and someone accidentally passes in a │ │ │ -tuple your code raises a TypeError. Because │ │ │ +tuple your code raises a TypeError. Because │ │ │ format() takes a variable number of arguments it always │ │ │ receives a tuple so this can never happen. Here’s an example:

    │ │ │
    >>> # How expecting to interpolate a single value can fail.
    │ │ │  >>> value = (12, 42)
    │ │ │  >>> print('the magic value is %s' % value)
    │ │ │  Traceback (most recent call last):
    │ │ │    File "<stdin>", line 1, in <module>
    │ │ │ @@ -1091,15 +1091,15 @@
    │ │ │  >>> print(format('the magic value is %s', value))
    │ │ │  the magic value is (12, 42)
    │ │ │  
    │ │ │
    │ │ │
  • │ │ │ │ │ │

    Why format() instead of the str.format() method?

    │ │ │ -

    When you’re doing complex string interpolation the str.format() │ │ │ +

    When you’re doing complex string interpolation the str.format() │ │ │ function results in more readable code, however I frequently find myself │ │ │ adding parentheses to force evaluation order. The format() function │ │ │ avoids this because of the relative priority between the comma and dot │ │ │ operators. Here’s an example:

    │ │ │
    >>> "{adjective} example" + " " + "(can't think of anything less {adjective})".format(adjective='silly')
    │ │ │  "{adjective} example (can't think of anything less silly)"
    │ │ │  >>> ("{adjective} example" + " " + "(can't think of anything less {adjective})").format(adjective='silly')
    │ │ │ @@ -1116,15 +1116,15 @@
    │ │ │  
    │ │ │
    │ │ │ humanfriendly.format_table(data, column_names=None, horizontal_bar='-', vertical_bar='|')
    │ │ │

    Render a table using characters like dashes and vertical bars to emulate borders.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │ -
    • data – An iterable (e.g. a tuple() or list) │ │ │ +

    • data – An iterable (e.g. a tuple() or list) │ │ │ containing the rows of the table, where each row is an │ │ │ iterable containing the columns of the table (strings).

    • │ │ │
    • column_names – An iterable of column names (strings).

    • │ │ │
    • horizontal_bar – The character used to represent a horizontal bar (a │ │ │ string).

    • │ │ │
    • vertical_bar – The character used to represent a vertical bar (a │ │ │ string).

    • │ │ │ @@ -1177,44 +1177,44 @@ │ │ │ humanfriendly.is_empty_line(text) │ │ │

      Check if a text is empty or contains only whitespace.

      │ │ │
      │ │ │
      Parameters:
      │ │ │

      text – The text to check for “emptiness” (a string).

      │ │ │
      │ │ │
      Returns:
      │ │ │ -

      True if the text is empty or contains only whitespace, │ │ │ -False otherwise.

      │ │ │ +

      True if the text is empty or contains only whitespace, │ │ │ +False otherwise.

      │ │ │
      │ │ │
      │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.is_string(value)
    │ │ │ -

    Check if a value is a basestring() (in Python 2) or str (in Python 3) object.

    │ │ │ +

    Check if a value is a python2:basestring() (in Python 2) or python3:str (in Python 3) object.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    value – The value to check.

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if the value is a string, False otherwise.

    │ │ │ +

    True if the value is a string, False otherwise.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.pluralize(count, singular, plural=None)
    │ │ │

    Combine a count with the singular or plural form of a word.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • count – The count (a number).

    • │ │ │
    • singular – The singular form of the word (a string).

    • │ │ │ -
    • plural – The plural form of the word (a string or None).

    • │ │ │ +
    • plural – The plural form of the word (a string or None).

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The count and singular or plural word concatenated (a string).

    │ │ │
    │ │ │
    │ │ │

    See pluralize_raw() for the logic underneath pluralize().

    │ │ │ @@ -1225,25 +1225,25 @@ │ │ │ humanfriendly.prompt_for_choice(choices, default=None, padding=True) │ │ │

    Prompt the user to select a choice from a group of options.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • choices – A sequence of strings with available options.

    • │ │ │
    • default – The default choice if the user simply presses Enter │ │ │ -(expected to be a string, defaults to None).

    • │ │ │ +(expected to be a string, defaults to None).

      │ │ │
    • padding – Refer to the documentation of │ │ │ prompt_for_input().

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The string corresponding to the user’s choice.

    │ │ │
    │ │ │
    Raises:
    │ │ │
      │ │ │ -
    • ValueError if choices is an empty sequence.

    • │ │ │ +
    • ValueError if choices is an empty sequence.

    • │ │ │
    • Any exceptions raised by │ │ │ retry_limit().

    • │ │ │
    • Any exceptions raised by │ │ │ prompt_for_input().

    • │ │ │
    │ │ │
    │ │ │
    │ │ │ @@ -1593,15 +1593,15 @@ │ │ │ humanfriendly.cli.ansi_strip(text, readline_hints=True) │ │ │

    Strip ANSI escape sequences from the given string.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text from which ANSI escape sequences should be removed (a │ │ │ string).

    • │ │ │ -
    • readline_hints – If True then readline_strip() is │ │ │ +

    • readline_hints – If True then readline_strip() is │ │ │ used to remove readline hints from the string.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The text without ANSI escape sequences (a string).

    │ │ │
    │ │ │
    │ │ │ @@ -1635,22 +1635,22 @@ │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.cli.enable_ansi_support()
    │ │ │

    Try to enable support for ANSI escape sequences (required on Windows).

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if ANSI is supported, False otherwise.

    │ │ │ +

    True if ANSI is supported, False otherwise.

    │ │ │
    │ │ │
    │ │ │

    This functions checks for the following supported configurations, in the │ │ │ given order:

    │ │ │
      │ │ │
    1. On Windows, if have_windows_native_ansi_support() confirms │ │ │ -native support for ANSI escape sequences ctypes will be used to │ │ │ +native support for ANSI escape sequences ctypes will be used to │ │ │ enable this support.

    2. │ │ │
    3. On Windows, if the environment variable $ANSICON is set nothing is │ │ │ done because it is assumed that support for ANSI escape sequences has │ │ │ already been enabled via ansicon.

    4. │ │ │
    5. On Windows, an attempt is made to import and initialize the Python │ │ │ package colorama instead (of course for this to work │ │ │ colorama has to be installed).

    6. │ │ │ @@ -1686,15 +1686,15 @@ │ │ │
      │ │ │

      Note

      │ │ │

      The find_terminal_size() function performs the steps │ │ │ above every time it is called, the result is not cached. This is │ │ │ because the size of a virtual terminal can change at any time and │ │ │ the result of find_terminal_size() should be correct.

      │ │ │

      Pre-emptive snarky comment: It’s possible to cache the result │ │ │ -of this function and use signal.SIGWINCH to │ │ │ +of this function and use signal.SIGWINCH to │ │ │ refresh the cached values!

      │ │ │

      Response: As a library I don’t consider it the role of the │ │ │ humanfriendly.terminal module to install a process wide │ │ │ signal handler …

      │ │ │
      │ │ │
    │ │ │ │ │ │ @@ -1702,16 +1702,16 @@ │ │ │
    │ │ │ humanfriendly.cli.format_length(num_metres, keep_width=False)
    │ │ │

    Format a metre count as a human readable length.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • num_metres – The length to format in metres (float / integer).

    • │ │ │ -
    • keep_widthTrue if trailing zeros should not be stripped, │ │ │ -False if they can be stripped.

    • │ │ │ +
    • keep_widthTrue if trailing zeros should not be stripped, │ │ │ +False if they can be stripped.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The corresponding human readable length (a string).

    │ │ │
    │ │ │
    │ │ │

    This function supports ranges from nanometres to kilometres.

    │ │ │ @@ -1734,16 +1734,16 @@ │ │ │
    │ │ │
    │ │ │ humanfriendly.cli.format_number(number, num_decimals=2)
    │ │ │

    Format a number as a string including thousands separators.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │ -
    • number – The number to format (a number like an int, │ │ │ -long or float).

    • │ │ │ +
    • number – The number to format (a number like an int, │ │ │ +long or float).

    • │ │ │
    • num_decimals – The number of decimals to render (2 by default). If no │ │ │ decimal places are required to represent the number │ │ │ they will be omitted regardless of this argument.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The formatted number (a string).

    │ │ │ @@ -1766,15 +1766,15 @@ │ │ │
    │ │ │
    │ │ │ humanfriendly.cli.format_pretty_table(data, column_names=None, horizontal_bar='-', vertical_bar='|')
    │ │ │

    Render a table using characters like dashes and vertical bars to emulate borders.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │ -
    • data – An iterable (e.g. a tuple() or list) │ │ │ +

    • data – An iterable (e.g. a tuple() or list) │ │ │ containing the rows of the table, where each row is an │ │ │ iterable containing the columns of the table (strings).

    • │ │ │
    • column_names – An iterable of column names (strings).

    • │ │ │
    • horizontal_bar – The character used to represent a horizontal bar (a │ │ │ string).

    • │ │ │
    • vertical_bar – The character used to represent a vertical bar (a │ │ │ string).

    • │ │ │ @@ -1826,18 +1826,18 @@ │ │ │
      │ │ │ humanfriendly.cli.format_size(num_bytes, keep_width=False, binary=False)
      │ │ │

      Format a byte count as a human readable file size.

      │ │ │
      │ │ │
      Parameters:
      │ │ │
        │ │ │
      • num_bytes – The size to format in bytes (an integer).

      • │ │ │ -
      • keep_widthTrue if trailing zeros should not be stripped, │ │ │ -False if they can be stripped.

      • │ │ │ -
      • binaryTrue to use binary multiples of bytes (base-2), │ │ │ -False to use decimal multiples of bytes (base-10).

      • │ │ │ +
      • keep_widthTrue if trailing zeros should not be stripped, │ │ │ +False if they can be stripped.

      • │ │ │ +
      • binaryTrue to use binary multiples of bytes (base-2), │ │ │ +False to use decimal multiples of bytes (base-10).

      • │ │ │
      │ │ │
      │ │ │
      Returns:
      │ │ │

      The corresponding human readable file size (a string).

      │ │ │
      │ │ │
      │ │ │

      This function knows how to format sizes in bytes, kilobytes, megabytes, │ │ │ @@ -1862,15 +1862,15 @@ │ │ │

      │ │ │
      │ │ │ humanfriendly.cli.format_smart_table(data, column_names)
      │ │ │

      Render tabular data using the most appropriate representation.

      │ │ │
      │ │ │
      Parameters:
      │ │ │
        │ │ │ -
      • data – An iterable (e.g. a tuple() or list) │ │ │ +

      • data – An iterable (e.g. a tuple() or list) │ │ │ containing the rows of the table, where each row is an │ │ │ iterable containing the columns of the table (strings).

      • │ │ │
      • column_names – An iterable of column names (strings).

      • │ │ │
      │ │ │
      │ │ │
      Returns:
      │ │ │

      The rendered table (a string).

      │ │ │ @@ -1894,17 +1894,17 @@ │ │ │
      │ │ │ humanfriendly.cli.format_timespan(num_seconds, detailed=False, max_units=3)
      │ │ │

      Format a timespan in seconds as a human readable string.

      │ │ │
      │ │ │
      Parameters:
      │ │ │
        │ │ │
      • num_seconds – Any value accepted by coerce_seconds().

      • │ │ │ -
      • detailed – If True milliseconds are represented separately │ │ │ +

      • detailed – If True milliseconds are represented separately │ │ │ instead of being represented as fractional seconds │ │ │ -(defaults to False).

      • │ │ │ +(defaults to False).

        │ │ │
      • max_units – The maximum number of units to show in the formatted time │ │ │ span (an integer, defaults to three).

      • │ │ │
      │ │ │
      │ │ │
      Returns:
      │ │ │

      The formatted timespan as a string.

      │ │ │
      │ │ │ @@ -1933,15 +1933,15 @@ │ │ │
      │ │ │
      │ │ │ humanfriendly.cli.output(text, *args, **kw)
      │ │ │

      Print a formatted message to the standard output stream.

      │ │ │

      For details about argument handling please refer to │ │ │ format().

      │ │ │

      Renders the message using format() and writes │ │ │ -the resulting string (followed by a newline) to sys.stdout using │ │ │ +the resulting string (followed by a newline) to sys.stdout using │ │ │ auto_encode().

      │ │ │
      │ │ │ │ │ │
      │ │ │
      │ │ │ humanfriendly.cli.parse_length(length)
      │ │ │

      Parse a human readable length and return the number of metres.

      │ │ │ @@ -1974,16 +1974,16 @@ │ │ │
      │ │ │ humanfriendly.cli.parse_size(size, binary=False)
      │ │ │

      Parse a human readable data size and return the number of bytes.

      │ │ │
      │ │ │
      Parameters:
      │ │ │
        │ │ │
      • size – The human readable file size to parse (a string).

      • │ │ │ -
      • binaryTrue to use binary multiples of bytes (base-2) for │ │ │ -ambiguous unit symbols and names, False to use │ │ │ +

      • binaryTrue to use binary multiples of bytes (base-2) for │ │ │ +ambiguous unit symbols and names, False to use │ │ │ decimal multiples of bytes (base-10).

      • │ │ │
      │ │ │
      │ │ │
      Returns:
      │ │ │

      The corresponding size in bytes (an integer).

      │ │ │
      │ │ │
      Raises:
      │ │ │ @@ -2028,143 +2028,143 @@ │ │ │
      │ │ │
      Parameters:
      │ │ │

      text – The usage message to print (a string).

      │ │ │
      │ │ │
      │ │ │

      This function does two things:

      │ │ │
        │ │ │ -
      1. If sys.stdout is connected to a terminal (see │ │ │ +

      2. If sys.stdout is connected to a terminal (see │ │ │ connected_to_terminal()) then the usage message is formatted │ │ │ using format_usage().

      3. │ │ │
      4. The usage message is shown using a pager (see show_pager()).

      5. │ │ │
      │ │ │
      │ │ │ │ │ │
      │ │ │
      │ │ │ humanfriendly.cli.warning(text, *args, **kw)
      │ │ │

      Show a warning message on the terminal.

      │ │ │

      For details about argument handling please refer to │ │ │ format().

      │ │ │

      Renders the message using format() and writes │ │ │ -the resulting string (followed by a newline) to sys.stderr using │ │ │ +the resulting string (followed by a newline) to sys.stderr using │ │ │ auto_encode().

      │ │ │ -

      If sys.stderr is connected to a terminal that supports colors, │ │ │ +

      If sys.stderr is connected to a terminal that supports colors, │ │ │ ansi_wrap() is used to color the message in a red font (to make │ │ │ the warning stand out from surrounding text).

      │ │ │
      │ │ │ │ │ │
    │ │ │
    │ │ │

    humanfriendly.compat

    │ │ │

    Compatibility with Python 2 and 3.

    │ │ │

    This module exposes aliases and functions that make it easier to write Python │ │ │ code that is compatible with Python 2 and Python 3.

    │ │ │
    │ │ │
    │ │ │ humanfriendly.compat.basestring
    │ │ │ -

    Alias for basestring() (in Python 2) or str │ │ │ +

    Alias for python2:basestring() (in Python 2) or python3:str │ │ │ (in Python 3). See also is_string().

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.compat.HTMLParser
    │ │ │ -

    Alias for HTMLParser.HTMLParser (in Python 2) or │ │ │ -html.parser.HTMLParser (in Python 3).

    │ │ │ +

    Alias for python2:HTMLParser.HTMLParser (in Python 2) or │ │ │ +python3:html.parser.HTMLParser (in Python 3).

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.compat.interactive_prompt
    │ │ │ -

    Alias for raw_input() (in Python 2) or │ │ │ -input() (in Python 3).

    │ │ │ +

    Alias for python2:raw_input() (in Python 2) or │ │ │ +python3:input() (in Python 3).

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.compat.StringIO
    │ │ │ -

    Alias for StringIO.StringIO (in Python 2) or │ │ │ -io.StringIO (in Python 3).

    │ │ │ +

    Alias for python2:StringIO.StringIO (in Python 2) or │ │ │ +python3:io.StringIO (in Python 3).

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.compat.unicode
    │ │ │ -

    Alias for unicode() (in Python 2) or str (in │ │ │ +

    Alias for python2:unicode() (in Python 2) or python3:str (in │ │ │ Python 3). See also coerce_string().

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.compat.monotonic
    │ │ │ -

    Alias for time.monotonic() (in Python 3.3 and higher) or │ │ │ +

    Alias for python3:time.monotonic() (in Python 3.3 and higher) or │ │ │ monotonic.monotonic() (a conditional dependency on older Python versions).

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.compat.coerce_string(value)
    │ │ │ -

    Coerce any value to a Unicode string (unicode() in Python 2 and str in Python 3).

    │ │ │ +

    Coerce any value to a Unicode string (python2:unicode() in Python 2 and python3:str in Python 3).

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    value – The value to coerce.

    │ │ │
    │ │ │
    Returns:
    │ │ │

    The value coerced to a Unicode string.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.compat.is_string(value)
    │ │ │ -

    Check if a value is a basestring() (in Python 2) or str (in Python 3) object.

    │ │ │ +

    Check if a value is a python2:basestring() (in Python 2) or python3:str (in Python 3) object.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    value – The value to check.

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if the value is a string, False otherwise.

    │ │ │ +

    True if the value is a string, False otherwise.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.compat.is_unicode(value)
    │ │ │ -

    Check if a value is a unicode() (in Python 2) or str (in Python 3) object.

    │ │ │ +

    Check if a value is a python2:unicode() (in Python 2) or python2:str (in Python 3) object.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    value – The value to check.

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if the value is a Unicode string, False otherwise.

    │ │ │ +

    True if the value is a Unicode string, False otherwise.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.compat.on_macos()
    │ │ │

    Check if we’re running on Apple MacOS.

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if running MacOS, False otherwise.

    │ │ │ +

    True if running MacOS, False otherwise.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.compat.on_windows()
    │ │ │

    Check if we’re running on the Microsoft Windows OS.

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if running Windows, False otherwise.

    │ │ │ +

    True if running Windows, False otherwise.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │

    humanfriendly.decorators

    │ │ │ @@ -2201,15 +2201,15 @@ │ │ │ │ │ │
    │ │ │
    │ │ │

    humanfriendly.deprecation

    │ │ │

    Support for deprecation warnings when importing names from old locations.

    │ │ │

    When software evolves, things tend to move around. This is usually detrimental │ │ │ to backwards compatibility (in Python this primarily manifests itself as │ │ │ -ImportError exceptions).

    │ │ │ +ImportError exceptions).

    │ │ │

    While backwards compatibility is very important, it should not get in the way │ │ │ of progress. It would be great to have the agility to move things around │ │ │ without breaking backwards compatibility.

    │ │ │

    This is where the humanfriendly.deprecation module comes in: It enables │ │ │ the definition of backwards compatible aliases that emit a deprecation warning │ │ │ when they are accessed.

    │ │ │

    The way it works is that it wraps the original module in an DeprecationProxy │ │ │ @@ -2274,15 +2274,15 @@ │ │ │

  • aliases – Each keyword argument defines an alias. The values │ │ │ are expected to be “dotted paths” (strings).

  • │ │ │ │ │ │ │ │ │ │ │ │

    The behavior of this function depends on whether the Sphinx documentation │ │ │ generator is active, because the use of DeprecationProxy to shadow the │ │ │ -real module in sys.modules has the unintended side effect of │ │ │ +real module in sys.modules has the unintended side effect of │ │ │ breaking autodoc support for :data: members (module variables).

    │ │ │

    To avoid breaking Sphinx the proxy object is omitted and instead the │ │ │ aliased names are injected into the original module namespace, to make sure │ │ │ that imports can be satisfied when the documentation is being rendered.

    │ │ │

    If you run into cyclic dependencies caused by define_aliases() when │ │ │ running Sphinx, you can try moving the call to define_aliases() to │ │ │ the bottom of the Python module you’re working on.

    │ │ │ @@ -2370,24 +2370,24 @@ │ │ │ humanfriendly.deprecation.is_method(function) │ │ │

    Check if the expected usage of the given function is as an instance method.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.deprecation.format(text, *args, **kw)
    │ │ │ -

    Format a string using the string formatting operator and/or str.format().

    │ │ │ +

    Format a string using the string formatting operator and/or str.format().

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text to format (a string).

    • │ │ │
    • args – Any positional arguments are interpolated into the text using │ │ │ the string formatting operator (%). If no positional │ │ │ arguments are given no interpolation is done.

    • │ │ │
    • kw – Any keyword arguments are interpolated into the text using the │ │ │ -str.format() function. If no keyword arguments are given │ │ │ +str.format() function. If no keyword arguments are given │ │ │ no interpolation is done.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The text with any positional and/or keyword arguments │ │ │ interpolated (a string).

    │ │ │
    │ │ │ @@ -2415,15 +2415,15 @@ │ │ │ the magic number is 42 │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ the magic numbers are 12 and 42 │ │ │ │ │ │ │ │ │ │ │ │
  • When you interpolate a single value and someone accidentally passes in a │ │ │ -tuple your code raises a TypeError. Because │ │ │ +tuple your code raises a TypeError. Because │ │ │ format() takes a variable number of arguments it always │ │ │ receives a tuple so this can never happen. Here’s an example:

    │ │ │
    >>> # How expecting to interpolate a single value can fail.
    │ │ │  >>> value = (12, 42)
    │ │ │  >>> print('the magic value is %s' % value)
    │ │ │  Traceback (most recent call last):
    │ │ │    File "<stdin>", line 1, in <module>
    │ │ │ @@ -2432,15 +2432,15 @@
    │ │ │  >>> print(format('the magic value is %s', value))
    │ │ │  the magic value is (12, 42)
    │ │ │  
    │ │ │
    │ │ │
  • │ │ │ │ │ │

    Why format() instead of the str.format() method?

    │ │ │ -

    When you’re doing complex string interpolation the str.format() │ │ │ +

    When you’re doing complex string interpolation the str.format() │ │ │ function results in more readable code, however I frequently find myself │ │ │ adding parentheses to force evaluation order. The format() function │ │ │ avoids this because of the relative priority between the comma and dot │ │ │ operators. Here’s an example:

    │ │ │
    >>> "{adjective} example" + " " + "(can't think of anything less {adjective})".format(adjective='silly')
    │ │ │  "{adjective} example (can't think of anything less silly)"
    │ │ │  >>> ("{adjective} example" + " " + "(can't think of anything less {adjective})").format(adjective='silly')
    │ │ │ @@ -2474,20 +2474,20 @@
    │ │ │  

    Raised by interactive prompts when they’ve received too many invalid inputs.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.prompts.prepare_friendly_prompts()
    │ │ │

    Make interactive prompts more user friendly.

    │ │ │ -

    The prompts presented by raw_input() (in Python 2) and │ │ │ -input() (in Python 3) are not very user friendly by │ │ │ +

    The prompts presented by python2:raw_input() (in Python 2) and │ │ │ +python3:input() (in Python 3) are not very user friendly by │ │ │ default, for example the cursor keys (, , and │ │ │ ) and the Home and End keys enter characters instead │ │ │ of performing the action you would expect them to. By simply importing the │ │ │ -readline module these prompts become much friendlier (as mentioned │ │ │ +readline module these prompts become much friendlier (as mentioned │ │ │ in the Python standard library documentation).

    │ │ │

    This function is called by the other functions in this module to enable │ │ │ user friendly prompts.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ @@ -2514,25 +2514,25 @@ │ │ │ humanfriendly.prompts.prompt_for_choice(choices, default=None, padding=True)
    │ │ │

    Prompt the user to select a choice from a group of options.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • choices – A sequence of strings with available options.

    • │ │ │
    • default – The default choice if the user simply presses Enter │ │ │ -(expected to be a string, defaults to None).

    • │ │ │ +(expected to be a string, defaults to None).

      │ │ │
    • padding – Refer to the documentation of │ │ │ prompt_for_input().

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The string corresponding to the user’s choice.

    │ │ │
    │ │ │
    Raises:
    │ │ │
      │ │ │ -
    • ValueError if choices is an empty sequence.

    • │ │ │ +
    • ValueError if choices is an empty sequence.

    • │ │ │
    • Any exceptions raised by │ │ │ retry_limit().

    • │ │ │
    • Any exceptions raised by │ │ │ prompt_for_input().

    • │ │ │
    │ │ │
    │ │ │
    │ │ │ @@ -2574,37 +2574,37 @@ │ │ │
    │ │ │ humanfriendly.prompts.prompt_for_confirmation(question, default=None, padding=True)
    │ │ │

    Prompt the user for confirmation.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • question – The text that explains what the user is confirming (a string).

    • │ │ │ -
    • default – The default value (a boolean) or None.

    • │ │ │ +
    • default – The default value (a boolean) or None.

    • │ │ │
    • padding – Refer to the documentation of prompt_for_input().

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

      │ │ │ -
    • If the user enters ‘yes’ or ‘y’ then True is returned.

    • │ │ │ -
    • If the user enters ‘no’ or ‘n’ then False is returned.

    • │ │ │ +
    • If the user enters ‘yes’ or ‘y’ then True is returned.

    • │ │ │ +
    • If the user enters ‘no’ or ‘n’ then False is returned.

    • │ │ │
    • If the user doesn’t enter any text or standard input is not │ │ │ connected to a terminal (which makes it impossible to prompt │ │ │ the user) the value of the keyword argument default is │ │ │ -returned (if that value is not None).

    • │ │ │ +returned (if that value is not None).

      │ │ │
    │ │ │

    │ │ │
    │ │ │
    Raises:
    │ │ │
    │ │ │
    │ │ │
    │ │ │ -

    When default is False and the user doesn’t enter any text an │ │ │ +

    When default is False and the user doesn’t enter any text an │ │ │ error message is printed and the prompt is repeated:

    │ │ │
    >>> prompt_for_confirmation("Are you sure?")
    │ │ │  
    │ │ │   Are you sure? [y/n]
    │ │ │  
    │ │ │   Error: Please enter 'yes' or 'no' (there's no default choice).
    │ │ │  
    │ │ │ @@ -2632,31 +2632,31 @@
    │ │ │  
      │ │ │
    • question – An explanation of what is expected from the user (a string).

    • │ │ │
    • default – The return value if the user doesn’t enter any text or │ │ │ standard input is not connected to a terminal (which │ │ │ makes it impossible to prompt the user).

    • │ │ │
    • padding – Render empty lines before and after the prompt to make it │ │ │ stand out from the surrounding text? (a boolean, defaults │ │ │ -to True)

    • │ │ │ +to True)

      │ │ │
    • strip – Strip leading/trailing whitespace from the user’s reply?

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The text entered by the user (a string) or the value of the │ │ │ default argument.

    │ │ │
    │ │ │
    Raises:
    │ │ │
      │ │ │ -
    • KeyboardInterrupt when the program is │ │ │ +

    • KeyboardInterrupt when the program is │ │ │ interrupted while the prompt is active, for example │ │ │ because the user presses Control-C.

    • │ │ │ -
    • EOFError when reading from standard input │ │ │ +

    • EOFError when reading from standard input │ │ │ fails, for example because the user presses Control-D or │ │ │ because the standard input stream is redirected (only if │ │ │ -default is None).

    • │ │ │ +default is None).

      │ │ │
    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ @@ -2684,15 +2684,15 @@ │ │ │ humanfriendly.prompts.ansi_strip(text, readline_hints=True)
    │ │ │

    Strip ANSI escape sequences from the given string.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text from which ANSI escape sequences should be removed (a │ │ │ string).

    • │ │ │ -
    • readline_hints – If True then readline_strip() is │ │ │ +

    • readline_hints – If True then readline_strip() is │ │ │ used to remove readline hints from the string.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The text without ANSI escape sequences (a string).

    │ │ │
    │ │ │
    │ │ │ @@ -2729,16 +2729,16 @@ │ │ │ humanfriendly.prompts.concatenate(items, conjunction='and', serial_comma=False) │ │ │

    Concatenate a list of items in a human friendly way.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • items – A sequence of strings.

    • │ │ │
    • conjunction – The word to use before the last item (a string, defaults to “and”).

    • │ │ │ -
    • serial_commaTrue to use a serial comma, False otherwise │ │ │ -(defaults to False).

    • │ │ │ +
    • serial_commaTrue to use a serial comma, False otherwise │ │ │ +(defaults to False).

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    A single string.

    │ │ │
    │ │ │
    │ │ │
    >>> from humanfriendly.text import concatenate
    │ │ │ @@ -2751,37 +2751,37 @@
    │ │ │  
    │ │ │
    │ │ │ humanfriendly.prompts.connected_to_terminal(stream=None)
    │ │ │

    Check if a stream is connected to a terminal.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    stream – The stream to check (a file-like object, │ │ │ -defaults to sys.stdout).

    │ │ │ +defaults to sys.stdout).

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if the stream is connected to a terminal, │ │ │ -False otherwise.

    │ │ │ +

    True if the stream is connected to a terminal, │ │ │ +False otherwise.

    │ │ │
    │ │ │
    │ │ │

    See also terminal_supports_colors().

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.prompts.format(text, *args, **kw)
    │ │ │ -

    Format a string using the string formatting operator and/or str.format().

    │ │ │ +

    Format a string using the string formatting operator and/or str.format().

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text to format (a string).

    • │ │ │
    • args – Any positional arguments are interpolated into the text using │ │ │ the string formatting operator (%). If no positional │ │ │ arguments are given no interpolation is done.

    • │ │ │
    • kw – Any keyword arguments are interpolated into the text using the │ │ │ -str.format() function. If no keyword arguments are given │ │ │ +str.format() function. If no keyword arguments are given │ │ │ no interpolation is done.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The text with any positional and/or keyword arguments │ │ │ interpolated (a string).

    │ │ │
    │ │ │ @@ -2809,15 +2809,15 @@ │ │ │ the magic number is 42 │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ the magic numbers are 12 and 42 │ │ │
    │ │ │
    │ │ │ │ │ │
  • When you interpolate a single value and someone accidentally passes in a │ │ │ -tuple your code raises a TypeError. Because │ │ │ +tuple your code raises a TypeError. Because │ │ │ format() takes a variable number of arguments it always │ │ │ receives a tuple so this can never happen. Here’s an example:

    │ │ │
    >>> # How expecting to interpolate a single value can fail.
    │ │ │  >>> value = (12, 42)
    │ │ │  >>> print('the magic value is %s' % value)
    │ │ │  Traceback (most recent call last):
    │ │ │    File "<stdin>", line 1, in <module>
    │ │ │ @@ -2826,15 +2826,15 @@
    │ │ │  >>> print(format('the magic value is %s', value))
    │ │ │  the magic value is (12, 42)
    │ │ │  
    │ │ │
    │ │ │
  • │ │ │ │ │ │

    Why format() instead of the str.format() method?

    │ │ │ -

    When you’re doing complex string interpolation the str.format() │ │ │ +

    When you’re doing complex string interpolation the str.format() │ │ │ function results in more readable code, however I frequently find myself │ │ │ adding parentheses to force evaluation order. The format() function │ │ │ avoids this because of the relative priority between the comma and dot │ │ │ operators. Here’s an example:

    │ │ │
    >>> "{adjective} example" + " " + "(can't think of anything less {adjective})".format(adjective='silly')
    │ │ │  "{adjective} example (can't think of anything less silly)"
    │ │ │  >>> ("{adjective} example" + " " + "(can't think of anything less {adjective})").format(adjective='silly')
    │ │ │ @@ -2851,36 +2851,36 @@
    │ │ │  
    │ │ │
    │ │ │ humanfriendly.prompts.terminal_supports_colors(stream=None)
    │ │ │

    Check if a stream is connected to a terminal that supports ANSI escape sequences.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    stream – The stream to check (a file-like object, │ │ │ -defaults to sys.stdout).

    │ │ │ +defaults to sys.stdout).

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if the terminal supports ANSI escape sequences, │ │ │ -False otherwise.

    │ │ │ +

    True if the terminal supports ANSI escape sequences, │ │ │ +False otherwise.

    │ │ │
    │ │ │
    │ │ │

    This function was originally inspired by the implementation of │ │ │ django.core.management.color.supports_color() │ │ │ but has since evolved significantly.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.prompts.warning(text, *args, **kw)
    │ │ │

    Show a warning message on the terminal.

    │ │ │

    For details about argument handling please refer to │ │ │ format().

    │ │ │

    Renders the message using format() and writes │ │ │ -the resulting string (followed by a newline) to sys.stderr using │ │ │ +the resulting string (followed by a newline) to sys.stderr using │ │ │ auto_encode().

    │ │ │ -

    If sys.stderr is connected to a terminal that supports colors, │ │ │ +

    If sys.stderr is connected to a terminal that supports colors, │ │ │ ansi_wrap() is used to color the message in a red font (to make │ │ │ the warning stand out from surrounding text).

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │

    humanfriendly.sphinx

    │ │ │ @@ -3107,15 +3107,15 @@ │ │ │ │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.sphinx.dedent(text, *args, **kw)
    │ │ │

    Dedent a string (remove common leading whitespace from all lines).

    │ │ │

    Removes common leading whitespace from all lines in the string using │ │ │ -textwrap.dedent(), removes leading and trailing empty lines using │ │ │ +textwrap.dedent(), removes leading and trailing empty lines using │ │ │ trim_empty_lines() and interpolates any arguments using │ │ │ format().

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text to dedent (a string).

    • │ │ │
    • args – Any positional arguments are interpolated using format().

    • │ │ │ @@ -3133,24 +3133,24 @@ │ │ │ for data file and code generation tasks (where newlines and indentation are │ │ │ very significant).

      │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.sphinx.format(text, *args, **kw)
    │ │ │ -

    Format a string using the string formatting operator and/or str.format().

    │ │ │ +

    Format a string using the string formatting operator and/or str.format().

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text to format (a string).

    • │ │ │
    • args – Any positional arguments are interpolated into the text using │ │ │ the string formatting operator (%). If no positional │ │ │ arguments are given no interpolation is done.

    • │ │ │
    • kw – Any keyword arguments are interpolated into the text using the │ │ │ -str.format() function. If no keyword arguments are given │ │ │ +str.format() function. If no keyword arguments are given │ │ │ no interpolation is done.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The text with any positional and/or keyword arguments │ │ │ interpolated (a string).

    │ │ │
    │ │ │ @@ -3178,15 +3178,15 @@ │ │ │ the magic number is 42 │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ the magic numbers are 12 and 42 │ │ │ │ │ │ │ │ │ │ │ │
  • When you interpolate a single value and someone accidentally passes in a │ │ │ -tuple your code raises a TypeError. Because │ │ │ +tuple your code raises a TypeError. Because │ │ │ format() takes a variable number of arguments it always │ │ │ receives a tuple so this can never happen. Here’s an example:

    │ │ │
    >>> # How expecting to interpolate a single value can fail.
    │ │ │  >>> value = (12, 42)
    │ │ │  >>> print('the magic value is %s' % value)
    │ │ │  Traceback (most recent call last):
    │ │ │    File "<stdin>", line 1, in <module>
    │ │ │ @@ -3195,15 +3195,15 @@
    │ │ │  >>> print(format('the magic value is %s', value))
    │ │ │  the magic value is (12, 42)
    │ │ │  
    │ │ │
    │ │ │
  • │ │ │ │ │ │

    Why format() instead of the str.format() method?

    │ │ │ -

    When you’re doing complex string interpolation the str.format() │ │ │ +

    When you’re doing complex string interpolation the str.format() │ │ │ function results in more readable code, however I frequently find myself │ │ │ adding parentheses to force evaluation order. The format() function │ │ │ avoids this because of the relative priority between the comma and dot │ │ │ operators. Here’s an example:

    │ │ │
    >>> "{adjective} example" + " " + "(can't think of anything less {adjective})".format(adjective='silly')
    │ │ │  "{adjective} example (can't think of anything less silly)"
    │ │ │  >>> ("{adjective} example" + " " + "(can't think of anything less {adjective})").format(adjective='silly')
    │ │ │ @@ -3281,15 +3281,15 @@
    │ │ │  
    │ │ │
    │ │ │ humanfriendly.tables.format_pretty_table(data, column_names=None, horizontal_bar='-', vertical_bar='|')
    │ │ │

    Render a table using characters like dashes and vertical bars to emulate borders.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │ -
    • data – An iterable (e.g. a tuple() or list) │ │ │ +

    • data – An iterable (e.g. a tuple() or list) │ │ │ containing the rows of the table, where each row is an │ │ │ iterable containing the columns of the table (strings).

    • │ │ │
    • column_names – An iterable of column names (strings).

    • │ │ │
    • horizontal_bar – The character used to represent a horizontal bar (a │ │ │ string).

    • │ │ │
    • vertical_bar – The character used to represent a vertical bar (a │ │ │ string).

    • │ │ │ @@ -3340,15 +3340,15 @@ │ │ │
      │ │ │
      │ │ │ humanfriendly.tables.format_robust_table(data, column_names)
      │ │ │

      Render tabular data with one column per line (allowing columns with line breaks).

      │ │ │
      │ │ │
      Parameters:
      │ │ │
        │ │ │ -
      • data – An iterable (e.g. a tuple() or list) │ │ │ +

      • data – An iterable (e.g. a tuple() or list) │ │ │ containing the rows of the table, where each row is an │ │ │ iterable containing the columns of the table (strings).

      • │ │ │
      • column_names – An iterable of column names (strings).

      • │ │ │
      │ │ │
      │ │ │
      Returns:
      │ │ │

      The rendered table (a string).

      │ │ │ @@ -3395,15 +3395,15 @@ │ │ │
      │ │ │
      │ │ │ humanfriendly.tables.format_rst_table(data, column_names=None)
      │ │ │

      Render a table in reStructuredText format.

      │ │ │
      │ │ │
      Parameters:
      │ │ │
        │ │ │ -
      • data – An iterable (e.g. a tuple() or list) │ │ │ +

      • data – An iterable (e.g. a tuple() or list) │ │ │ containing the rows of the table, where each row is an │ │ │ iterable containing the columns of the table (strings).

      • │ │ │
      • column_names – An iterable of column names (strings).

      • │ │ │
      │ │ │
      │ │ │
      Returns:
      │ │ │

      The rendered table (a string).

      │ │ │ @@ -3436,15 +3436,15 @@ │ │ │
      │ │ │
      │ │ │ humanfriendly.tables.format_smart_table(data, column_names)
      │ │ │

      Render tabular data using the most appropriate representation.

      │ │ │
      │ │ │
      Parameters:
      │ │ │
        │ │ │ -
      • data – An iterable (e.g. a tuple() or list) │ │ │ +

      • data – An iterable (e.g. a tuple() or list) │ │ │ containing the rows of the table, where each row is an │ │ │ iterable containing the columns of the table (strings).

      • │ │ │
      • column_names – An iterable of column names (strings).

      • │ │ │
      │ │ │
      │ │ │
      Returns:
      │ │ │

      The rendered table (a string).

      │ │ │ @@ -3469,15 +3469,15 @@ │ │ │ humanfriendly.tables.ansi_strip(text, readline_hints=True) │ │ │

      Strip ANSI escape sequences from the given string.

      │ │ │
      │ │ │
      Parameters:
      │ │ │
        │ │ │
      • text – The text from which ANSI escape sequences should be removed (a │ │ │ string).

      • │ │ │ -
      • readline_hints – If True then readline_strip() is │ │ │ +

      • readline_hints – If True then readline_strip() is │ │ │ used to remove readline hints from the string.

      • │ │ │
      │ │ │
      │ │ │
      Returns:
      │ │ │

      The text without ANSI escape sequences (a string).

      │ │ │
      │ │ │
      │ │ │ @@ -3525,15 +3525,15 @@ │ │ │
      │ │ │
      │ │ │
      │ │ │ │ │ │
      │ │ │
      │ │ │ humanfriendly.tables.coerce_string(value)
      │ │ │ -

      Coerce any value to a Unicode string (unicode() in Python 2 and str in Python 3).

      │ │ │ +

      Coerce any value to a Unicode string (python2:unicode() in Python 2 and python3:str in Python 3).

      │ │ │
      │ │ │
      Parameters:
      │ │ │

      value – The value to coerce.

      │ │ │
      │ │ │
      Returns:
      │ │ │

      The value coerced to a Unicode string.

      │ │ │
      │ │ │ @@ -3559,34 +3559,34 @@ │ │ │
      │ │ │

      Note

      │ │ │

      The find_terminal_size() function performs the steps │ │ │ above every time it is called, the result is not cached. This is │ │ │ because the size of a virtual terminal can change at any time and │ │ │ the result of find_terminal_size() should be correct.

      │ │ │

      Pre-emptive snarky comment: It’s possible to cache the result │ │ │ -of this function and use signal.SIGWINCH to │ │ │ +of this function and use signal.SIGWINCH to │ │ │ refresh the cached values!

      │ │ │

      Response: As a library I don’t consider it the role of the │ │ │ humanfriendly.terminal module to install a process wide │ │ │ signal handler …

      │ │ │
      │ │ │
      │ │ │ │ │ │
      │ │ │
      │ │ │ humanfriendly.tables.terminal_supports_colors(stream=None)
      │ │ │

      Check if a stream is connected to a terminal that supports ANSI escape sequences.

      │ │ │
      │ │ │
      Parameters:
      │ │ │

      stream – The stream to check (a file-like object, │ │ │ -defaults to sys.stdout).

      │ │ │ +defaults to sys.stdout).

      │ │ │
      │ │ │
      Returns:
      │ │ │ -

      True if the terminal supports ANSI escape sequences, │ │ │ -False otherwise.

      │ │ │ +

      True if the terminal supports ANSI escape sequences, │ │ │ +False otherwise.

      │ │ │
      │ │ │
      │ │ │

      This function was originally inspired by the implementation of │ │ │ django.core.management.color.supports_color() │ │ │ but has since evolved significantly.

      │ │ │
      │ │ │ │ │ │ @@ -3602,15 +3602,15 @@ │ │ │

      This module was originally developed for use on UNIX systems, but since then │ │ │ Windows 10 gained native support for ANSI escape sequences and this module was │ │ │ enhanced to recognize and support this. For details please refer to the │ │ │ enable_ansi_support() function.

      │ │ │
      │ │ │

      Note

      │ │ │

      Deprecated names

      │ │ │ -

      The following aliases exist to preserve backwards compatibility, however a DeprecationWarning is triggered when they are accessed, because these aliases will be removed in a future release.

      │ │ │ +

      The following aliases exist to preserve backwards compatibility, however a DeprecationWarning is triggered when they are accessed, because these aliases will be removed in a future release.

      │ │ │
      │ │ │
      │ │ │ humanfriendly.terminal.find_meta_variables
      │ │ │

      Alias for humanfriendly.usage.find_meta_variables.

      │ │ │
      │ │ │ │ │ │
      │ │ │ @@ -3724,15 +3724,15 @@ │ │ │ humanfriendly.terminal.ansi_strip(text, readline_hints=True) │ │ │

      Strip ANSI escape sequences from the given string.

      │ │ │
      │ │ │
      Parameters:
      │ │ │
        │ │ │
      • text – The text from which ANSI escape sequences should be removed (a │ │ │ string).

      • │ │ │ -
      • readline_hints – If True then readline_strip() is │ │ │ +

      • readline_hints – If True then readline_strip() is │ │ │ used to remove readline hints from the string.

      • │ │ │
      │ │ │
      │ │ │
      Returns:
      │ │ │

      The text without ANSI escape sequences (a string).

      │ │ │
      │ │ │
      │ │ │ @@ -3749,36 +3749,36 @@ │ │ │
        │ │ │
      • The name of a color (one of the strings ‘black’, ‘red’, │ │ │ ‘green’, ‘yellow’, ‘blue’, ‘magenta’, ‘cyan’ or ‘white’).

      • │ │ │
      • An integer that refers to the 256 color mode palette.

      • │ │ │
      • A tuple or list with three integers representing an RGB │ │ │ (red, green, blue) value.

      • │ │ │
      │ │ │ -

      The value None (the default) means no escape │ │ │ +

      The value None (the default) means no escape │ │ │ sequence to switch color will be emitted.

      │ │ │

      │ │ │
    • background – The background color (see the description │ │ │ of the color argument).

    • │ │ │
    • bright – Use high intensity colors instead of default colors │ │ │ -(a boolean, defaults to False).

    • │ │ │ -
    • readline_hints – If True then readline_wrap() is │ │ │ +(a boolean, defaults to False).

    • │ │ │ +
    • readline_hints – If True then readline_wrap() is │ │ │ applied to the generated ANSI escape sequences (the │ │ │ -default is False).

    • │ │ │ +default is False).

      │ │ │
    • kw – Any additional keyword arguments are expected to match a key │ │ │ in the ANSI_TEXT_STYLES dictionary. If the argument’s │ │ │ -value evaluates to True the respective style will be │ │ │ +value evaluates to True the respective style will be │ │ │ enabled.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The ANSI escape sequences to enable the requested text styles or │ │ │ an empty string if no styles were requested.

    │ │ │
    │ │ │
    Raises:
    │ │ │ -

    ValueError when an invalid color name is given.

    │ │ │ +

    ValueError when an invalid color name is given.

    │ │ │
    │ │ │
    │ │ │

    Even though only eight named colors are supported, the use of bright=True │ │ │ and faint=True increases the number of available colors to around 24 (it │ │ │ may be slightly lower, for example because faint black is just black).

    │ │ │

    Support for 8-bit colors

    │ │ │

    In release 4.7 support for 256 color mode was added. While this │ │ │ @@ -3847,28 +3847,28 @@ │ │ │

    │ │ │ humanfriendly.terminal.auto_encode(stream, text, *args, **kw)
    │ │ │

    Reliably write Unicode strings to the terminal.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • stream – The file-like object to write to (a value like │ │ │ -sys.stdout or sys.stderr).

    • │ │ │ +sys.stdout or sys.stderr).

      │ │ │
    • text – The text to write to the stream (a string).

    • │ │ │
    • args – Refer to format().

    • │ │ │
    • kw – Refer to format().

    • │ │ │
    │ │ │
    │ │ │
    │ │ │

    Renders the text using format() and writes it │ │ │ -to the given stream. If an UnicodeEncodeError is │ │ │ +to the given stream. If an UnicodeEncodeError is │ │ │ encountered in doing so, the text is encoded using DEFAULT_ENCODING │ │ │ and the write is retried. The reasoning behind this rather blunt approach │ │ │ is that it’s preferable to get output on the command line in the wrong │ │ │ encoding then to have the Python program blow up with a │ │ │ -UnicodeEncodeError exception.

    │ │ │ +UnicodeEncodeError exception.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.terminal.clean_terminal_output(text)
    │ │ │

    Clean up the terminal output of a command.

    │ │ │
    │ │ │ @@ -3880,26 +3880,26 @@ │ │ │
    │ │ │
    │ │ │

    This function emulates the effect of backspace (0x08), carriage return │ │ │ (0x0D) and line feed (0x0A) characters and the ANSI ‘erase line’ escape │ │ │ sequence on interactive terminals. It’s intended to clean up command output │ │ │ that was originally meant to be rendered on an interactive terminal and │ │ │ that has been captured using e.g. the script program [3] or the │ │ │ -pty module [4].

    │ │ │ +pty module [4].

    │ │ │ │ │ │

    Some caveats about the use of this function:

    │ │ │
      │ │ │ @@ -3919,38 +3919,38 @@ │ │ │
      │ │ │
      │ │ │ humanfriendly.terminal.connected_to_terminal(stream=None)
      │ │ │

      Check if a stream is connected to a terminal.

      │ │ │
      │ │ │
      Parameters:
      │ │ │

      stream – The stream to check (a file-like object, │ │ │ -defaults to sys.stdout).

      │ │ │ +defaults to sys.stdout).

      │ │ │
      │ │ │
      Returns:
      │ │ │ -

      True if the stream is connected to a terminal, │ │ │ -False otherwise.

      │ │ │ +

      True if the stream is connected to a terminal, │ │ │ +False otherwise.

      │ │ │
      │ │ │
      │ │ │

      See also terminal_supports_colors().

      │ │ │
      │ │ │ │ │ │
      │ │ │
      │ │ │ humanfriendly.terminal.enable_ansi_support()
      │ │ │

      Try to enable support for ANSI escape sequences (required on Windows).

      │ │ │
      │ │ │
      Returns:
      │ │ │ -

      True if ANSI is supported, False otherwise.

      │ │ │ +

      True if ANSI is supported, False otherwise.

      │ │ │
      │ │ │
      │ │ │

      This functions checks for the following supported configurations, in the │ │ │ given order:

      │ │ │
        │ │ │
      1. On Windows, if have_windows_native_ansi_support() confirms │ │ │ -native support for ANSI escape sequences ctypes will be used to │ │ │ +native support for ANSI escape sequences ctypes will be used to │ │ │ enable this support.

      2. │ │ │
      3. On Windows, if the environment variable $ANSICON is set nothing is │ │ │ done because it is assumed that support for ANSI escape sequences has │ │ │ already been enabled via ansicon.

      4. │ │ │
      5. On Windows, an attempt is made to import and initialize the Python │ │ │ package colorama instead (of course for this to work │ │ │ colorama has to be installed).

      6. │ │ │ @@ -3986,26 +3986,26 @@ │ │ │
        │ │ │

        Note

        │ │ │

        The find_terminal_size() function performs the steps │ │ │ above every time it is called, the result is not cached. This is │ │ │ because the size of a virtual terminal can change at any time and │ │ │ the result of find_terminal_size() should be correct.

        │ │ │

        Pre-emptive snarky comment: It’s possible to cache the result │ │ │ -of this function and use signal.SIGWINCH to │ │ │ +of this function and use signal.SIGWINCH to │ │ │ refresh the cached values!

        │ │ │

        Response: As a library I don’t consider it the role of the │ │ │ humanfriendly.terminal module to install a process wide │ │ │ signal handler …

        │ │ │
        │ │ │
      │ │ │ │ │ │
      │ │ │
      │ │ │ humanfriendly.terminal.find_terminal_size_using_ioctl(stream)
      │ │ │ -

      Find the terminal size using fcntl.ioctl().

      │ │ │ +

      Find the terminal size using fcntl.ioctl().

      │ │ │
      │ │ │
      Parameters:
      │ │ │

      stream – A stream connected to the terminal (a file object with a │ │ │ fileno attribute).

      │ │ │
      │ │ │
      Returns:
      │ │ │

      A tuple of two integers with the line and column count.

      │ │ │ @@ -4069,41 +4069,41 @@ │ │ │ │ │ │
      │ │ │
      │ │ │ humanfriendly.terminal.have_windows_native_ansi_support()
      │ │ │

      Check if we’re running on a Windows 10 release with native support for ANSI escape sequences.

      │ │ │
      │ │ │
      Returns:
      │ │ │ -

      True if so, False otherwise.

      │ │ │ +

      True if so, False otherwise.

      │ │ │
      │ │ │
      │ │ │

      The cached() decorator is used as a minor │ │ │ performance optimization. Semantically this should have zero impact because │ │ │ the answer doesn’t change in the lifetime of a computer process.

      │ │ │
      │ │ │ │ │ │
      │ │ │
      │ │ │ humanfriendly.terminal.message(text, *args, **kw)
      │ │ │

      Print a formatted message to the standard error stream.

      │ │ │

      For details about argument handling please refer to │ │ │ format().

      │ │ │

      Renders the message using format() and writes │ │ │ -the resulting string (followed by a newline) to sys.stderr using │ │ │ +the resulting string (followed by a newline) to sys.stderr using │ │ │ auto_encode().

      │ │ │
      │ │ │ │ │ │
      │ │ │
      │ │ │ humanfriendly.terminal.output(text, *args, **kw)
      │ │ │

      Print a formatted message to the standard output stream.

      │ │ │

      For details about argument handling please refer to │ │ │ format().

      │ │ │

      Renders the message using format() and writes │ │ │ -the resulting string (followed by a newline) to sys.stdout using │ │ │ +the resulting string (followed by a newline) to sys.stdout using │ │ │ auto_encode().

      │ │ │
      │ │ │ │ │ │
      │ │ │
      │ │ │ humanfriendly.terminal.readline_strip(expr)
      │ │ │

      Remove readline hints from a string.

      │ │ │ @@ -4141,15 +4141,15 @@ │ │ │
    • formatted_text – The text to print to the terminal (a string).

    • │ │ │
    • encoding – The name of the text encoding used to encode the formatted │ │ │ text if the formatted text is a Unicode string (a string, │ │ │ defaults to DEFAULT_ENCODING).

    • │ │ │
    │ │ │
    │ │ │
    │ │ │ -

    When connected_to_terminal() returns True a pager is used │ │ │ +

    When connected_to_terminal() returns True a pager is used │ │ │ to show the text on the terminal, otherwise the text is printed directly │ │ │ without invoking a pager.

    │ │ │

    The use of a pager helps to avoid the wall of text effect where the user │ │ │ has to scroll up to see where the output began (not very user friendly).

    │ │ │

    Refer to get_pager_command() for details about the command line │ │ │ that’s used to invoke the pager.

    │ │ │
    │ │ │ @@ -4157,19 +4157,19 @@ │ │ │
    │ │ │
    │ │ │ humanfriendly.terminal.terminal_supports_colors(stream=None)
    │ │ │

    Check if a stream is connected to a terminal that supports ANSI escape sequences.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    stream – The stream to check (a file-like object, │ │ │ -defaults to sys.stdout).

    │ │ │ +defaults to sys.stdout).

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if the terminal supports ANSI escape sequences, │ │ │ -False otherwise.

    │ │ │ +

    True if the terminal supports ANSI escape sequences, │ │ │ +False otherwise.

    │ │ │
    │ │ │
    │ │ │

    This function was originally inspired by the implementation of │ │ │ django.core.management.color.supports_color() │ │ │ but has since evolved significantly.

    │ │ │
    │ │ │ │ │ │ @@ -4180,31 +4180,31 @@ │ │ │
    │ │ │
    Parameters:
    │ │ │

    text – The usage message to print (a string).

    │ │ │
    │ │ │
    │ │ │

    This function does two things:

    │ │ │
      │ │ │ -
    1. If sys.stdout is connected to a terminal (see │ │ │ +

    2. If sys.stdout is connected to a terminal (see │ │ │ connected_to_terminal()) then the usage message is formatted │ │ │ using format_usage().

    3. │ │ │
    4. The usage message is shown using a pager (see show_pager()).

    5. │ │ │
    │ │ │ │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.terminal.warning(text, *args, **kw)
    │ │ │

    Show a warning message on the terminal.

    │ │ │

    For details about argument handling please refer to │ │ │ format().

    │ │ │

    Renders the message using format() and writes │ │ │ -the resulting string (followed by a newline) to sys.stderr using │ │ │ +the resulting string (followed by a newline) to sys.stderr using │ │ │ auto_encode().

    │ │ │ -

    If sys.stderr is connected to a terminal that supports colors, │ │ │ +

    If sys.stderr is connected to a terminal that supports colors, │ │ │ ansi_wrap() is used to color the message in a red font (to make │ │ │ the warning stand out from surrounding text).

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.terminal.cached(function)
    │ │ │ @@ -4228,15 +4228,15 @@ │ │ │ function arguments, which is not currently the case.

    │ │ │ │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.terminal.coerce_string(value)
    │ │ │ -

    Coerce any value to a Unicode string (unicode() in Python 2 and str in Python 3).

    │ │ │ +

    Coerce any value to a Unicode string (python2:unicode() in Python 2 and python3:str in Python 3).

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    value – The value to coerce.

    │ │ │
    │ │ │
    Returns:
    │ │ │

    The value coerced to a Unicode string.

    │ │ │
    │ │ │ @@ -4248,16 +4248,16 @@ │ │ │ humanfriendly.terminal.concatenate(items, conjunction='and', serial_comma=False) │ │ │

    Concatenate a list of items in a human friendly way.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • items – A sequence of strings.

    • │ │ │
    • conjunction – The word to use before the last item (a string, defaults to “and”).

    • │ │ │ -
    • serial_commaTrue to use a serial comma, False otherwise │ │ │ -(defaults to False).

    • │ │ │ +
    • serial_commaTrue to use a serial comma, False otherwise │ │ │ +(defaults to False).

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    A single string.

    │ │ │
    │ │ │
    │ │ │
    >>> from humanfriendly.text import concatenate
    │ │ │ @@ -4278,15 +4278,15 @@
    │ │ │  
  • aliases – Each keyword argument defines an alias. The values │ │ │ are expected to be “dotted paths” (strings).

  • │ │ │ │ │ │
    │ │ │
    │ │ │

    The behavior of this function depends on whether the Sphinx documentation │ │ │ generator is active, because the use of DeprecationProxy to shadow the │ │ │ -real module in sys.modules has the unintended side effect of │ │ │ +real module in sys.modules has the unintended side effect of │ │ │ breaking autodoc support for :data: members (module variables).

    │ │ │

    To avoid breaking Sphinx the proxy object is omitted and instead the │ │ │ aliased names are injected into the original module namespace, to make sure │ │ │ that imports can be satisfied when the documentation is being rendered.

    │ │ │

    If you run into cyclic dependencies caused by define_aliases() when │ │ │ running Sphinx, you can try moving the call to define_aliases() to │ │ │ the bottom of the Python module you’re working on.

    │ │ │ @@ -4309,24 +4309,24 @@ │ │ │ format such options as --option=ARG. The text ARG in this example │ │ │ is the meta variable.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.terminal.format(text, *args, **kw)
    │ │ │ -

    Format a string using the string formatting operator and/or str.format().

    │ │ │ +

    Format a string using the string formatting operator and/or str.format().

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text to format (a string).

    • │ │ │
    • args – Any positional arguments are interpolated into the text using │ │ │ the string formatting operator (%). If no positional │ │ │ arguments are given no interpolation is done.

    • │ │ │
    • kw – Any keyword arguments are interpolated into the text using the │ │ │ -str.format() function. If no keyword arguments are given │ │ │ +str.format() function. If no keyword arguments are given │ │ │ no interpolation is done.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The text with any positional and/or keyword arguments │ │ │ interpolated (a string).

    │ │ │
    │ │ │ @@ -4354,15 +4354,15 @@ │ │ │ the magic number is 42 │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ the magic numbers are 12 and 42 │ │ │ │ │ │ │ │ │ │ │ │
  • When you interpolate a single value and someone accidentally passes in a │ │ │ -tuple your code raises a TypeError. Because │ │ │ +tuple your code raises a TypeError. Because │ │ │ format() takes a variable number of arguments it always │ │ │ receives a tuple so this can never happen. Here’s an example:

    │ │ │
    >>> # How expecting to interpolate a single value can fail.
    │ │ │  >>> value = (12, 42)
    │ │ │  >>> print('the magic value is %s' % value)
    │ │ │  Traceback (most recent call last):
    │ │ │    File "<stdin>", line 1, in <module>
    │ │ │ @@ -4371,15 +4371,15 @@
    │ │ │  >>> print(format('the magic value is %s', value))
    │ │ │  the magic value is (12, 42)
    │ │ │  
    │ │ │
    │ │ │
  • │ │ │ │ │ │

    Why format() instead of the str.format() method?

    │ │ │ -

    When you’re doing complex string interpolation the str.format() │ │ │ +

    When you’re doing complex string interpolation the str.format() │ │ │ function results in more readable code, however I frequently find myself │ │ │ adding parentheses to force evaluation order. The format() function │ │ │ avoids this because of the relative priority between the comma and dot │ │ │ operators. Here’s an example:

    │ │ │
    >>> "{adjective} example" + " " + "(can't think of anything less {adjective})".format(adjective='silly')
    │ │ │  "{adjective} example (can't think of anything less silly)"
    │ │ │  >>> ("{adjective} example" + " " + "(can't think of anything less {adjective})").format(adjective='silly')
    │ │ │ @@ -4435,32 +4435,32 @@
    │ │ │  details about the conversion process (like which tags are supported) and an
    │ │ │  example with a screenshot.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.terminal.is_unicode(value)
    │ │ │ -

    Check if a value is a unicode() (in Python 2) or str (in Python 3) object.

    │ │ │ +

    Check if a value is a python2:unicode() (in Python 2) or python2:str (in Python 3) object.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    value – The value to check.

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if the value is a Unicode string, False otherwise.

    │ │ │ +

    True if the value is a Unicode string, False otherwise.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.terminal.on_windows()
    │ │ │

    Check if we’re running on the Microsoft Windows OS.

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if running Windows, False otherwise.

    │ │ │ +

    True if running Windows, False otherwise.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.terminal.which(cmd, mode=1, path=None)
    │ │ │ @@ -4524,15 +4524,15 @@ │ │ │ the uppercase symbols are highlighted in light blue with an underline.

    │ │ │
  • <div>, <p> and <pre> tags are considered block level tags │ │ │ and are wrapped in vertical whitespace to prevent their content from │ │ │ “running into” surrounding text. This may cause runs of multiple empty │ │ │ lines to be emitted. As a workaround the __call__() method │ │ │ will automatically call compact_empty_lines() on the generated │ │ │ output before returning it to the caller. Of course this won’t work │ │ │ -when output is set to something like sys.stdout.

  • │ │ │ +when output is set to something like sys.stdout.

    │ │ │
  • <br> is converted to a single plain text line break.

  • │ │ │ │ │ │

    Implementation notes:

    │ │ │
      │ │ │
    • A list of dictionaries with style information is used as a stack where │ │ │ new styling can be pushed and a pop will restore the previous styling. │ │ │ When new styling is pushed, it is merged with (but overrides) the current │ │ │ @@ -4566,15 +4566,15 @@ │ │ │

    • callback – Optional keyword argument to specify a function that │ │ │ will be called to process text fragments before they │ │ │ are emitted on the output stream. Note that link text │ │ │ and preformatted text fragments are not processed by │ │ │ this callback.

    • │ │ │
    • output – Optional keyword argument to redirect the output to the │ │ │ given file-like object. If this is not given a new │ │ │ -StringIO object is created.

    • │ │ │ +StringIO object is created.

      │ │ │
    │ │ │ │ │ │
    │ │ │ │ │ │ │ │ │
    │ │ │
    │ │ │ @@ -4582,15 +4582,15 @@ │ │ │

    Reset the parser, convert some HTML and get the text with ANSI escape sequences.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    data – The HTML to convert to text (a string).

    │ │ │
    │ │ │
    Returns:
    │ │ │

    The converted text (only in case output is │ │ │ -a StringIO object).

    │ │ │ +a StringIO object).

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ property current_style
    │ │ │ @@ -4610,15 +4610,15 @@ │ │ │
    │ │ │
    │ │ │ emit_style(style=None)
    │ │ │

    Emit an ANSI escape sequence for the given or current style to the output stream.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    style – A dictionary with arguments for ansi_style() or │ │ │ -None, in which case the style at the top of the │ │ │ +None, in which case the style at the top of the │ │ │ stack is emitted.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ @@ -4697,15 +4697,15 @@ │ │ │ parse_color(value)
    │ │ │

    Convert a CSS color to something that ansi_style() understands.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    value – A string like rgb(1,2,3), #AABBCC or yellow.

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    A color value supported by ansi_style() or None.

    │ │ │ +

    A color value supported by ansi_style() or None.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ push_styles(**changes)
    │ │ │ @@ -4746,15 +4746,15 @@ │ │ │ │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ reset()
    │ │ │

    Reset the state of the HTML parser and ANSI converter.

    │ │ │ -

    When output is a StringIO object a new │ │ │ +

    When output is a StringIO object a new │ │ │ instance will be created (and the old one garbage collected).

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ urls_match(a, b)
    │ │ │

    Compare two URLs for equality using normalize_url().

    │ │ │ @@ -4762,15 +4762,15 @@ │ │ │
    Parameters:
    │ │ │
      │ │ │
    • a – A string containing a URL.

    • │ │ │
    • b – A string containing a URL.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if the URLs are the same, False otherwise.

    │ │ │ +

    True if the URLs are the same, False otherwise.

    │ │ │
    │ │ │
    │ │ │

    This method is used by handle_endtag() to omit the URL of a │ │ │ hyperlink (<a href="...">) when the link text is that same URL.

    │ │ │
    │ │ │ │ │ │ │ │ │ @@ -4806,36 +4806,36 @@ │ │ │ │ │ │ -

    The value None (the default) means no escape │ │ │ +

    The value None (the default) means no escape │ │ │ sequence to switch color will be emitted.

    │ │ │

    │ │ │
  • background – The background color (see the description │ │ │ of the color argument).

  • │ │ │
  • bright – Use high intensity colors instead of default colors │ │ │ -(a boolean, defaults to False).

  • │ │ │ -
  • readline_hints – If True then readline_wrap() is │ │ │ +(a boolean, defaults to False).

  • │ │ │ +
  • readline_hints – If True then readline_wrap() is │ │ │ applied to the generated ANSI escape sequences (the │ │ │ -default is False).

  • │ │ │ +default is False).

    │ │ │
  • kw – Any additional keyword arguments are expected to match a key │ │ │ in the ANSI_TEXT_STYLES dictionary. If the argument’s │ │ │ -value evaluates to True the respective style will be │ │ │ +value evaluates to True the respective style will be │ │ │ enabled.

  • │ │ │ │ │ │ │ │ │
    Returns:
    │ │ │

    The ANSI escape sequences to enable the requested text styles or │ │ │ an empty string if no styles were requested.

    │ │ │
    │ │ │
    Raises:
    │ │ │ -

    ValueError when an invalid color name is given.

    │ │ │ +

    ValueError when an invalid color name is given.

    │ │ │
    │ │ │ │ │ │

    Even though only eight named colors are supported, the use of bright=True │ │ │ and faint=True increases the number of available colors to around 24 (it │ │ │ may be slightly lower, for example because faint black is just black).

    │ │ │

    Support for 8-bit colors

    │ │ │

    In release 4.7 support for 256 color mode was added. While this │ │ │ @@ -4951,35 +4951,35 @@ │ │ │ when the spinner ends.

    │ │ │
    │ │ │
    │ │ │ class humanfriendly.terminal.spinners.AutomaticSpinner(label, show_time=True)
    │ │ │

    Show a spinner on the terminal that automatically starts animating.

    │ │ │

    This class shows a spinner on the terminal (just like Spinner │ │ │ does) that automatically starts animating. This class should be used as a │ │ │ -context manager using the with statement. The animation │ │ │ +context manager using the with statement. The animation │ │ │ continues for as long as the context is active.

    │ │ │

    AutomaticSpinner provides an alternative to Spinner │ │ │ for situations where it is not practical for the caller to periodically │ │ │ call step() to advance the animation, e.g. because │ │ │ you’re performing a blocking call and don’t fancy implementing threading or │ │ │ subprocess handling just to provide some user feedback.

    │ │ │ -

    This works using the multiprocessing module by spawning a │ │ │ +

    This works using the multiprocessing module by spawning a │ │ │ subprocess to render the spinner while the main process is busy doing │ │ │ -something more useful. By using the with statement you’re │ │ │ +something more useful. By using the with statement you’re │ │ │ guaranteed that the subprocess is properly terminated at the appropriate │ │ │ time.

    │ │ │
    │ │ │
    │ │ │ __init__(label, show_time=True)
    │ │ │

    Initialize an automatic spinner.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • label – The label for the spinner (a string).

    • │ │ │ -
    • show_time – If this is True (the default) then the spinner │ │ │ +

    • show_time – If this is True (the default) then the spinner │ │ │ shows elapsed time.

    • │ │ │
    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │ @@ -5015,21 +5015,21 @@ │ │ │
    │ │ │
    │ │ │ __init__(**options)
    │ │ │

    Initialize a Spinner object.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │ -
    • label – The label for the spinner (a string or None, defaults to │ │ │ -None).

    • │ │ │ -
    • total – The expected number of steps (an integer or None). If this is │ │ │ +

    • label – The label for the spinner (a string or None, defaults to │ │ │ +None).

    • │ │ │ +
    • total – The expected number of steps (an integer or None). If this is │ │ │ provided the spinner will show a progress percentage.

    • │ │ │
    • stream – The output stream to show the spinner on (a file-like object, │ │ │ -defaults to sys.stderr).

    • │ │ │ -
    • interactiveTrue to enable rendering of the spinner, False to │ │ │ +defaults to sys.stderr).

    • │ │ │ +
    • interactiveTrue to enable rendering of the spinner, False to │ │ │ disable (defaults to the result of stream.isatty()).

    • │ │ │
    • timer – A Timer object (optional). If this is given the spinner │ │ │ will show the elapsed time according to the timer.

    • │ │ │
    • interval – The spinner will be updated at most once every this many seconds │ │ │ (a floating point number, defaults to MINIMUM_INTERVAL).

    • │ │ │
    • glyphs – A list of strings with single characters that are drawn in the same │ │ │ place in succession to implement a simple animated effect (defaults │ │ │ @@ -5164,24 +5164,24 @@ │ │ │ │ │ │ │ │ │

    │ │ │ │ │ │
    │ │ │
    │ │ │

    humanfriendly.testing

    │ │ │ -

    Utility classes and functions that make it easy to write unittest compatible test suites.

    │ │ │ +

    Utility classes and functions that make it easy to write unittest compatible test suites.

    │ │ │

    Over the years I’ve developed the habit of writing test suites for Python │ │ │ -projects using the unittest module. During those years I’ve come to know │ │ │ +projects using the unittest module. During those years I’ve come to know │ │ │ pytest and in fact I use pytest to run my test suites (due to │ │ │ its much better error reporting) but I’ve yet to publish a test suite that │ │ │ requires pytest. I have several reasons for doing so:

    │ │ │ │ │ │
    │ │ │
    │ │ │ exception humanfriendly.testing.CallableTimedOut
    │ │ │

    Raised by retry() when the timeout expires.

    │ │ │ @@ -5208,15 +5208,15 @@ │ │ │
    │ │ │ │ │ │ │ │ │ │ │ │
    │ │ │
    │ │ │ class humanfriendly.testing.CaptureOutput(merged=False, input='', enabled=True)
    │ │ │ -

    Context manager that captures what’s written to sys.stdout and sys.stderr.

    │ │ │ +

    Context manager that captures what’s written to sys.stdout and sys.stderr.

    │ │ │
    │ │ │
    │ │ │ stdin
    │ │ │

    The StringIO object used to feed the standard input stream.

    │ │ │
    │ │ │ │ │ │
    │ │ │ @@ -5234,38 +5234,38 @@ │ │ │
    │ │ │
    │ │ │ __init__(merged=False, input='', enabled=True)
    │ │ │

    Initialize a CaptureOutput object.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │ -
    • mergedTrue to merge the streams, │ │ │ -False to capture them separately.

    • │ │ │ -
    • input – The data that reads from sys.stdin │ │ │ +

    • mergedTrue to merge the streams, │ │ │ +False to capture them separately.

    • │ │ │ +
    • input – The data that reads from sys.stdin │ │ │ should return (a string).

    • │ │ │ -
    • enabledTrue to enable capturing (the default), │ │ │ -False otherwise. This makes it easy to │ │ │ +

    • enabledTrue to enable capturing (the default), │ │ │ +False otherwise. This makes it easy to │ │ │ unconditionally use CaptureOutput in │ │ │ -a with block while preserving the │ │ │ +a with block while preserving the │ │ │ choice to opt out of capturing output.

    • │ │ │
    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ __enter__()
    │ │ │ -

    Start capturing what’s written to sys.stdout and sys.stderr.

    │ │ │ +

    Start capturing what’s written to sys.stdout and sys.stderr.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ __exit__(exc_type=None, exc_value=None, traceback=None)
    │ │ │ -

    Stop capturing what’s written to sys.stdout and sys.stderr.

    │ │ │ +

    Stop capturing what’s written to sys.stdout and sys.stderr.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ get_lines()
    │ │ │

    Get the contents of stdout split into separate lines.

    │ │ │
    │ │ │ @@ -5275,15 +5275,15 @@ │ │ │ get_text() │ │ │

    Get the contents of stdout as a Unicode string.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ getvalue()
    │ │ │ -

    Get the text written to sys.stdout.

    │ │ │ +

    Get the text written to sys.stdout.

    │ │ │
    │ │ │ │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ class humanfriendly.testing.ContextManager
    │ │ │ @@ -5310,16 +5310,16 @@ │ │ │ TemporaryDirectory context managers.

    │ │ │
    │ │ │
    │ │ │ __init__(isolated=False)
    │ │ │

    Initialize a CustomSearchPath object.

    │ │ │
    │ │ │
    Parameters:
    │ │ │ -

    isolatedTrue to clear the original search path, │ │ │ -False to add the temporary directory to the │ │ │ +

    isolatedTrue to clear the original search path, │ │ │ +False to add the temporary directory to the │ │ │ start of the search path.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ @@ -5338,15 +5338,15 @@ │ │ │ __exit__(exc_type=None, exc_value=None, traceback=None)
    │ │ │

    Deactivate the custom $PATH.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ property current_search_path
    │ │ │ -

    The value of $PATH or os.defpath (a string).

    │ │ │ +

    The value of $PATH or os.defpath (a string).

    │ │ │
    │ │ │ │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ class humanfriendly.testing.MockedProgram(name, returncode=0, script=None)
    │ │ │ @@ -5359,15 +5359,15 @@ │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • name – The name of the program (a string).

    • │ │ │
    • returncode – The return code that the program should emit (a │ │ │ number, defaults to zero).

    • │ │ │
    • script – Shell script code to include in the mocked program (a │ │ │ -string or None). This can be used to mock a │ │ │ +string or None). This can be used to mock a │ │ │ program that is expected to generate specific output.

    • │ │ │
    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │ @@ -5384,26 +5384,26 @@ │ │ │ │ │ │
    │ │ │
    │ │ │ __exit__(*args, **kw)
    │ │ │

    Ensure that the mock program was run.

    │ │ │
    │ │ │
    Raises:
    │ │ │ -

    AssertionError when │ │ │ +

    AssertionError when │ │ │ the mock program hasn’t been run.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ class humanfriendly.testing.PatchedAttribute(obj, name, value)
    │ │ │ -

    Context manager that temporary replaces an object attribute using setattr().

    │ │ │ +

    Context manager that temporary replaces an object attribute using setattr().

    │ │ │
    │ │ │
    │ │ │ __init__(obj, name, value)
    │ │ │

    Initialize a PatchedAttribute object.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │ @@ -5433,15 +5433,15 @@ │ │ │
    │ │ │ │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ class humanfriendly.testing.PatchedItem(obj, item, value)
    │ │ │ -

    Context manager that temporary replaces an object item using __setitem__().

    │ │ │ +

    Context manager that temporary replaces an object item using __setitem__().

    │ │ │
    │ │ │
    │ │ │ __init__(obj, item, value)
    │ │ │

    Initialize a PatchedItem object.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │ @@ -5471,56 +5471,56 @@ │ │ │
    │ │ │ │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ class humanfriendly.testing.TemporaryDirectory(**options)
    │ │ │ -

    Easy temporary directory creation & cleanup using the with statement.

    │ │ │ +

    Easy temporary directory creation & cleanup using the with statement.

    │ │ │

    Here’s an example of how to use this:

    │ │ │
    with TemporaryDirectory() as directory:
    │ │ │      # Do something useful here.
    │ │ │      assert os.path.isdir(directory)
    │ │ │  
    │ │ │
    │ │ │
    │ │ │
    │ │ │ __init__(**options)
    │ │ │

    Initialize a TemporaryDirectory object.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    options – Any keyword arguments are passed on to │ │ │ -tempfile.mkdtemp().

    │ │ │ +tempfile.mkdtemp().

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ __enter__()
    │ │ │ -

    Create the temporary directory using tempfile.mkdtemp().

    │ │ │ +

    Create the temporary directory using tempfile.mkdtemp().

    │ │ │
    │ │ │
    Returns:
    │ │ │

    The pathname of the directory (a string).

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ __exit__(exc_type=None, exc_value=None, traceback=None)
    │ │ │ -

    Cleanup the temporary directory using shutil.rmtree().

    │ │ │ +

    Cleanup the temporary directory using shutil.rmtree().

    │ │ │
    │ │ │ │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ class humanfriendly.testing.TestCase(*args, **kw)
    │ │ │ -

    Subclass of unittest.TestCase with automatic logging and other miscellaneous features.

    │ │ │ +

    Subclass of unittest.TestCase with automatic logging and other miscellaneous features.

    │ │ │
    │ │ │
    │ │ │ __init__(*args, **kw)
    │ │ │

    Initialize a TestCase object.

    │ │ │

    Any positional and/or keyword arguments are passed on to the │ │ │ initializer of the superclass.

    │ │ │
    │ │ │ @@ -5531,41 +5531,41 @@ │ │ │

    Automatically configure logging to the terminal.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    log_level – Refer to configure_logging().

    │ │ │
    │ │ │
    │ │ │

    The setUp() method is automatically called by │ │ │ -unittest.TestCase before each test method starts. │ │ │ +unittest.TestCase before each test method starts. │ │ │ It does two things:

    │ │ │
      │ │ │
    • Logging to the terminal is configured using │ │ │ configure_logging().

    • │ │ │
    • Before the test method starts a newline is emitted, to separate the │ │ │ name of the test method (which will be printed to the terminal by │ │ │ -unittest or pytest) from the first line of logging │ │ │ +unittest or pytest) from the first line of logging │ │ │ output that the test method is likely going to generate.

    • │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.testing.configure_logging(log_level=logging.DEBUG)
    │ │ │

    Automatically configure logging to the terminal.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    log_level – The log verbosity (a number, defaults │ │ │ -to logging.DEBUG).

    │ │ │ +to logging.DEBUG).

    │ │ │
    │ │ │
    │ │ │ -

    When coloredlogs is installed coloredlogs.install() will be │ │ │ +

    When coloredlogs is installed coloredlogs.install() will be │ │ │ used to configure logging to the terminal. When this fails with an │ │ │ -ImportError then logging.basicConfig() is used │ │ │ +ImportError then logging.basicConfig() is used │ │ │ as a fall back.

    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.testing.make_dirs(pathname)
    │ │ │

    Create missing directories.

    │ │ │ @@ -5580,28 +5580,28 @@ │ │ │
    │ │ │ humanfriendly.testing.retry(func, timeout=60, exc_type=AssertionError)
    │ │ │

    Retry a function until assertions no longer fail.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • func – A callable. When the callable returns │ │ │ -False it will also be retried.

    • │ │ │ +False it will also be retried.

      │ │ │
    • timeout – The number of seconds after which to abort (a number, │ │ │ defaults to 60).

    • │ │ │
    • exc_type – The type of exceptions to retry (defaults │ │ │ -to AssertionError).

    • │ │ │ +to AssertionError).

      │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The value returned by func.

    │ │ │
    │ │ │
    Raises:
    │ │ │

    Once the timeout has expired retry() will raise the │ │ │ previously retried assertion error. When func keeps returning │ │ │ -False until timeout expires CallableTimedOut │ │ │ +False until timeout expires CallableTimedOut │ │ │ will be raised.

    │ │ │
    │ │ │
    │ │ │

    This function sleeps between retries to avoid claiming CPU cycles we don’t │ │ │ need. It starts by sleeping for 0.1 second but adjusts this to one second │ │ │ as the number of retries grows.

    │ │ │
    │ │ │ @@ -5612,26 +5612,26 @@ │ │ │

    Test a command line entry point.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • entry_point – The function that implements the command line interface │ │ │ (a callable).

    • │ │ │
    • arguments – Any positional arguments (strings) become the command │ │ │ -line arguments (sys.argv items 1-N).

    • │ │ │ +line arguments (sys.argv items 1-N).

      │ │ │
    • options

      The following keyword arguments are supported:

      │ │ │
      │ │ │
      capture

      Whether to use CaptureOutput. Defaults │ │ │ -to True but can be disabled by passing │ │ │ -False instead.

      │ │ │ +to True but can be disabled by passing │ │ │ +False instead.

      │ │ │
      │ │ │
      input

      Refer to CaptureOutput.

      │ │ │
      │ │ │
      merged

      Refer to CaptureOutput.

      │ │ │
      │ │ │ -
      program_name

      Used to set sys.argv item 0.

      │ │ │ +
      program_name

      Used to set sys.argv item 0.

      │ │ │
      │ │ │
      │ │ │

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    A tuple with two values:

    │ │ │ @@ -5643,19 +5643,19 @@ │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.testing.skip_on_raise(*exc_types)
    │ │ │ -

    Decorate a test function to translation specific exception types to unittest.SkipTest.

    │ │ │ +

    Decorate a test function to translation specific exception types to unittest.SkipTest.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    exc_types – One or more positional arguments give the exception │ │ │ -types to be translated to unittest.SkipTest.

    │ │ │ +types to be translated to unittest.SkipTest.

    │ │ │
    │ │ │
    Returns:
    │ │ │

    A decorator function specialized to exc_types.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │ @@ -5685,15 +5685,15 @@ │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • length – The length of the string to be generated (a number or a │ │ │ tuple with two numbers). If this is a tuple then a random │ │ │ number between the two numbers given in the tuple is used.

    • │ │ │
    • characters – The characters to be used (a string, defaults │ │ │ -to string.ascii_letters).

    • │ │ │ +to string.ascii_letters).

      │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    A random string.

    │ │ │
    │ │ │
    │ │ │

    The random_string() function is very useful in test suites; by the │ │ │ @@ -5766,16 +5766,16 @@ │ │ │ humanfriendly.text.concatenate(items, conjunction='and', serial_comma=False) │ │ │

    Concatenate a list of items in a human friendly way.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • items – A sequence of strings.

    • │ │ │
    • conjunction – The word to use before the last item (a string, defaults to “and”).

    • │ │ │ -
    • serial_commaTrue to use a serial comma, False otherwise │ │ │ -(defaults to False).

    • │ │ │ +
    • serial_commaTrue to use a serial comma, False otherwise │ │ │ +(defaults to False).

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    A single string.

    │ │ │
    │ │ │
    │ │ │
    >>> from humanfriendly.text import concatenate
    │ │ │ @@ -5786,15 +5786,15 @@
    │ │ │  
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.text.dedent(text, *args, **kw)
    │ │ │

    Dedent a string (remove common leading whitespace from all lines).

    │ │ │

    Removes common leading whitespace from all lines in the string using │ │ │ -textwrap.dedent(), removes leading and trailing empty lines using │ │ │ +textwrap.dedent(), removes leading and trailing empty lines using │ │ │ trim_empty_lines() and interpolates any arguments using │ │ │ format().

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text to dedent (a string).

    • │ │ │
    • args – Any positional arguments are interpolated using format().

    • │ │ │ @@ -5812,24 +5812,24 @@ │ │ │ for data file and code generation tasks (where newlines and indentation are │ │ │ very significant).

      │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.text.format(text, *args, **kw)
    │ │ │ -

    Format a string using the string formatting operator and/or str.format().

    │ │ │ +

    Format a string using the string formatting operator and/or str.format().

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text to format (a string).

    • │ │ │
    • args – Any positional arguments are interpolated into the text using │ │ │ the string formatting operator (%). If no positional │ │ │ arguments are given no interpolation is done.

    • │ │ │
    • kw – Any keyword arguments are interpolated into the text using the │ │ │ -str.format() function. If no keyword arguments are given │ │ │ +str.format() function. If no keyword arguments are given │ │ │ no interpolation is done.

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The text with any positional and/or keyword arguments │ │ │ interpolated (a string).

    │ │ │
    │ │ │ @@ -5857,15 +5857,15 @@ │ │ │ the magic number is 42 │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ the magic numbers are 12 and 42 │ │ │ │ │ │ │ │ │ │ │ │
  • When you interpolate a single value and someone accidentally passes in a │ │ │ -tuple your code raises a TypeError. Because │ │ │ +tuple your code raises a TypeError. Because │ │ │ format() takes a variable number of arguments it always │ │ │ receives a tuple so this can never happen. Here’s an example:

    │ │ │
    >>> # How expecting to interpolate a single value can fail.
    │ │ │  >>> value = (12, 42)
    │ │ │  >>> print('the magic value is %s' % value)
    │ │ │  Traceback (most recent call last):
    │ │ │    File "<stdin>", line 1, in <module>
    │ │ │ @@ -5874,15 +5874,15 @@
    │ │ │  >>> print(format('the magic value is %s', value))
    │ │ │  the magic value is (12, 42)
    │ │ │  
    │ │ │
    │ │ │
  • │ │ │ │ │ │

    Why format() instead of the str.format() method?

    │ │ │ -

    When you’re doing complex string interpolation the str.format() │ │ │ +

    When you’re doing complex string interpolation the str.format() │ │ │ function results in more readable code, however I frequently find myself │ │ │ adding parentheses to force evaluation order. The format() function │ │ │ avoids this because of the relative priority between the comma and dot │ │ │ operators. Here’s an example:

    │ │ │
    >>> "{adjective} example" + " " + "(can't think of anything less {adjective})".format(adjective='silly')
    │ │ │  "{adjective} example (can't think of anything less silly)"
    │ │ │  >>> ("{adjective} example" + " " + "(can't think of anything less {adjective})").format(adjective='silly')
    │ │ │ @@ -5908,31 +5908,31 @@
    │ │ │  (defaults to the - character).

    │ │ │ │ │ │
    │ │ │
    Returns:
    │ │ │

    The slug text, for example some-random-text.

    │ │ │
    │ │ │
    Raises:
    │ │ │ -

    ValueError when the provided │ │ │ +

    ValueError when the provided │ │ │ text is nonempty but results in an empty slug.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.text.is_empty_line(text)
    │ │ │

    Check if a text is empty or contains only whitespace.

    │ │ │
    │ │ │
    Parameters:
    │ │ │

    text – The text to check for “emptiness” (a string).

    │ │ │
    │ │ │
    Returns:
    │ │ │ -

    True if the text is empty or contains only whitespace, │ │ │ -False otherwise.

    │ │ │ +

    True if the text is empty or contains only whitespace, │ │ │ +False otherwise.

    │ │ │
    │ │ │
    │ │ │
    │ │ │ │ │ │
    │ │ │
    │ │ │ humanfriendly.text.join_lines(text)
    │ │ │ @@ -5957,15 +5957,15 @@ │ │ │ humanfriendly.text.pluralize(count, singular, plural=None) │ │ │

    Combine a count with the singular or plural form of a word.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • count – The count (a number).

    • │ │ │
    • singular – The singular form of the word (a string).

    • │ │ │ -
    • plural – The plural form of the word (a string or None).

    • │ │ │ +
    • plural – The plural form of the word (a string or None).

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The count and singular or plural word concatenated (a string).

    │ │ │
    │ │ │
    │ │ │

    See pluralize_raw() for the logic underneath pluralize().

    │ │ │ @@ -5976,15 +5976,15 @@ │ │ │ humanfriendly.text.pluralize_raw(count, singular, plural=None) │ │ │

    Select the singular or plural form of a word based on a count.

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • count – The count (a number).

    • │ │ │
    • singular – The singular form of the word (a string).

    • │ │ │ -
    • plural – The plural form of the word (a string or None).

    • │ │ │ +
    • plural – The plural form of the word (a string or None).

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The singular or plural form of the word (a string).

    │ │ │
    │ │ │
    │ │ │

    When the given count is exactly 1.0 the singular form of the word is │ │ │ @@ -6002,15 +6002,15 @@ │ │ │

    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • length – The length of the string to be generated (a number or a │ │ │ tuple with two numbers). If this is a tuple then a random │ │ │ number between the two numbers given in the tuple is used.

    • │ │ │
    • characters – The characters to be used (a string, defaults │ │ │ -to string.ascii_letters).

    • │ │ │ +to string.ascii_letters).

      │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    A random string.

    │ │ │
    │ │ │
    │ │ │

    The random_string() function is very useful in test suites; by the │ │ │ @@ -6029,15 +6029,15 @@ │ │ │

  • delimiter – The delimiter to split on (a string).

  • │ │ │ │ │ │
    │ │ │
    Returns:
    │ │ │

    A list of zero or more nonempty strings.

    │ │ │
    │ │ │
    │ │ │ -

    Here’s the default behavior of Python’s built in str.split() │ │ │ +

    Here’s the default behavior of Python’s built in str.split() │ │ │ function:

    │ │ │
    >>> 'foo,bar, baz,'.split(',')
    │ │ │  ['foo', 'bar', ' baz', '']
    │ │ │  
    │ │ │
    │ │ │

    In contrast here’s the default behavior of the split() function:

    │ │ │
    >>> from humanfriendly.text import split
    │ │ │ @@ -6298,23 +6298,23 @@
    │ │ │  
    │ │ │  
    │ │ │  
    │ │ │
    │ │ │ humanfriendly.usage.dedent(text, *args, **kw)
    │ │ │

    Dedent a string (remove common leading whitespace from all lines).

    │ │ │

    Removes common leading whitespace from all lines in the string using │ │ │ -textwrap.dedent(), removes leading and trailing empty lines using │ │ │ +textwrap.dedent(), removes leading and trailing empty lines using │ │ │ trim_empty_lines() and interpolates any arguments using │ │ │ -format().

    │ │ │ +format().

    │ │ │
    │ │ │
    Parameters:
    │ │ │
      │ │ │
    • text – The text to dedent (a string).

    • │ │ │ -
    • args – Any positional arguments are interpolated using format().

    • │ │ │ -
    • kw – Any keyword arguments are interpolated using format().

    • │ │ │ +
    • args – Any positional arguments are interpolated using format().

    • │ │ │ +
    • kw – Any keyword arguments are interpolated using format().

    • │ │ │
    │ │ │
    │ │ │
    Returns:
    │ │ │

    The dedented text (a string).

    │ │ │
    │ │ │
    │ │ │

    The compact() function’s documentation contains an example of how I │ │ │ ├── html2text {} │ │ │ │ @@ -40,15 +40,15 @@ │ │ │ │ thehumanfriendlypackage in your project, make sure to at least pin the major │ │ │ │ version number in order to avoid unexpected surprises. │ │ │ │ ********** _hh_uu_mm_aa_nn_ff_rr_ii_ee_nn_dd_ll_yy_?¶ ********** │ │ │ │ The main module of thehumanfriendlypackage. │ │ │ │ Note │ │ │ │ Deprecated names │ │ │ │ The following aliases exist to preserve backwards compatibility, however a │ │ │ │ -_D_e_p_r_e_c_a_t_i_o_n_W_a_r_n_i_n_g is triggered when they are accessed, because these aliases │ │ │ │ +DeprecationWarning is triggered when they are accessed, because these aliases │ │ │ │ will be removed in a future release. │ │ │ │ humanfriendly.format_table_¶ │ │ │ │ Alias for _h_u_m_a_n_f_r_i_e_n_d_l_y_._t_a_b_l_e_s_._f_o_r_m_a_t___p_r_e_t_t_y___t_a_b_l_e. │ │ │ │ humanfriendly.compact_¶ │ │ │ │ Alias for _h_u_m_a_n_f_r_i_e_n_d_l_y_._t_e_x_t_._c_o_m_p_a_c_t. │ │ │ │ humanfriendly.concatenate_¶ │ │ │ │ Alias for _h_u_m_a_n_f_r_i_e_n_d_l_y_._t_e_x_t_._c_o_n_c_a_t_e_n_a_t_e. │ │ │ │ @@ -160,39 +160,39 @@ │ │ │ │ Easy to use timer to keep track of long during operations. │ │ │ │ __init__(ssttaarrtt__ttiimmee==NNoonnee, rreessuummaabbllee==FFaallssee)_¶ │ │ │ │ Remember the time when the _T_i_m_e_r was created. │ │ │ │ Parameters: │ │ │ │ * ssttaarrtt__ttiimmee – The start time (a float, defaults to the │ │ │ │ current time). │ │ │ │ * rreessuummaabbllee – Create a resumable timer (defaults to │ │ │ │ - _F_a_l_s_e). │ │ │ │ - Whenstart_timeis given _T_i_m_e_r uses _t_i_m_e_._t_i_m_e_(_) as a clock source, │ │ │ │ + False). │ │ │ │ + Whenstart_timeis given _T_i_m_e_r uses time.time() as a clock source, │ │ │ │ otherwise it uses _h_u_m_a_n_f_r_i_e_n_d_l_y_._c_o_m_p_a_t_._m_o_n_o_t_o_n_i_c_(_). │ │ │ │ __enter__()_¶ │ │ │ │ Start or resume counting elapsed time. │ │ │ │ Returns: │ │ │ │ The _T_i_m_e_r object. │ │ │ │ Raises: │ │ │ │ - _V_a_l_u_e_E_r_r_o_r when the timer isn’t resumable. │ │ │ │ + ValueError when the timer isn’t resumable. │ │ │ │ __exit__(eexxcc__ttyyppee==NNoonnee, eexxcc__vvaalluuee==NNoonnee, ttrraacceebbaacckk==NNoonnee)_¶ │ │ │ │ Stop counting elapsed time. │ │ │ │ Raises: │ │ │ │ - _V_a_l_u_e_E_r_r_o_r when the timer isn’t resumable. │ │ │ │ + ValueError when the timer isn’t resumable. │ │ │ │ sleep(sseeccoonnddss)_¶ │ │ │ │ Easy to use rate limiting of repeating actions. │ │ │ │ Parameters: │ │ │ │ sseeccoonnddss – The number of seconds to sleep (an integer or │ │ │ │ floating point number). │ │ │ │ This method sleeps for the given number of seconds minus the │ │ │ │ - _e_l_a_p_s_e_d___t_i_m_e. If the resulting duration is negative _t_i_m_e_._s_l_e_e_p_(_) │ │ │ │ + _e_l_a_p_s_e_d___t_i_m_e. If the resulting duration is negative time.sleep() │ │ │ │ will still be called, but the argument given to it will be the │ │ │ │ - number 0 (negative numbers cause _t_i_m_e_._s_l_e_e_p_(_) to raise an │ │ │ │ + number 0 (negative numbers cause time.sleep() to raise an │ │ │ │ exception). │ │ │ │ The use case for this is to initialize a _T_i_m_e_r inside the body of a │ │ │ │ - _f_o_r or _w_h_i_l_e loop and call _T_i_m_e_r_._s_l_e_e_p_(_) at the end of the loop │ │ │ │ + for or while loop and call _T_i_m_e_r_._s_l_e_e_p_(_) at the end of the loop │ │ │ │ body to rate limit whatever it is that is being done inside the │ │ │ │ loop body. │ │ │ │ For posterity: Although the implementation of _s_l_e_e_p_(_) only requires │ │ │ │ a single line of code I’ve added it to _h_u_m_a_n_f_r_i_e_n_d_l_y anyway because │ │ │ │ now that I’ve thought about how to tackle this once I never want to │ │ │ │ have to think about it again :-P (unless I find ways to improve │ │ │ │ this). │ │ │ │ @@ -203,42 +203,42 @@ │ │ │ │ __str__()_¶ │ │ │ │ Show the elapsed time since the _T_i_m_e_r was created. │ │ │ │ humanfriendly.coerce_boolean(vvaalluuee)_¶ │ │ │ │ Coerce any value to a boolean. │ │ │ │ Returns: │ │ │ │ A proper boolean value. │ │ │ │ Raises: │ │ │ │ - _e_x_c_e_p_t_i_o_n_s_._V_a_l_u_e_E_r_r_o_r when the value is a string but cannot be │ │ │ │ + exceptions.ValueError when the value is a string but cannot be │ │ │ │ coerced with certainty. │ │ │ │ humanfriendly.coerce_pattern(vvaalluuee, ffllaaggss==00)_¶ │ │ │ │ Coerce strings to compiled regular expressions. │ │ │ │ Parameters: │ │ │ │ * vvaalluuee – A string containing a regular expression pattern or a │ │ │ │ compiled regular expression. │ │ │ │ * ffllaaggss – The flags used to compile the pattern (an integer). │ │ │ │ Returns: │ │ │ │ A compiled regular expression. │ │ │ │ Raises: │ │ │ │ - _V_a_l_u_e_E_r_r_o_r whenvalueisn’t a string and also isn’t a compiled │ │ │ │ + ValueError whenvalueisn’t a string and also isn’t a compiled │ │ │ │ regular expression. │ │ │ │ humanfriendly.coerce_seconds(vvaalluuee)_¶ │ │ │ │ Coerce a value to the number of seconds. │ │ │ │ Parameters: │ │ │ │ - vvaalluuee – An _i_n_t, _f_l_o_a_t or _d_a_t_e_t_i_m_e_._t_i_m_e_d_e_l_t_a object. │ │ │ │ + vvaalluuee – An int, float or datetime.timedelta object. │ │ │ │ Returns: │ │ │ │ - An _i_n_t or _f_l_o_a_t value. │ │ │ │ - Whenvalueis a _d_a_t_e_t_i_m_e_._t_i_m_e_d_e_l_t_a object the _t_o_t_a_l___s_e_c_o_n_d_s_(_) method is │ │ │ │ + An int or float value. │ │ │ │ + Whenvalueis a datetime.timedelta object the total_seconds() method is │ │ │ │ called. │ │ │ │ humanfriendly.format_length(nnuumm__mmeettrreess, kkeeeepp__wwiiddtthh==FFaallssee)_¶ │ │ │ │ Format a metre count as a human readable length. │ │ │ │ Parameters: │ │ │ │ * nnuumm__mmeettrreess – The length to format in metres (float / │ │ │ │ integer). │ │ │ │ - * kkeeeepp__wwiiddtthh – _T_r_u_e if trailing zeros should not be stripped, │ │ │ │ - _F_a_l_s_e if they can be stripped. │ │ │ │ + * kkeeeepp__wwiiddtthh – True if trailing zeros should not be stripped, │ │ │ │ + False if they can be stripped. │ │ │ │ Returns: │ │ │ │ The corresponding human readable length (a string). │ │ │ │ This function supports ranges from nanometres to kilometres. │ │ │ │ Some examples: │ │ │ │ >>> from humanfriendly import format_length │ │ │ │ >>> format_length(0) │ │ │ │ '0 metres' │ │ │ │ @@ -249,16 +249,16 @@ │ │ │ │ >>> format_length(1000) │ │ │ │ '1 km' │ │ │ │ >>> format_length(0.004) │ │ │ │ '4 mm' │ │ │ │ humanfriendly.format_number(nnuummbbeerr, nnuumm__ddeecciimmaallss==22)_¶ │ │ │ │ Format a number as a string including thousands separators. │ │ │ │ Parameters: │ │ │ │ - * nnuummbbeerr – The number to format (a number like an _i_n_t, _l_o_n_g or │ │ │ │ - _f_l_o_a_t). │ │ │ │ + * nnuummbbeerr – The number to format (a number like an int, long or │ │ │ │ + float). │ │ │ │ * nnuumm__ddeecciimmaallss – The number of decimals to render (2 by │ │ │ │ default). If no decimal places are required to represent the │ │ │ │ number they will be omitted regardless of this argument. │ │ │ │ Returns: │ │ │ │ The formatted number (a string). │ │ │ │ This function is intended to make it easier to recognize the order of │ │ │ │ size of the number being formatted. │ │ │ │ @@ -289,18 +289,18 @@ │ │ │ │ >>> from humanfriendly import format_path │ │ │ │ >>> format_path(vimrc) │ │ │ │ '~/.vimrc' │ │ │ │ humanfriendly.format_size(nnuumm__bbyytteess, kkeeeepp__wwiiddtthh==FFaallssee, bbiinnaarryy==FFaallssee)_¶ │ │ │ │ Format a byte count as a human readable file size. │ │ │ │ Parameters: │ │ │ │ * nnuumm__bbyytteess – The size to format in bytes (an integer). │ │ │ │ - * kkeeeepp__wwiiddtthh – _T_r_u_e if trailing zeros should not be stripped, │ │ │ │ - _F_a_l_s_e if they can be stripped. │ │ │ │ - * bbiinnaarryy – _T_r_u_e to use binary multiples of bytes (base-2), │ │ │ │ - _F_a_l_s_e to use decimal multiples of bytes (base-10). │ │ │ │ + * kkeeeepp__wwiiddtthh – True if trailing zeros should not be stripped, │ │ │ │ + False if they can be stripped. │ │ │ │ + * bbiinnaarryy – True to use binary multiples of bytes (base-2), │ │ │ │ + False to use decimal multiples of bytes (base-10). │ │ │ │ Returns: │ │ │ │ The corresponding human readable file size (a string). │ │ │ │ This function knows how to format sizes in bytes, kilobytes, megabytes, │ │ │ │ gigabytes, terabytes and petabytes. Some examples: │ │ │ │ >>> from humanfriendly import format_size │ │ │ │ >>> format_size(0) │ │ │ │ '0 bytes' │ │ │ │ @@ -314,17 +314,17 @@ │ │ │ │ '1 KiB' │ │ │ │ >>> format_size(1000 ** 3 * 4) │ │ │ │ '4 GB' │ │ │ │ humanfriendly.format_timespan(nnuumm__sseeccoonnddss, ddeettaaiilleedd==FFaallssee, mmaaxx__uunniittss==33)_¶ │ │ │ │ Format a timespan in seconds as a human readable string. │ │ │ │ Parameters: │ │ │ │ * nnuumm__sseeccoonnddss – Any value accepted by _c_o_e_r_c_e___s_e_c_o_n_d_s_(_). │ │ │ │ - * ddeettaaiilleedd – If _T_r_u_e milliseconds are represented separately │ │ │ │ + * ddeettaaiilleedd – If True milliseconds are represented separately │ │ │ │ instead of being represented as fractional seconds (defaults │ │ │ │ - to _F_a_l_s_e). │ │ │ │ + to False). │ │ │ │ * mmaaxx__uunniittss – The maximum number of units to show in the │ │ │ │ formatted time span (an integer, defaults to three). │ │ │ │ Returns: │ │ │ │ The formatted timespan as a string. │ │ │ │ Raise: │ │ │ │ See _c_o_e_r_c_e___s_e_c_o_n_d_s_(_). │ │ │ │ Some examples: │ │ │ │ @@ -351,30 +351,30 @@ │ │ │ │ Raises: │ │ │ │ _I_n_v_a_l_i_d_D_a_t_e when the date cannot be parsed. │ │ │ │ Supported date/time formats: │ │ │ │ * YYYY-MM-DD │ │ │ │ * YYYY-MM-DD HH:MM:SS │ │ │ │ Note │ │ │ │ If you want to parse date/time strings with a fixed, known format and │ │ │ │ - _p_a_r_s_e___d_a_t_e_(_) isn’t useful to you, consider _t_i_m_e_._s_t_r_p_t_i_m_e_(_) or │ │ │ │ - _d_a_t_e_t_i_m_e_._d_a_t_e_t_i_m_e_._s_t_r_p_t_i_m_e_(_), both of which are included in the Python │ │ │ │ + _p_a_r_s_e___d_a_t_e_(_) isn’t useful to you, consider time.strptime() or │ │ │ │ + datetime.datetime.strptime(), both of which are included in the Python │ │ │ │ standard library. Alternatively for more complex tasks consider using the │ │ │ │ date/time parsing module in the _d_a_t_e_u_t_i_l package. │ │ │ │ Examples: │ │ │ │ >>> from humanfriendly import parse_date │ │ │ │ >>> parse_date('2013-06-17') │ │ │ │ (2013, 6, 17, 0, 0, 0) │ │ │ │ >>> parse_date('2013-06-17 02:47:42') │ │ │ │ (2013, 6, 17, 2, 47, 42) │ │ │ │ Here’s how you convert the result to a number (_U_n_i_x_ _t_i_m_e): │ │ │ │ >>> from humanfriendly import parse_date │ │ │ │ >>> from time import mktime │ │ │ │ >>> mktime(parse_date('2013-06-17 02:47:42') + (-1, -1, -1)) │ │ │ │ 1371430062.0 │ │ │ │ - And here’s how you convert it to a _d_a_t_e_t_i_m_e_._d_a_t_e_t_i_m_e object: │ │ │ │ + And here’s how you convert it to a datetime.datetime object: │ │ │ │ >>> from humanfriendly import parse_date │ │ │ │ >>> from datetime import datetime │ │ │ │ >>> datetime(*parse_date('2013-06-17 02:47:42')) │ │ │ │ datetime.datetime(2013, 6, 17, 2, 47, 42) │ │ │ │ Here’s an example that combines _f_o_r_m_a_t___t_i_m_e_s_p_a_n_(_) and _p_a_r_s_e___d_a_t_e_(_) to │ │ │ │ calculate a human friendly timespan since a given date: │ │ │ │ >>> from humanfriendly import format_timespan, parse_date │ │ │ │ @@ -399,27 +399,27 @@ │ │ │ │ 1000 │ │ │ │ >>> parse_length('5mm') │ │ │ │ 0.005 │ │ │ │ >>> parse_length('15.3cm') │ │ │ │ 0.153 │ │ │ │ humanfriendly.parse_path(ppaatthhnnaammee)_¶ │ │ │ │ Convert a human friendly pathname to an absolute pathname. │ │ │ │ - Expands leading tildes using _o_s_._p_a_t_h_._e_x_p_a_n_d_u_s_e_r_(_) and environment │ │ │ │ - variables using _o_s_._p_a_t_h_._e_x_p_a_n_d_v_a_r_s_(_) and makes the resulting pathname │ │ │ │ - absolute using _o_s_._p_a_t_h_._a_b_s_p_a_t_h_(_). │ │ │ │ + Expands leading tildes using os.path.expanduser() and environment │ │ │ │ + variables using os.path.expandvars() and makes the resulting pathname │ │ │ │ + absolute using os.path.abspath(). │ │ │ │ Parameters: │ │ │ │ ppaatthhnnaammee – A human friendly pathname (a string). │ │ │ │ Returns: │ │ │ │ An absolute pathname (a string). │ │ │ │ humanfriendly.parse_size(ssiizzee, bbiinnaarryy==FFaallssee)_¶ │ │ │ │ Parse a human readable data size and return the number of bytes. │ │ │ │ Parameters: │ │ │ │ * ssiizzee – The human readable file size to parse (a string). │ │ │ │ - * bbiinnaarryy – _T_r_u_e to use binary multiples of bytes (base-2) for │ │ │ │ - ambiguous unit symbols and names, _F_a_l_s_e to use decimal │ │ │ │ + * bbiinnaarryy – True to use binary multiples of bytes (base-2) for │ │ │ │ + ambiguous unit symbols and names, False to use decimal │ │ │ │ multiples of bytes (base-10). │ │ │ │ Returns: │ │ │ │ The corresponding size in bytes (an integer). │ │ │ │ Raises: │ │ │ │ _I_n_v_a_l_i_d_S_i_z_e when the input can’t be parsed. │ │ │ │ This function knows how to parse sizes in bytes, kilobytes, megabytes, │ │ │ │ gigabytes, terabytes and petabytes. Some examples: │ │ │ │ @@ -477,16 +477,16 @@ │ │ │ │ >>> parse_timespan('1d') │ │ │ │ 86400.0 │ │ │ │ humanfriendly.round_number(ccoouunntt, kkeeeepp__wwiiddtthh==FFaallssee)_¶ │ │ │ │ Round a floating point number to two decimal places in a human friendly │ │ │ │ format. │ │ │ │ Parameters: │ │ │ │ * ccoouunntt – The number to format. │ │ │ │ - * kkeeeepp__wwiiddtthh – _T_r_u_e if trailing zeros should not be stripped, │ │ │ │ - _F_a_l_s_e if they can be stripped. │ │ │ │ + * kkeeeepp__wwiiddtthh – True if trailing zeros should not be stripped, │ │ │ │ + False if they can be stripped. │ │ │ │ Returns: │ │ │ │ The formatted number as a string. If no decimal places are required │ │ │ │ to represent the number, they will be omitted. │ │ │ │ The main purpose of this function is to be used by functions like │ │ │ │ _f_o_r_m_a_t___l_e_n_g_t_h_(_), _f_o_r_m_a_t___s_i_z_e_(_) and _f_o_r_m_a_t___t_i_m_e_s_p_a_n_(_). │ │ │ │ Here are some examples: │ │ │ │ >>> from humanfriendly import round_number │ │ │ │ @@ -519,25 +519,25 @@ │ │ │ │ write, easy to read and work well with Python’s whitespace sensitivity. │ │ │ │ humanfriendly.concatenate(iitteemmss, ccoonnjjuunnccttiioonn==''aanndd'', sseerriiaall__ccoommmmaa==FFaallssee)_¶ │ │ │ │ Concatenate a list of items in a human friendly way. │ │ │ │ Parameters: │ │ │ │ * iitteemmss – A sequence of strings. │ │ │ │ * ccoonnjjuunnccttiioonn – The word to use before the last item (a string, │ │ │ │ defaults to “and”). │ │ │ │ - * sseerriiaall__ccoommmmaa – _T_r_u_e to use a _s_e_r_i_a_l_ _c_o_m_m_a, _F_a_l_s_e otherwise │ │ │ │ - (defaults to _F_a_l_s_e). │ │ │ │ + * sseerriiaall__ccoommmmaa – True to use a _s_e_r_i_a_l_ _c_o_m_m_a, False otherwise │ │ │ │ + (defaults to False). │ │ │ │ Returns: │ │ │ │ A single string. │ │ │ │ >>> from humanfriendly.text import concatenate │ │ │ │ >>> concatenate(["eggs", "milk", "bread"]) │ │ │ │ 'eggs, milk and bread' │ │ │ │ humanfriendly.dedent(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ Dedent a string (remove common leading whitespace from all lines). │ │ │ │ Removes common leading whitespace from all lines in the string using │ │ │ │ - _t_e_x_t_w_r_a_p_._d_e_d_e_n_t_(_), removes leading and trailing empty lines using │ │ │ │ + textwrap.dedent(), removes leading and trailing empty lines using │ │ │ │ _t_r_i_m___e_m_p_t_y___l_i_n_e_s_(_) and interpolates any arguments using _f_o_r_m_a_t_(_). │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text to dedent (a string). │ │ │ │ * aarrggss – Any positional arguments are interpolated using _f_o_r_m_a_t │ │ │ │ _(_). │ │ │ │ * kkww – Any keyword arguments are interpolated using _f_o_r_m_a_t_(_). │ │ │ │ Returns: │ │ │ │ @@ -551,32 +551,32 @@ │ │ │ │ Update a module with backwards compatible aliases. │ │ │ │ Parameters: │ │ │ │ * mmoodduullee__nnaammee – The __name__ of the module (a string). │ │ │ │ * aalliiaasseess – Each keyword argument defines an alias. The values │ │ │ │ are expected to be “dotted paths” (strings). │ │ │ │ The behavior of this function depends on whether the Sphinx documentation │ │ │ │ generator is active, because the use of DeprecationProxy to shadow the │ │ │ │ - real module in _s_y_s_._m_o_d_u_l_e_s has the unintended side effect of breaking │ │ │ │ + real module in sys.modules has the unintended side effect of breaking │ │ │ │ autodoc support for :data: members (module variables). │ │ │ │ To avoid breaking Sphinx the proxy object is omitted and instead the │ │ │ │ aliased names are injected into the original module namespace, to make │ │ │ │ sure that imports can be satisfied when the documentation is being │ │ │ │ rendered. │ │ │ │ If you run into cyclic dependencies caused by _d_e_f_i_n_e___a_l_i_a_s_e_s_(_) when │ │ │ │ running Sphinx, you can try moving the call to _d_e_f_i_n_e___a_l_i_a_s_e_s_(_) to the │ │ │ │ bottom of the Python module you’re working on. │ │ │ │ humanfriendly.format(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ - Format a string using the string formatting operator and/or _s_t_r_._f_o_r_m_a_t_(_). │ │ │ │ + Format a string using the string formatting operator and/or str.format(). │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text to format (a string). │ │ │ │ * aarrggss – Any positional arguments are interpolated into the │ │ │ │ text using the string formatting operator (%). If no │ │ │ │ positional arguments are given no interpolation is done. │ │ │ │ * kkww – Any keyword arguments are interpolated into the text │ │ │ │ - using the _s_t_r_._f_o_r_m_a_t_(_) function. If no keyword arguments are │ │ │ │ + using the str.format() function. If no keyword arguments are │ │ │ │ given no interpolation is done. │ │ │ │ Returns: │ │ │ │ The text with any positional and/or keyword arguments interpolated │ │ │ │ (a string). │ │ │ │ The implementation of this function is so trivial that it seems silly to │ │ │ │ even bother writing and documenting it. Justifying this requires some │ │ │ │ context :-). │ │ │ │ @@ -595,28 +595,28 @@ │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ >>> # The format() function. │ │ │ │ >>> print(format('the magic number is %s', 42)) │ │ │ │ the magic number is 42 │ │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ * When you interpolate a single value and someone accidentally passes │ │ │ │ - in a tuple your code raises a _T_y_p_e_E_r_r_o_r. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ + in a tuple your code raises a TypeError. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ _v_a_r_i_a_b_l_e_ _n_u_m_b_e_r_ _o_f_ _a_r_g_u_m_e_n_t_s it always receives a tuple so this can │ │ │ │ never happen. Here’s an example: │ │ │ │ >>> # How expecting to interpolate a single value can fail. │ │ │ │ >>> value = (12, 42) │ │ │ │ >>> print('the magic value is %s' % value) │ │ │ │ Traceback (most recent call last): │ │ │ │ File "", line 1, in │ │ │ │ TypeError: not all arguments converted during string formatting │ │ │ │ >>> # The following line works as intended, no surprises here! │ │ │ │ >>> print(format('the magic value is %s', value)) │ │ │ │ the magic value is (12, 42) │ │ │ │ WWhhyy ffoorrmmaatt(()) iinnsstteeaadd ooff tthhee ssttrr..ffoorrmmaatt(()) mmeetthhoodd?? │ │ │ │ - When you’re doing complex string interpolation the _s_t_r_._f_o_r_m_a_t_(_) function │ │ │ │ + When you’re doing complex string interpolation the str.format() function │ │ │ │ results in more readable code, however I frequently find myself adding │ │ │ │ parentheses to force evaluation order. The _f_o_r_m_a_t_(_) function avoids this │ │ │ │ because of the relative priority between the comma and dot operators. │ │ │ │ Here’s an example: │ │ │ │ >>> "{adjective} example" + " " + "(can't think of anything less │ │ │ │ {adjective})".format(adjective='silly') │ │ │ │ "{adjective} example (can't think of anything less silly)" │ │ │ │ @@ -630,15 +630,15 @@ │ │ │ │ with whitespace manipulation to make it easy to write nice to read Python │ │ │ │ code. │ │ │ │ humanfriendly.format_table(ddaattaa, ccoolluummnn__nnaammeess==NNoonnee, hhoorriizzoonnttaall__bbaarr==''--'', │ │ │ │ vveerrttiiccaall__bbaarr==''||'')_¶ │ │ │ │ Render a table using characters like dashes and vertical bars to emulate │ │ │ │ borders. │ │ │ │ Parameters: │ │ │ │ - * ddaattaa – An iterable (e.g. a _t_u_p_l_e_(_) or _l_i_s_t) containing the │ │ │ │ + * ddaattaa – An iterable (e.g. a tuple() or list) containing the │ │ │ │ rows of the table, where each row is an iterable containing │ │ │ │ the columns of the table (strings). │ │ │ │ * ccoolluummnn__nnaammeess – An iterable of column names (strings). │ │ │ │ * hhoorriizzoonnttaall__bbaarr – The character used to represent a horizontal │ │ │ │ bar (a string). │ │ │ │ * vveerrttiiccaall__bbaarr – The character used to represent a vertical bar │ │ │ │ (a string). │ │ │ │ @@ -676,43 +676,43 @@ │ │ │ │ a black background): │ │ │ │ [_images/pretty-table.png] │ │ │ │ humanfriendly.is_empty_line(tteexxtt)_¶ │ │ │ │ Check if a text is empty or contains only whitespace. │ │ │ │ Parameters: │ │ │ │ tteexxtt – The text to check for “emptiness” (a string). │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the text is empty or contains only whitespace, _F_a_l_s_e │ │ │ │ + True if the text is empty or contains only whitespace, False │ │ │ │ otherwise. │ │ │ │ humanfriendly.is_string(vvaalluuee)_¶ │ │ │ │ - Check if a value is a _b_a_s_e_s_t_r_i_n_g_(_) (in Python 2) or _s_t_r (in Python 3) │ │ │ │ - object. │ │ │ │ + Check if a value is a python2:basestring() (in Python 2) or python3:str │ │ │ │ + (in Python 3) object. │ │ │ │ Parameters: │ │ │ │ vvaalluuee – The value to check. │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the value is a string, _F_a_l_s_e otherwise. │ │ │ │ + True if the value is a string, False otherwise. │ │ │ │ humanfriendly.pluralize(ccoouunntt, ssiinngguullaarr, pplluurraall==NNoonnee)_¶ │ │ │ │ Combine a count with the singular or plural form of a word. │ │ │ │ Parameters: │ │ │ │ * ccoouunntt – The count (a number). │ │ │ │ * ssiinngguullaarr – The singular form of the word (a string). │ │ │ │ - * pplluurraall – The plural form of the word (a string or _N_o_n_e). │ │ │ │ + * pplluurraall – The plural form of the word (a string or None). │ │ │ │ Returns: │ │ │ │ The count and singular or plural word concatenated (a string). │ │ │ │ See pluralize_raw() for the logic underneath _p_l_u_r_a_l_i_z_e_(_). │ │ │ │ humanfriendly.prompt_for_choice(cchhooiicceess, ddeeffaauulltt==NNoonnee, ppaaddddiinngg==TTrruuee)_¶ │ │ │ │ Prompt the user to select a choice from a group of options. │ │ │ │ Parameters: │ │ │ │ * cchhooiicceess – A sequence of strings with available options. │ │ │ │ * ddeeffaauulltt – The default choice if the user simply presses Enter │ │ │ │ - (expected to be a string, defaults to _N_o_n_e). │ │ │ │ + (expected to be a string, defaults to None). │ │ │ │ * ppaaddddiinngg – Refer to the documentation of _p_r_o_m_p_t___f_o_r___i_n_p_u_t_(_). │ │ │ │ Returns: │ │ │ │ The string corresponding to the user’s choice. │ │ │ │ Raises: │ │ │ │ - * _V_a_l_u_e_E_r_r_o_r ifchoicesis an empty sequence. │ │ │ │ + * ValueError ifchoicesis an empty sequence. │ │ │ │ * Any exceptions raised by _r_e_t_r_y___l_i_m_i_t_(_). │ │ │ │ * Any exceptions raised by _p_r_o_m_p_t___f_o_r___i_n_p_u_t_(_). │ │ │ │ When no options are given an exception is raised: │ │ │ │ >>> prompt_for_choice([]) │ │ │ │ Traceback (most recent call last): │ │ │ │ File "humanfriendly/prompts.py", line 148, in prompt_for_choice │ │ │ │ raise ValueError("Can't prompt for choice without any options!") │ │ │ │ @@ -887,28 +887,28 @@ │ │ │ │ humanfriendly.cli.run_command(ccoommmmaanndd__lliinnee)_¶ │ │ │ │ Run an external command and show a spinner while the command is running. │ │ │ │ humanfriendly.cli.ansi_strip(tteexxtt, rreeaaddlliinnee__hhiinnttss==TTrruuee)_¶ │ │ │ │ Strip ANSI escape sequences from the given string. │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text from which ANSI escape sequences should be │ │ │ │ removed (a string). │ │ │ │ - * rreeaaddlliinnee__hhiinnttss – If _T_r_u_e then readline_strip() is used to │ │ │ │ + * rreeaaddlliinnee__hhiinnttss – If True then readline_strip() is used to │ │ │ │ remove _r_e_a_d_l_i_n_e_ _h_i_n_t_s from the string. │ │ │ │ Returns: │ │ │ │ The text without ANSI escape sequences (a string). │ │ │ │ humanfriendly.cli.ansi_wrap(tteexxtt, ****kkww)_¶ │ │ │ │ Wrap text in ANSI escape sequences for the given color and/or style(s). │ │ │ │ humanfriendly.cli.enable_ansi_support()_¶ │ │ │ │ Try to enable support for ANSI escape sequences (required on Windows). │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if ANSI is supported, _F_a_l_s_e otherwise. │ │ │ │ + True if ANSI is supported, False otherwise. │ │ │ │ This functions checks for the following supported configurations, in the │ │ │ │ given order: │ │ │ │ 1. On Windows, if have_windows_native_ansi_support() confirms native │ │ │ │ - support for ANSI escape sequences _c_t_y_p_e_s will be used to enable │ │ │ │ + support for ANSI escape sequences ctypes will be used to enable │ │ │ │ this support. │ │ │ │ 2. On Windows, if the environment variable $ANSICON is set nothing is │ │ │ │ done because it is assumed that support for ANSI escape sequences │ │ │ │ has already been enabled via _a_n_s_i_c_o_n. │ │ │ │ 3. On Windows, an attempt is made to import and initialize the Python │ │ │ │ package _c_o_l_o_r_a_m_a instead (of course for this to work _c_o_l_o_r_a_m_a has │ │ │ │ to be installed). │ │ │ │ @@ -931,24 +931,24 @@ │ │ │ │ 3. finally DEFAULT_LINES and DEFAULT_COLUMNS are returned. │ │ │ │ Note │ │ │ │ The _f_i_n_d___t_e_r_m_i_n_a_l___s_i_z_e_(_) function performs the steps above every time it │ │ │ │ is called, the result is not cached. This is because the size of a │ │ │ │ virtual terminal can change at any time and the result of │ │ │ │ _f_i_n_d___t_e_r_m_i_n_a_l___s_i_z_e_(_) should be correct. │ │ │ │ _P_r_e_-_e_m_p_t_i_v_e_ _s_n_a_r_k_y_ _c_o_m_m_e_n_t: It’s possible to cache the result of this │ │ │ │ - function and use _s_i_g_n_a_l_._S_I_G_W_I_N_C_H to refresh the cached values! │ │ │ │ + function and use signal.SIGWINCH to refresh the cached values! │ │ │ │ Response: As a library I don’t consider it the role of the │ │ │ │ _h_u_m_a_n_f_r_i_e_n_d_l_y_._t_e_r_m_i_n_a_l module to install a process wide signal handler … │ │ │ │ humanfriendly.cli.format_length(nnuumm__mmeettrreess, kkeeeepp__wwiiddtthh==FFaallssee)_¶ │ │ │ │ Format a metre count as a human readable length. │ │ │ │ Parameters: │ │ │ │ * nnuumm__mmeettrreess – The length to format in metres (float / │ │ │ │ integer). │ │ │ │ - * kkeeeepp__wwiiddtthh – _T_r_u_e if trailing zeros should not be stripped, │ │ │ │ - _F_a_l_s_e if they can be stripped. │ │ │ │ + * kkeeeepp__wwiiddtthh – True if trailing zeros should not be stripped, │ │ │ │ + False if they can be stripped. │ │ │ │ Returns: │ │ │ │ The corresponding human readable length (a string). │ │ │ │ This function supports ranges from nanometres to kilometres. │ │ │ │ Some examples: │ │ │ │ >>> from humanfriendly import format_length │ │ │ │ >>> format_length(0) │ │ │ │ '0 metres' │ │ │ │ @@ -959,16 +959,16 @@ │ │ │ │ >>> format_length(1000) │ │ │ │ '1 km' │ │ │ │ >>> format_length(0.004) │ │ │ │ '4 mm' │ │ │ │ humanfriendly.cli.format_number(nnuummbbeerr, nnuumm__ddeecciimmaallss==22)_¶ │ │ │ │ Format a number as a string including thousands separators. │ │ │ │ Parameters: │ │ │ │ - * nnuummbbeerr – The number to format (a number like an _i_n_t, _l_o_n_g or │ │ │ │ - _f_l_o_a_t). │ │ │ │ + * nnuummbbeerr – The number to format (a number like an int, long or │ │ │ │ + float). │ │ │ │ * nnuumm__ddeecciimmaallss – The number of decimals to render (2 by │ │ │ │ default). If no decimal places are required to represent the │ │ │ │ number they will be omitted regardless of this argument. │ │ │ │ Returns: │ │ │ │ The formatted number (a string). │ │ │ │ This function is intended to make it easier to recognize the order of │ │ │ │ size of the number being formatted. │ │ │ │ @@ -981,15 +981,15 @@ │ │ │ │ > print(format_number(6000000000.42, num_decimals=0)) │ │ │ │ 6,000,000,000 │ │ │ │ humanfriendly.cli.format_pretty_table(ddaattaa, ccoolluummnn__nnaammeess==NNoonnee, │ │ │ │ hhoorriizzoonnttaall__bbaarr==''--'', vveerrttiiccaall__bbaarr==''||'')_¶ │ │ │ │ Render a table using characters like dashes and vertical bars to emulate │ │ │ │ borders. │ │ │ │ Parameters: │ │ │ │ - * ddaattaa – An iterable (e.g. a _t_u_p_l_e_(_) or _l_i_s_t) containing the │ │ │ │ + * ddaattaa – An iterable (e.g. a tuple() or list) containing the │ │ │ │ rows of the table, where each row is an iterable containing │ │ │ │ the columns of the table (strings). │ │ │ │ * ccoolluummnn__nnaammeess – An iterable of column names (strings). │ │ │ │ * hhoorriizzoonnttaall__bbaarr – The character used to represent a horizontal │ │ │ │ bar (a string). │ │ │ │ * vveerrttiiccaall__bbaarr – The character used to represent a vertical bar │ │ │ │ (a string). │ │ │ │ @@ -1026,18 +1026,18 @@ │ │ │ │ what that looks like (my terminals are always set to white text on │ │ │ │ a black background): │ │ │ │ [_images/pretty-table.png] │ │ │ │ humanfriendly.cli.format_size(nnuumm__bbyytteess, kkeeeepp__wwiiddtthh==FFaallssee, bbiinnaarryy==FFaallssee)_¶ │ │ │ │ Format a byte count as a human readable file size. │ │ │ │ Parameters: │ │ │ │ * nnuumm__bbyytteess – The size to format in bytes (an integer). │ │ │ │ - * kkeeeepp__wwiiddtthh – _T_r_u_e if trailing zeros should not be stripped, │ │ │ │ - _F_a_l_s_e if they can be stripped. │ │ │ │ - * bbiinnaarryy – _T_r_u_e to use binary multiples of bytes (base-2), │ │ │ │ - _F_a_l_s_e to use decimal multiples of bytes (base-10). │ │ │ │ + * kkeeeepp__wwiiddtthh – True if trailing zeros should not be stripped, │ │ │ │ + False if they can be stripped. │ │ │ │ + * bbiinnaarryy – True to use binary multiples of bytes (base-2), │ │ │ │ + False to use decimal multiples of bytes (base-10). │ │ │ │ Returns: │ │ │ │ The corresponding human readable file size (a string). │ │ │ │ This function knows how to format sizes in bytes, kilobytes, megabytes, │ │ │ │ gigabytes, terabytes and petabytes. Some examples: │ │ │ │ >>> from humanfriendly import format_size │ │ │ │ >>> format_size(0) │ │ │ │ '0 bytes' │ │ │ │ @@ -1050,15 +1050,15 @@ │ │ │ │ > format_size(1024, binary=True) │ │ │ │ '1 KiB' │ │ │ │ >>> format_size(1000 ** 3 * 4) │ │ │ │ '4 GB' │ │ │ │ humanfriendly.cli.format_smart_table(ddaattaa, ccoolluummnn__nnaammeess)_¶ │ │ │ │ Render tabular data using the most appropriate representation. │ │ │ │ Parameters: │ │ │ │ - * ddaattaa – An iterable (e.g. a _t_u_p_l_e_(_) or _l_i_s_t) containing the │ │ │ │ + * ddaattaa – An iterable (e.g. a tuple() or list) containing the │ │ │ │ rows of the table, where each row is an iterable containing │ │ │ │ the columns of the table (strings). │ │ │ │ * ccoolluummnn__nnaammeess – An iterable of column names (strings). │ │ │ │ Returns: │ │ │ │ The rendered table (a string). │ │ │ │ If you want an easy way to render tabular data on a terminal in a human │ │ │ │ friendly format then this function is for you! It works as follows: │ │ │ │ @@ -1070,17 +1070,17 @@ │ │ │ │ would wrap (given the width of the terminal) then the function │ │ │ │ format_robust_table() is used to render a more robust table that │ │ │ │ can deal with data containing line breaks and long text. │ │ │ │ humanfriendly.cli.format_timespan(nnuumm__sseeccoonnddss, ddeettaaiilleedd==FFaallssee, mmaaxx__uunniittss==33)_¶ │ │ │ │ Format a timespan in seconds as a human readable string. │ │ │ │ Parameters: │ │ │ │ * nnuumm__sseeccoonnddss – Any value accepted by coerce_seconds(). │ │ │ │ - * ddeettaaiilleedd – If _T_r_u_e milliseconds are represented separately │ │ │ │ + * ddeettaaiilleedd – If True milliseconds are represented separately │ │ │ │ instead of being represented as fractional seconds (defaults │ │ │ │ - to _F_a_l_s_e). │ │ │ │ + to False). │ │ │ │ * mmaaxx__uunniittss – The maximum number of units to show in the │ │ │ │ formatted time span (an integer, defaults to three). │ │ │ │ Returns: │ │ │ │ The formatted timespan as a string. │ │ │ │ Raise: │ │ │ │ See coerce_seconds(). │ │ │ │ Some examples: │ │ │ │ @@ -1097,15 +1097,15 @@ │ │ │ │ >>> week = day * 7 │ │ │ │ >>> format_timespan(week * 52 + day * 2 + hour * 3) │ │ │ │ '1 year, 2 days and 3 hours' │ │ │ │ humanfriendly.cli.output(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ Print a formatted message to the standard output stream. │ │ │ │ For details about argument handling please refer to _f_o_r_m_a_t_(_). │ │ │ │ Renders the message using _f_o_r_m_a_t_(_) and writes the resulting string │ │ │ │ - (followed by a newline) to _s_y_s_._s_t_d_o_u_t using auto_encode(). │ │ │ │ + (followed by a newline) to sys.stdout using auto_encode(). │ │ │ │ humanfriendly.cli.parse_length(lleennggtthh)_¶ │ │ │ │ Parse a human readable length and return the number of metres. │ │ │ │ Parameters: │ │ │ │ lleennggtthh – The human readable length to parse (a string). │ │ │ │ Returns: │ │ │ │ The corresponding length in metres (a float). │ │ │ │ Raises: │ │ │ │ @@ -1120,16 +1120,16 @@ │ │ │ │ 0.005 │ │ │ │ >>> parse_length('15.3cm') │ │ │ │ 0.153 │ │ │ │ humanfriendly.cli.parse_size(ssiizzee, bbiinnaarryy==FFaallssee)_¶ │ │ │ │ Parse a human readable data size and return the number of bytes. │ │ │ │ Parameters: │ │ │ │ * ssiizzee – The human readable file size to parse (a string). │ │ │ │ - * bbiinnaarryy – _T_r_u_e to use binary multiples of bytes (base-2) for │ │ │ │ - ambiguous unit symbols and names, _F_a_l_s_e to use decimal │ │ │ │ + * bbiinnaarryy – True to use binary multiples of bytes (base-2) for │ │ │ │ + ambiguous unit symbols and names, False to use decimal │ │ │ │ multiples of bytes (base-10). │ │ │ │ Returns: │ │ │ │ The corresponding size in bytes (an integer). │ │ │ │ Raises: │ │ │ │ InvalidSize when the input can’t be parsed. │ │ │ │ This function knows how to parse sizes in bytes, kilobytes, megabytes, │ │ │ │ gigabytes, terabytes and petabytes. Some examples: │ │ │ │ @@ -1155,75 +1155,77 @@ │ │ │ │ humanfriendly.cli.quote(ss)_¶ │ │ │ │ Return a shell-escaped version of the string ss. │ │ │ │ humanfriendly.cli.usage(uussaaggee__tteexxtt)_¶ │ │ │ │ Print a human friendly usage message to the terminal. │ │ │ │ Parameters: │ │ │ │ tteexxtt – The usage message to print (a string). │ │ │ │ This function does two things: │ │ │ │ - 1. If _s_y_s_._s_t_d_o_u_t is connected to a terminal (see connected_to_terminal │ │ │ │ + 1. If sys.stdout is connected to a terminal (see connected_to_terminal │ │ │ │ ()) then the usage message is formatted using _f_o_r_m_a_t___u_s_a_g_e_(_). │ │ │ │ 2. The usage message is shown using a pager (see show_pager()). │ │ │ │ humanfriendly.cli.warning(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ Show a warning message on the terminal. │ │ │ │ For details about argument handling please refer to _f_o_r_m_a_t_(_). │ │ │ │ Renders the message using _f_o_r_m_a_t_(_) and writes the resulting string │ │ │ │ - (followed by a newline) to _s_y_s_._s_t_d_e_r_r using auto_encode(). │ │ │ │ - If _s_y_s_._s_t_d_e_r_r is connected to a terminal that supports colors, _a_n_s_i___w_r_a_p │ │ │ │ + (followed by a newline) to sys.stderr using auto_encode(). │ │ │ │ + If sys.stderr is connected to a terminal that supports colors, _a_n_s_i___w_r_a_p │ │ │ │ _(_) is used to color the message in a red font (to make the warning stand │ │ │ │ out from surrounding text). │ │ │ │ ********** _hh_uu_mm_aa_nn_ff_rr_ii_ee_nn_dd_ll_yy_.._cc_oo_mm_pp_aa_tt_?¶ ********** │ │ │ │ Compatibility with Python 2 and 3. │ │ │ │ This module exposes aliases and functions that make it easier to write Python │ │ │ │ code that is compatible with Python 2 and Python 3. │ │ │ │ humanfriendly.compat.basestring_¶ │ │ │ │ - Alias for _b_a_s_e_s_t_r_i_n_g_(_) (in Python 2) or _s_t_r (in Python 3). See also │ │ │ │ - _i_s___s_t_r_i_n_g_(_). │ │ │ │ + Alias for python2:basestring() (in Python 2) or python3:str (in Python │ │ │ │ + 3). See also _i_s___s_t_r_i_n_g_(_). │ │ │ │ humanfriendly.compat.HTMLParser_¶ │ │ │ │ - Alias for _H_T_M_L_P_a_r_s_e_r_._H_T_M_L_P_a_r_s_e_r (in Python 2) or _h_t_m_l_._p_a_r_s_e_r_._H_T_M_L_P_a_r_s_e_r │ │ │ │ - (in Python 3). │ │ │ │ + Alias for python2:HTMLParser.HTMLParser (in Python 2) or python3: │ │ │ │ + html.parser.HTMLParser (in Python 3). │ │ │ │ humanfriendly.compat.interactive_prompt_¶ │ │ │ │ - Alias for _r_a_w___i_n_p_u_t_(_) (in Python 2) or _i_n_p_u_t_(_) (in Python 3). │ │ │ │ + Alias for python2:raw_input() (in Python 2) or python3:input() (in Python │ │ │ │ + 3). │ │ │ │ humanfriendly.compat.StringIO_¶ │ │ │ │ - Alias for _S_t_r_i_n_g_I_O_._S_t_r_i_n_g_I_O (in Python 2) or _i_o_._S_t_r_i_n_g_I_O (in Python 3). │ │ │ │ + Alias for python2:StringIO.StringIO (in Python 2) or python3:io.StringIO │ │ │ │ + (in Python 3). │ │ │ │ humanfriendly.compat.unicode_¶ │ │ │ │ - Alias for _u_n_i_c_o_d_e_(_) (in Python 2) or _s_t_r (in Python 3). See also │ │ │ │ - _c_o_e_r_c_e___s_t_r_i_n_g_(_). │ │ │ │ + Alias for python2:unicode() (in Python 2) or python3:str (in Python 3). │ │ │ │ + See also _c_o_e_r_c_e___s_t_r_i_n_g_(_). │ │ │ │ humanfriendly.compat.monotonic_¶ │ │ │ │ - Alias for _t_i_m_e_._m_o_n_o_t_o_n_i_c_(_) (in Python 3.3 and higher) │ │ │ │ + Alias for python3:time.monotonic() (in Python 3.3 and higher) │ │ │ │ ormonotonic.monotonic()(a _c_o_n_d_i_t_i_o_n_a_l_ _d_e_p_e_n_d_e_n_c_y on older Python │ │ │ │ versions). │ │ │ │ humanfriendly.compat.coerce_string(vvaalluuee)_¶ │ │ │ │ - Coerce any value to a Unicode string (_u_n_i_c_o_d_e_(_) in Python 2 and _s_t_r in │ │ │ │ - Python 3). │ │ │ │ + Coerce any value to a Unicode string (python2:unicode() in Python 2 and │ │ │ │ + python3:str in Python 3). │ │ │ │ Parameters: │ │ │ │ vvaalluuee – The value to coerce. │ │ │ │ Returns: │ │ │ │ The value coerced to a Unicode string. │ │ │ │ humanfriendly.compat.is_string(vvaalluuee)_¶ │ │ │ │ - Check if a value is a _b_a_s_e_s_t_r_i_n_g_(_) (in Python 2) or _s_t_r (in Python 3) │ │ │ │ - object. │ │ │ │ + Check if a value is a python2:basestring() (in Python 2) or python3:str │ │ │ │ + (in Python 3) object. │ │ │ │ Parameters: │ │ │ │ vvaalluuee – The value to check. │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the value is a string, _F_a_l_s_e otherwise. │ │ │ │ + True if the value is a string, False otherwise. │ │ │ │ humanfriendly.compat.is_unicode(vvaalluuee)_¶ │ │ │ │ - Check if a value is a _u_n_i_c_o_d_e_(_) (in Python 2) or _s_t_r (in Python 3) │ │ │ │ - object. │ │ │ │ + Check if a value is a python2:unicode() (in Python 2) or python2:str (in │ │ │ │ + Python 3) object. │ │ │ │ Parameters: │ │ │ │ vvaalluuee – The value to check. │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the value is a Unicode string, _F_a_l_s_e otherwise. │ │ │ │ + True if the value is a Unicode string, False otherwise. │ │ │ │ humanfriendly.compat.on_macos()_¶ │ │ │ │ Check if we’re running on Apple MacOS. │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if running MacOS, _F_a_l_s_e otherwise. │ │ │ │ + True if running MacOS, False otherwise. │ │ │ │ humanfriendly.compat.on_windows()_¶ │ │ │ │ Check if we’re running on the Microsoft Windows OS. │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if running Windows, _F_a_l_s_e otherwise. │ │ │ │ + True if running Windows, False otherwise. │ │ │ │ ********** _hh_uu_mm_aa_nn_ff_rr_ii_ee_nn_dd_ll_yy_.._dd_ee_cc_oo_rr_aa_tt_oo_rr_ss_?¶ ********** │ │ │ │ Simple function decorators to make Python programming easier. │ │ │ │ humanfriendly.decorators.RESULTS_ATTRIBUTE == ''ccaacchheedd__rreessuullttss''_¶ │ │ │ │ The name of the property used to cache the return values of functions (a │ │ │ │ string). │ │ │ │ humanfriendly.decorators.cached(ffuunnccttiioonn)_¶ │ │ │ │ Rudimentary caching decorator for functions. │ │ │ │ @@ -1239,15 +1241,15 @@ │ │ │ │ return value can be cached. Accepting any function arguments at all would │ │ │ │ imply that the cache is parametrized on function arguments, which is not │ │ │ │ currently the case. │ │ │ │ ********** _hh_uu_mm_aa_nn_ff_rr_ii_ee_nn_dd_ll_yy_.._dd_ee_pp_rr_ee_cc_aa_tt_ii_oo_nn_?¶ ********** │ │ │ │ Support for deprecation warnings when importing names from old locations. │ │ │ │ When software evolves, things tend to move around. This is usually detrimental │ │ │ │ to backwards compatibility (in Python this primarily manifests itself as │ │ │ │ -_I_m_p_o_r_t_E_r_r_o_r exceptions). │ │ │ │ +ImportError exceptions). │ │ │ │ While backwards compatibility is very important, it should not get in the way │ │ │ │ of progress. It would be great to have the agility to move things around │ │ │ │ without breaking backwards compatibility. │ │ │ │ This is where the _h_u_m_a_n_f_r_i_e_n_d_l_y_._d_e_p_r_e_c_a_t_i_o_n module comes in: It enables the │ │ │ │ definition of backwards compatible aliases that emit a deprecation warning when │ │ │ │ they are accessed. │ │ │ │ The way it works is that it wraps the original module in an _D_e_p_r_e_c_a_t_i_o_n_P_r_o_x_y │ │ │ │ @@ -1276,15 +1278,15 @@ │ │ │ │ Update a module with backwards compatible aliases. │ │ │ │ Parameters: │ │ │ │ * mmoodduullee__nnaammee – The __name__ of the module (a string). │ │ │ │ * aalliiaasseess – Each keyword argument defines an alias. The values │ │ │ │ are expected to be “dotted paths” (strings). │ │ │ │ The behavior of this function depends on whether the Sphinx documentation │ │ │ │ generator is active, because the use of _D_e_p_r_e_c_a_t_i_o_n_P_r_o_x_y to shadow the │ │ │ │ - real module in _s_y_s_._m_o_d_u_l_e_s has the unintended side effect of breaking │ │ │ │ + real module in sys.modules has the unintended side effect of breaking │ │ │ │ autodoc support for :data: members (module variables). │ │ │ │ To avoid breaking Sphinx the proxy object is omitted and instead the │ │ │ │ aliased names are injected into the original module namespace, to make │ │ │ │ sure that imports can be satisfied when the documentation is being │ │ │ │ rendered. │ │ │ │ If you run into cyclic dependencies caused by _d_e_f_i_n_e___a_l_i_a_s_e_s_(_) when │ │ │ │ running Sphinx, you can try moving the call to _d_e_f_i_n_e___a_l_i_a_s_e_s_(_) to the │ │ │ │ @@ -1327,22 +1329,22 @@ │ │ │ │ this will not give a deprecation warning │ │ │ │ humanfriendly.deprecation.get_aliases(mmoodduullee__nnaammee)_¶ │ │ │ │ Get the aliases defined by a module. │ │ │ │ humanfriendly.deprecation.is_method(ffuunnccttiioonn)_¶ │ │ │ │ Check if the expected usage of the given function is as an instance │ │ │ │ method. │ │ │ │ humanfriendly.deprecation.format(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ - Format a string using the string formatting operator and/or _s_t_r_._f_o_r_m_a_t_(_). │ │ │ │ + Format a string using the string formatting operator and/or str.format(). │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text to format (a string). │ │ │ │ * aarrggss – Any positional arguments are interpolated into the │ │ │ │ text using the string formatting operator (%). If no │ │ │ │ positional arguments are given no interpolation is done. │ │ │ │ * kkww – Any keyword arguments are interpolated into the text │ │ │ │ - using the _s_t_r_._f_o_r_m_a_t_(_) function. If no keyword arguments are │ │ │ │ + using the str.format() function. If no keyword arguments are │ │ │ │ given no interpolation is done. │ │ │ │ Returns: │ │ │ │ The text with any positional and/or keyword arguments interpolated │ │ │ │ (a string). │ │ │ │ The implementation of this function is so trivial that it seems silly to │ │ │ │ even bother writing and documenting it. Justifying this requires some │ │ │ │ context :-). │ │ │ │ @@ -1361,28 +1363,28 @@ │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ >>> # The format() function. │ │ │ │ >>> print(format('the magic number is %s', 42)) │ │ │ │ the magic number is 42 │ │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ * When you interpolate a single value and someone accidentally passes │ │ │ │ - in a tuple your code raises a _T_y_p_e_E_r_r_o_r. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ + in a tuple your code raises a TypeError. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ _v_a_r_i_a_b_l_e_ _n_u_m_b_e_r_ _o_f_ _a_r_g_u_m_e_n_t_s it always receives a tuple so this can │ │ │ │ never happen. Here’s an example: │ │ │ │ >>> # How expecting to interpolate a single value can fail. │ │ │ │ >>> value = (12, 42) │ │ │ │ >>> print('the magic value is %s' % value) │ │ │ │ Traceback (most recent call last): │ │ │ │ File "", line 1, in │ │ │ │ TypeError: not all arguments converted during string formatting │ │ │ │ >>> # The following line works as intended, no surprises here! │ │ │ │ >>> print(format('the magic value is %s', value)) │ │ │ │ the magic value is (12, 42) │ │ │ │ WWhhyy ffoorrmmaatt(()) iinnsstteeaadd ooff tthhee ssttrr..ffoorrmmaatt(()) mmeetthhoodd?? │ │ │ │ - When you’re doing complex string interpolation the _s_t_r_._f_o_r_m_a_t_(_) function │ │ │ │ + When you’re doing complex string interpolation the str.format() function │ │ │ │ results in more readable code, however I frequently find myself adding │ │ │ │ parentheses to force evaluation order. The _f_o_r_m_a_t_(_) function avoids this │ │ │ │ because of the relative priority between the comma and dot operators. │ │ │ │ Here’s an example: │ │ │ │ >>> "{adjective} example" + " " + "(can't think of anything less │ │ │ │ {adjective})".format(adjective='silly') │ │ │ │ "{adjective} example (can't think of anything less silly)" │ │ │ │ @@ -1405,20 +1407,20 @@ │ │ │ │ The number of times an interactive prompt is shown on invalid input (an │ │ │ │ integer). │ │ │ │ eexxcceeppttiioonn humanfriendly.prompts.TooManyInvalidReplies_¶ │ │ │ │ Raised by interactive prompts when they’ve received too many invalid │ │ │ │ inputs. │ │ │ │ humanfriendly.prompts.prepare_friendly_prompts()_¶ │ │ │ │ Make interactive prompts more user friendly. │ │ │ │ - The prompts presented by _r_a_w___i_n_p_u_t_(_) (in Python 2) and _i_n_p_u_t_(_) (in Python │ │ │ │ - 3) are not very user friendly by default, for example the cursor keys (←, │ │ │ │ - ↑, → and ↓) and the Home and End keys enter characters instead of │ │ │ │ - performing the action you would expect them to. By simply importing the │ │ │ │ - _r_e_a_d_l_i_n_e module these prompts become much friendlier (as mentioned in the │ │ │ │ - Python standard library documentation). │ │ │ │ + The prompts presented by python2:raw_input() (in Python 2) and python3: │ │ │ │ + input() (in Python 3) are not very user friendly by default, for example │ │ │ │ + the cursor keys (←, ↑, → and ↓) and the Home and End keys enter │ │ │ │ + characters instead of performing the action you would expect them to. By │ │ │ │ + simply importing the readline module these prompts become much friendlier │ │ │ │ + (as mentioned in the Python standard library documentation). │ │ │ │ This function is called by the other functions in this module to enable │ │ │ │ user friendly prompts. │ │ │ │ humanfriendly.prompts.prepare_prompt_text(pprroommpptt__tteexxtt, ****ooppttiioonnss)_¶ │ │ │ │ Wrap a text to be rendered as an interactive prompt in ANSI escape │ │ │ │ sequences. │ │ │ │ Parameters: │ │ │ │ * pprroommpptt__tteexxtt – The text to render on the prompt (a string). │ │ │ │ @@ -1429,20 +1431,20 @@ │ │ │ │ connected to a terminal. When the standard input stream is connected to a │ │ │ │ terminal any escape sequences are wrapped in “readline hints”. │ │ │ │ humanfriendly.prompts.prompt_for_choice(cchhooiicceess, ddeeffaauulltt==NNoonnee, ppaaddddiinngg==TTrruuee)_¶ │ │ │ │ Prompt the user to select a choice from a group of options. │ │ │ │ Parameters: │ │ │ │ * cchhooiicceess – A sequence of strings with available options. │ │ │ │ * ddeeffaauulltt – The default choice if the user simply presses Enter │ │ │ │ - (expected to be a string, defaults to _N_o_n_e). │ │ │ │ + (expected to be a string, defaults to None). │ │ │ │ * ppaaddddiinngg – Refer to the documentation of _p_r_o_m_p_t___f_o_r___i_n_p_u_t_(_). │ │ │ │ Returns: │ │ │ │ The string corresponding to the user’s choice. │ │ │ │ Raises: │ │ │ │ - * _V_a_l_u_e_E_r_r_o_r ifchoicesis an empty sequence. │ │ │ │ + * ValueError ifchoicesis an empty sequence. │ │ │ │ * Any exceptions raised by _r_e_t_r_y___l_i_m_i_t_(_). │ │ │ │ * Any exceptions raised by _p_r_o_m_p_t___f_o_r___i_n_p_u_t_(_). │ │ │ │ When no options are given an exception is raised: │ │ │ │ >>> prompt_for_choice([]) │ │ │ │ Traceback (most recent call last): │ │ │ │ File "humanfriendly/prompts.py", line 148, in prompt_for_choice │ │ │ │ raise ValueError("Can't prompt for choice without any options!") │ │ │ │ @@ -1469,27 +1471,27 @@ │ │ │ │ 'first option' │ │ │ │ humanfriendly.prompts.prompt_for_confirmation(qquueessttiioonn, ddeeffaauulltt==NNoonnee, │ │ │ │ ppaaddddiinngg==TTrruuee)_¶ │ │ │ │ Prompt the user for confirmation. │ │ │ │ Parameters: │ │ │ │ * qquueessttiioonn – The text that explains what the user is confirming │ │ │ │ (a string). │ │ │ │ - * ddeeffaauulltt – The default value (a boolean) or _N_o_n_e. │ │ │ │ + * ddeeffaauulltt – The default value (a boolean) or None. │ │ │ │ * ppaaddddiinngg – Refer to the documentation of _p_r_o_m_p_t___f_o_r___i_n_p_u_t_(_). │ │ │ │ Returns: │ │ │ │ - * If the user enters ‘yes’ or ‘y’ then _T_r_u_e is returned. │ │ │ │ - * If the user enters ‘no’ or ‘n’ then _F_a_l_s_e is returned. │ │ │ │ + * If the user enters ‘yes’ or ‘y’ then True is returned. │ │ │ │ + * If the user enters ‘no’ or ‘n’ then False is returned. │ │ │ │ * If the user doesn’t enter any text or standard input is not │ │ │ │ connected to a terminal (which makes it impossible to prompt │ │ │ │ the user) the value of the keyword argument default is │ │ │ │ - returned (if that value is not _N_o_n_e). │ │ │ │ + returned (if that value is not None). │ │ │ │ Raises: │ │ │ │ * Any exceptions raised by _r_e_t_r_y___l_i_m_i_t_(_). │ │ │ │ * Any exceptions raised by _p_r_o_m_p_t___f_o_r___i_n_p_u_t_(_). │ │ │ │ - Whendefaultis _F_a_l_s_e and the user doesn’t enter any text an error message │ │ │ │ + Whendefaultis False and the user doesn’t enter any text an error message │ │ │ │ is printed and the prompt is repeated: │ │ │ │ >>> prompt_for_confirmation("Are you sure?") │ │ │ │ │ │ │ │ Are you sure? [y/n] │ │ │ │ │ │ │ │ Error: Please enter 'yes' or 'no' (there's no default choice). │ │ │ │ │ │ │ │ @@ -1510,27 +1512,27 @@ │ │ │ │ * qquueessttiioonn – An explanation of what is expected from the user │ │ │ │ (a string). │ │ │ │ * ddeeffaauulltt – The return value if the user doesn’t enter any text │ │ │ │ or standard input is not connected to a terminal (which makes │ │ │ │ it impossible to prompt the user). │ │ │ │ * ppaaddddiinngg – Render empty lines before and after the prompt to │ │ │ │ make it stand out from the surrounding text? (a boolean, │ │ │ │ - defaults to _T_r_u_e) │ │ │ │ + defaults to True) │ │ │ │ * ssttrriipp – Strip leading/trailing whitespace from the user’s │ │ │ │ reply? │ │ │ │ Returns: │ │ │ │ The text entered by the user (a string) or the value of │ │ │ │ thedefaultargument. │ │ │ │ Raises: │ │ │ │ - * _K_e_y_b_o_a_r_d_I_n_t_e_r_r_u_p_t when the program is _i_n_t_e_r_r_u_p_t_e_d while the │ │ │ │ + * KeyboardInterrupt when the program is _i_n_t_e_r_r_u_p_t_e_d while the │ │ │ │ prompt is active, for example because the user presses │ │ │ │ _C_o_n_t_r_o_l_-_C. │ │ │ │ - * _E_O_F_E_r_r_o_r when reading from _s_t_a_n_d_a_r_d_ _i_n_p_u_t fails, for example │ │ │ │ + * EOFError when reading from _s_t_a_n_d_a_r_d_ _i_n_p_u_t fails, for example │ │ │ │ because the user presses _C_o_n_t_r_o_l_-_D or because the standard │ │ │ │ - input stream is redirected (only ifdefaultis _N_o_n_e). │ │ │ │ + input stream is redirected (only ifdefaultis None). │ │ │ │ humanfriendly.prompts.retry_limit(lliimmiitt==1100)_¶ │ │ │ │ Allow the user to provide valid input up tolimittimes. │ │ │ │ Parameters: │ │ │ │ lliimmiitt – The maximum number of attempts (a number, defaults to │ │ │ │ _M_A_X___A_T_T_E_M_P_T_S). │ │ │ │ Returns: │ │ │ │ A generator of numbers starting from one. │ │ │ │ @@ -1540,51 +1542,51 @@ │ │ │ │ This function returns a generator for interactive prompts that want to │ │ │ │ repeat on invalid input without getting stuck in infinite loops. │ │ │ │ humanfriendly.prompts.ansi_strip(tteexxtt, rreeaaddlliinnee__hhiinnttss==TTrruuee)_¶ │ │ │ │ Strip ANSI escape sequences from the given string. │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text from which ANSI escape sequences should be │ │ │ │ removed (a string). │ │ │ │ - * rreeaaddlliinnee__hhiinnttss – If _T_r_u_e then readline_strip() is used to │ │ │ │ + * rreeaaddlliinnee__hhiinnttss – If True then readline_strip() is used to │ │ │ │ remove _r_e_a_d_l_i_n_e_ _h_i_n_t_s from the string. │ │ │ │ Returns: │ │ │ │ The text without ANSI escape sequences (a string). │ │ │ │ humanfriendly.prompts.ansi_wrap(tteexxtt, ****kkww)_¶ │ │ │ │ Wrap text in ANSI escape sequences for the given color and/or style(s). │ │ │ │ humanfriendly.prompts.concatenate(iitteemmss, ccoonnjjuunnccttiioonn==''aanndd'', │ │ │ │ sseerriiaall__ccoommmmaa==FFaallssee)_¶ │ │ │ │ Concatenate a list of items in a human friendly way. │ │ │ │ Parameters: │ │ │ │ * iitteemmss – A sequence of strings. │ │ │ │ * ccoonnjjuunnccttiioonn – The word to use before the last item (a string, │ │ │ │ defaults to “and”). │ │ │ │ - * sseerriiaall__ccoommmmaa – _T_r_u_e to use a _s_e_r_i_a_l_ _c_o_m_m_a, _F_a_l_s_e otherwise │ │ │ │ - (defaults to _F_a_l_s_e). │ │ │ │ + * sseerriiaall__ccoommmmaa – True to use a _s_e_r_i_a_l_ _c_o_m_m_a, False otherwise │ │ │ │ + (defaults to False). │ │ │ │ Returns: │ │ │ │ A single string. │ │ │ │ >>> from humanfriendly.text import concatenate │ │ │ │ >>> concatenate(["eggs", "milk", "bread"]) │ │ │ │ 'eggs, milk and bread' │ │ │ │ humanfriendly.prompts.connected_to_terminal(ssttrreeaamm==NNoonnee)_¶ │ │ │ │ Check if a stream is connected to a terminal. │ │ │ │ Parameters: │ │ │ │ ssttrreeaamm – The stream to check (a file-like object, defaults to │ │ │ │ - _s_y_s_._s_t_d_o_u_t). │ │ │ │ + sys.stdout). │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the stream is connected to a terminal, _F_a_l_s_e otherwise. │ │ │ │ + True if the stream is connected to a terminal, False otherwise. │ │ │ │ See also _t_e_r_m_i_n_a_l___s_u_p_p_o_r_t_s___c_o_l_o_r_s_(_). │ │ │ │ humanfriendly.prompts.format(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ - Format a string using the string formatting operator and/or _s_t_r_._f_o_r_m_a_t_(_). │ │ │ │ + Format a string using the string formatting operator and/or str.format(). │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text to format (a string). │ │ │ │ * aarrggss – Any positional arguments are interpolated into the │ │ │ │ text using the string formatting operator (%). If no │ │ │ │ positional arguments are given no interpolation is done. │ │ │ │ * kkww – Any keyword arguments are interpolated into the text │ │ │ │ - using the _s_t_r_._f_o_r_m_a_t_(_) function. If no keyword arguments are │ │ │ │ + using the str.format() function. If no keyword arguments are │ │ │ │ given no interpolation is done. │ │ │ │ Returns: │ │ │ │ The text with any positional and/or keyword arguments interpolated │ │ │ │ (a string). │ │ │ │ The implementation of this function is so trivial that it seems silly to │ │ │ │ even bother writing and documenting it. Justifying this requires some │ │ │ │ context :-). │ │ │ │ @@ -1603,28 +1605,28 @@ │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ >>> # The format() function. │ │ │ │ >>> print(format('the magic number is %s', 42)) │ │ │ │ the magic number is 42 │ │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ * When you interpolate a single value and someone accidentally passes │ │ │ │ - in a tuple your code raises a _T_y_p_e_E_r_r_o_r. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ + in a tuple your code raises a TypeError. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ _v_a_r_i_a_b_l_e_ _n_u_m_b_e_r_ _o_f_ _a_r_g_u_m_e_n_t_s it always receives a tuple so this can │ │ │ │ never happen. Here’s an example: │ │ │ │ >>> # How expecting to interpolate a single value can fail. │ │ │ │ >>> value = (12, 42) │ │ │ │ >>> print('the magic value is %s' % value) │ │ │ │ Traceback (most recent call last): │ │ │ │ File "", line 1, in │ │ │ │ TypeError: not all arguments converted during string formatting │ │ │ │ >>> # The following line works as intended, no surprises here! │ │ │ │ >>> print(format('the magic value is %s', value)) │ │ │ │ the magic value is (12, 42) │ │ │ │ WWhhyy ffoorrmmaatt(()) iinnsstteeaadd ooff tthhee ssttrr..ffoorrmmaatt(()) mmeetthhoodd?? │ │ │ │ - When you’re doing complex string interpolation the _s_t_r_._f_o_r_m_a_t_(_) function │ │ │ │ + When you’re doing complex string interpolation the str.format() function │ │ │ │ results in more readable code, however I frequently find myself adding │ │ │ │ parentheses to force evaluation order. The _f_o_r_m_a_t_(_) function avoids this │ │ │ │ because of the relative priority between the comma and dot operators. │ │ │ │ Here’s an example: │ │ │ │ >>> "{adjective} example" + " " + "(can't think of anything less │ │ │ │ {adjective})".format(adjective='silly') │ │ │ │ "{adjective} example (can't think of anything less silly)" │ │ │ │ @@ -1638,27 +1640,27 @@ │ │ │ │ with whitespace manipulation to make it easy to write nice to read Python │ │ │ │ code. │ │ │ │ humanfriendly.prompts.terminal_supports_colors(ssttrreeaamm==NNoonnee)_¶ │ │ │ │ Check if a stream is connected to a terminal that supports ANSI escape │ │ │ │ sequences. │ │ │ │ Parameters: │ │ │ │ ssttrreeaamm – The stream to check (a file-like object, defaults to │ │ │ │ - _s_y_s_._s_t_d_o_u_t). │ │ │ │ + sys.stdout). │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the terminal supports ANSI escape sequences, _F_a_l_s_e │ │ │ │ + True if the terminal supports ANSI escape sequences, False │ │ │ │ otherwise. │ │ │ │ This function was originally inspired by the implementation of │ │ │ │ _d_j_a_n_g_o_._c_o_r_e_._m_a_n_a_g_e_m_e_n_t_._c_o_l_o_r_._s_u_p_p_o_r_t_s___c_o_l_o_r_(_) but has since evolved │ │ │ │ significantly. │ │ │ │ humanfriendly.prompts.warning(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ Show a warning message on the terminal. │ │ │ │ For details about argument handling please refer to _f_o_r_m_a_t_(_). │ │ │ │ Renders the message using _f_o_r_m_a_t_(_) and writes the resulting string │ │ │ │ - (followed by a newline) to _s_y_s_._s_t_d_e_r_r using auto_encode(). │ │ │ │ - If _s_y_s_._s_t_d_e_r_r is connected to a terminal that supports colors, _a_n_s_i___w_r_a_p │ │ │ │ + (followed by a newline) to sys.stderr using auto_encode(). │ │ │ │ + If sys.stderr is connected to a terminal that supports colors, _a_n_s_i___w_r_a_p │ │ │ │ _(_) is used to color the message in a red font (to make the warning stand │ │ │ │ out from surrounding text). │ │ │ │ ********** _hh_uu_mm_aa_nn_ff_rr_ii_ee_nn_dd_ll_yy_.._ss_pp_hh_ii_nn_xx_?¶ ********** │ │ │ │ Customizations for and integration with the _S_p_h_i_n_x documentation generator. │ │ │ │ The _h_u_m_a_n_f_r_i_e_n_d_l_y_._s_p_h_i_n_x module uses the _S_p_h_i_n_x_ _e_x_t_e_n_s_i_o_n_ _A_P_I to customize the │ │ │ │ process of generating Sphinx based Python documentation. To explore the │ │ │ │ functionality this module offers its best to start reading from the _s_e_t_u_p_(_) │ │ │ │ @@ -1795,37 +1797,37 @@ │ │ │ │ """, filename=self.ports_config)) │ │ │ │ The combination of _c_o_m_p_a_c_t_(_) and Python’s multi line strings allows me to │ │ │ │ write long text fragments with interpolated variables that are easy to │ │ │ │ write, easy to read and work well with Python’s whitespace sensitivity. │ │ │ │ humanfriendly.sphinx.dedent(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ Dedent a string (remove common leading whitespace from all lines). │ │ │ │ Removes common leading whitespace from all lines in the string using │ │ │ │ - _t_e_x_t_w_r_a_p_._d_e_d_e_n_t_(_), removes leading and trailing empty lines using │ │ │ │ + textwrap.dedent(), removes leading and trailing empty lines using │ │ │ │ trim_empty_lines() and interpolates any arguments using _f_o_r_m_a_t_(_). │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text to dedent (a string). │ │ │ │ * aarrggss – Any positional arguments are interpolated using _f_o_r_m_a_t │ │ │ │ _(_). │ │ │ │ * kkww – Any keyword arguments are interpolated using _f_o_r_m_a_t_(_). │ │ │ │ Returns: │ │ │ │ The dedented text (a string). │ │ │ │ The _c_o_m_p_a_c_t_(_) function’s documentation contains an example of how I like │ │ │ │ to use the _c_o_m_p_a_c_t_(_) and _d_e_d_e_n_t_(_) functions. The main difference is that │ │ │ │ I use _c_o_m_p_a_c_t_(_) for text that will be presented to the user (where │ │ │ │ whitespace is not so significant) and _d_e_d_e_n_t_(_) for data file and code │ │ │ │ generation tasks (where newlines and indentation are very significant). │ │ │ │ humanfriendly.sphinx.format(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ - Format a string using the string formatting operator and/or _s_t_r_._f_o_r_m_a_t_(_). │ │ │ │ + Format a string using the string formatting operator and/or str.format(). │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text to format (a string). │ │ │ │ * aarrggss – Any positional arguments are interpolated into the │ │ │ │ text using the string formatting operator (%). If no │ │ │ │ positional arguments are given no interpolation is done. │ │ │ │ * kkww – Any keyword arguments are interpolated into the text │ │ │ │ - using the _s_t_r_._f_o_r_m_a_t_(_) function. If no keyword arguments are │ │ │ │ + using the str.format() function. If no keyword arguments are │ │ │ │ given no interpolation is done. │ │ │ │ Returns: │ │ │ │ The text with any positional and/or keyword arguments interpolated │ │ │ │ (a string). │ │ │ │ The implementation of this function is so trivial that it seems silly to │ │ │ │ even bother writing and documenting it. Justifying this requires some │ │ │ │ context :-). │ │ │ │ @@ -1844,28 +1846,28 @@ │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ >>> # The format() function. │ │ │ │ >>> print(format('the magic number is %s', 42)) │ │ │ │ the magic number is 42 │ │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ * When you interpolate a single value and someone accidentally passes │ │ │ │ - in a tuple your code raises a _T_y_p_e_E_r_r_o_r. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ + in a tuple your code raises a TypeError. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ _v_a_r_i_a_b_l_e_ _n_u_m_b_e_r_ _o_f_ _a_r_g_u_m_e_n_t_s it always receives a tuple so this can │ │ │ │ never happen. Here’s an example: │ │ │ │ >>> # How expecting to interpolate a single value can fail. │ │ │ │ >>> value = (12, 42) │ │ │ │ >>> print('the magic value is %s' % value) │ │ │ │ Traceback (most recent call last): │ │ │ │ File "", line 1, in │ │ │ │ TypeError: not all arguments converted during string formatting │ │ │ │ >>> # The following line works as intended, no surprises here! │ │ │ │ >>> print(format('the magic value is %s', value)) │ │ │ │ the magic value is (12, 42) │ │ │ │ WWhhyy ffoorrmmaatt(()) iinnsstteeaadd ooff tthhee ssttrr..ffoorrmmaatt(()) mmeetthhoodd?? │ │ │ │ - When you’re doing complex string interpolation the _s_t_r_._f_o_r_m_a_t_(_) function │ │ │ │ + When you’re doing complex string interpolation the str.format() function │ │ │ │ results in more readable code, however I frequently find myself adding │ │ │ │ parentheses to force evaluation order. The _f_o_r_m_a_t_(_) function avoids this │ │ │ │ because of the relative priority between the comma and dot operators. │ │ │ │ Here’s an example: │ │ │ │ >>> "{adjective} example" + " " + "(can't think of anything less │ │ │ │ {adjective})".format(adjective='silly') │ │ │ │ "{adjective} example (can't think of anything less silly)" │ │ │ │ @@ -1904,15 +1906,15 @@ │ │ │ │ highlight certain column’s values if you feel like it (for example to │ │ │ │ highlight deviations from the norm in an overview of calculated values). │ │ │ │ humanfriendly.tables.format_pretty_table(ddaattaa, ccoolluummnn__nnaammeess==NNoonnee, │ │ │ │ hhoorriizzoonnttaall__bbaarr==''--'', vveerrttiiccaall__bbaarr==''||'')_¶ │ │ │ │ Render a table using characters like dashes and vertical bars to emulate │ │ │ │ borders. │ │ │ │ Parameters: │ │ │ │ - * ddaattaa – An iterable (e.g. a _t_u_p_l_e_(_) or _l_i_s_t) containing the │ │ │ │ + * ddaattaa – An iterable (e.g. a tuple() or list) containing the │ │ │ │ rows of the table, where each row is an iterable containing │ │ │ │ the columns of the table (strings). │ │ │ │ * ccoolluummnn__nnaammeess – An iterable of column names (strings). │ │ │ │ * hhoorriizzoonnttaall__bbaarr – The character used to represent a horizontal │ │ │ │ bar (a string). │ │ │ │ * vveerrttiiccaall__bbaarr – The character used to represent a vertical bar │ │ │ │ (a string). │ │ │ │ @@ -1949,15 +1951,15 @@ │ │ │ │ what that looks like (my terminals are always set to white text on │ │ │ │ a black background): │ │ │ │ [_images/pretty-table.png] │ │ │ │ humanfriendly.tables.format_robust_table(ddaattaa, ccoolluummnn__nnaammeess)_¶ │ │ │ │ Render tabular data with one column per line (allowing columns with line │ │ │ │ breaks). │ │ │ │ Parameters: │ │ │ │ - * ddaattaa – An iterable (e.g. a _t_u_p_l_e_(_) or _l_i_s_t) containing the │ │ │ │ + * ddaattaa – An iterable (e.g. a tuple() or list) containing the │ │ │ │ rows of the table, where each row is an iterable containing │ │ │ │ the columns of the table (strings). │ │ │ │ * ccoolluummnn__nnaammeess – An iterable of column names (strings). │ │ │ │ Returns: │ │ │ │ The rendered table (a string). │ │ │ │ Here’s an example: │ │ │ │ >>> from humanfriendly.tables import format_robust_table │ │ │ │ @@ -1992,15 +1994,15 @@ │ │ │ │ Downloads: 197 │ │ │ │ ----------------------- │ │ │ │ The column names are highlighted in bold font and color so they stand out │ │ │ │ a bit more (see _H_I_G_H_L_I_G_H_T___C_O_L_O_R). │ │ │ │ humanfriendly.tables.format_rst_table(ddaattaa, ccoolluummnn__nnaammeess==NNoonnee)_¶ │ │ │ │ Render a table in _r_e_S_t_r_u_c_t_u_r_e_d_T_e_x_t format. │ │ │ │ Parameters: │ │ │ │ - * ddaattaa – An iterable (e.g. a _t_u_p_l_e_(_) or _l_i_s_t) containing the │ │ │ │ + * ddaattaa – An iterable (e.g. a tuple() or list) containing the │ │ │ │ rows of the table, where each row is an iterable containing │ │ │ │ the columns of the table (strings). │ │ │ │ * ccoolluummnn__nnaammeess – An iterable of column names (strings). │ │ │ │ Returns: │ │ │ │ The rendered table (a string). │ │ │ │ Here’s an example: │ │ │ │ >>> from humanfriendly.tables import format_rst_table │ │ │ │ @@ -2021,15 +2023,15 @@ │ │ │ │ 1.24 2015-05-26 223 │ │ │ │ 1.25 2015-05-26 4319 │ │ │ │ 1.25.1 2015-06-02 197 │ │ │ │ ======= =========== ========= │ │ │ │ humanfriendly.tables.format_smart_table(ddaattaa, ccoolluummnn__nnaammeess)_¶ │ │ │ │ Render tabular data using the most appropriate representation. │ │ │ │ Parameters: │ │ │ │ - * ddaattaa – An iterable (e.g. a _t_u_p_l_e_(_) or _l_i_s_t) containing the │ │ │ │ + * ddaattaa – An iterable (e.g. a tuple() or list) containing the │ │ │ │ rows of the table, where each row is an iterable containing │ │ │ │ the columns of the table (strings). │ │ │ │ * ccoolluummnn__nnaammeess – An iterable of column names (strings). │ │ │ │ Returns: │ │ │ │ The rendered table (a string). │ │ │ │ If you want an easy way to render tabular data on a terminal in a human │ │ │ │ friendly format then this function is for you! It works as follows: │ │ │ │ @@ -2042,15 +2044,15 @@ │ │ │ │ _f_o_r_m_a_t___r_o_b_u_s_t___t_a_b_l_e_(_) is used to render a more robust table that │ │ │ │ can deal with data containing line breaks and long text. │ │ │ │ humanfriendly.tables.ansi_strip(tteexxtt, rreeaaddlliinnee__hhiinnttss==TTrruuee)_¶ │ │ │ │ Strip ANSI escape sequences from the given string. │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text from which ANSI escape sequences should be │ │ │ │ removed (a string). │ │ │ │ - * rreeaaddlliinnee__hhiinnttss – If _T_r_u_e then readline_strip() is used to │ │ │ │ + * rreeaaddlliinnee__hhiinnttss – If True then readline_strip() is used to │ │ │ │ remove _r_e_a_d_l_i_n_e_ _h_i_n_t_s from the string. │ │ │ │ Returns: │ │ │ │ The text without ANSI escape sequences (a string). │ │ │ │ humanfriendly.tables.ansi_width(tteexxtt)_¶ │ │ │ │ Calculate the effective width of the given text (ignoring ANSI escape │ │ │ │ sequences). │ │ │ │ Parameters: │ │ │ │ @@ -2058,16 +2060,16 @@ │ │ │ │ Returns: │ │ │ │ The width of the text without ANSI escape sequences (an integer). │ │ │ │ This function uses _a_n_s_i___s_t_r_i_p_(_) to strip ANSI escape sequences from the │ │ │ │ given string and returns the length of the resulting string. │ │ │ │ humanfriendly.tables.ansi_wrap(tteexxtt, ****kkww)_¶ │ │ │ │ Wrap text in ANSI escape sequences for the given color and/or style(s). │ │ │ │ humanfriendly.tables.coerce_string(vvaalluuee)_¶ │ │ │ │ - Coerce any value to a Unicode string (_u_n_i_c_o_d_e_(_) in Python 2 and _s_t_r in │ │ │ │ - Python 3). │ │ │ │ + Coerce any value to a Unicode string (python2:unicode() in Python 2 and │ │ │ │ + python3:str in Python 3). │ │ │ │ Parameters: │ │ │ │ vvaalluuee – The value to coerce. │ │ │ │ Returns: │ │ │ │ The value coerced to a Unicode string. │ │ │ │ humanfriendly.tables.find_terminal_size()_¶ │ │ │ │ Determine the number of lines and columns visible in the terminal. │ │ │ │ Returns: │ │ │ │ @@ -2079,25 +2081,25 @@ │ │ │ │ 3. finally DEFAULT_LINES and DEFAULT_COLUMNS are returned. │ │ │ │ Note │ │ │ │ The _f_i_n_d___t_e_r_m_i_n_a_l___s_i_z_e_(_) function performs the steps above every time it │ │ │ │ is called, the result is not cached. This is because the size of a │ │ │ │ virtual terminal can change at any time and the result of │ │ │ │ _f_i_n_d___t_e_r_m_i_n_a_l___s_i_z_e_(_) should be correct. │ │ │ │ _P_r_e_-_e_m_p_t_i_v_e_ _s_n_a_r_k_y_ _c_o_m_m_e_n_t: It’s possible to cache the result of this │ │ │ │ - function and use _s_i_g_n_a_l_._S_I_G_W_I_N_C_H to refresh the cached values! │ │ │ │ + function and use signal.SIGWINCH to refresh the cached values! │ │ │ │ Response: As a library I don’t consider it the role of the │ │ │ │ _h_u_m_a_n_f_r_i_e_n_d_l_y_._t_e_r_m_i_n_a_l module to install a process wide signal handler … │ │ │ │ humanfriendly.tables.terminal_supports_colors(ssttrreeaamm==NNoonnee)_¶ │ │ │ │ Check if a stream is connected to a terminal that supports ANSI escape │ │ │ │ sequences. │ │ │ │ Parameters: │ │ │ │ ssttrreeaamm – The stream to check (a file-like object, defaults to │ │ │ │ - _s_y_s_._s_t_d_o_u_t). │ │ │ │ + sys.stdout). │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the terminal supports ANSI escape sequences, _F_a_l_s_e │ │ │ │ + True if the terminal supports ANSI escape sequences, False │ │ │ │ otherwise. │ │ │ │ This function was originally inspired by the implementation of │ │ │ │ _d_j_a_n_g_o_._c_o_r_e_._m_a_n_a_g_e_m_e_n_t_._c_o_l_o_r_._s_u_p_p_o_r_t_s___c_o_l_o_r_(_) but has since evolved │ │ │ │ significantly. │ │ │ │ ********** _hh_uu_mm_aa_nn_ff_rr_ii_ee_nn_dd_ll_yy_.._tt_ee_rr_mm_ii_nn_aa_ll_?¶ ********** │ │ │ │ Interaction with interactive text terminals. │ │ │ │ The _t_e_r_m_i_n_a_l module makes it easy to interact with interactive text terminals │ │ │ │ @@ -2108,15 +2110,15 @@ │ │ │ │ This module was originally developed for use on UNIX systems, but since then │ │ │ │ Windows 10 gained native support for ANSI escape sequences and this module was │ │ │ │ enhanced to recognize and support this. For details please refer to the │ │ │ │ _e_n_a_b_l_e___a_n_s_i___s_u_p_p_o_r_t_(_) function. │ │ │ │ Note │ │ │ │ Deprecated names │ │ │ │ The following aliases exist to preserve backwards compatibility, however a │ │ │ │ -_D_e_p_r_e_c_a_t_i_o_n_W_a_r_n_i_n_g is triggered when they are accessed, because these aliases │ │ │ │ +DeprecationWarning is triggered when they are accessed, because these aliases │ │ │ │ will be removed in a future release. │ │ │ │ humanfriendly.terminal.find_meta_variables_¶ │ │ │ │ Alias for _h_u_m_a_n_f_r_i_e_n_d_l_y_._u_s_a_g_e_._f_i_n_d___m_e_t_a___v_a_r_i_a_b_l_e_s. │ │ │ │ humanfriendly.terminal.format_usage_¶ │ │ │ │ Alias for _h_u_m_a_n_f_r_i_e_n_d_l_y_._u_s_a_g_e_._f_o_r_m_a_t___u_s_a_g_e. │ │ │ │ humanfriendly.terminal.html_to_ansi_¶ │ │ │ │ Alias for _h_u_m_a_n_f_r_i_e_n_d_l_y_._t_e_r_m_i_n_a_l_._h_t_m_l_._h_t_m_l___t_o___a_n_s_i. │ │ │ │ @@ -2162,25 +2164,25 @@ │ │ │ │ $HUMANFRIENDLY_HIGHLIGHT_COLOR is set it determines the value of │ │ │ │ _H_I_G_H_L_I_G_H_T___C_O_L_O_R. │ │ │ │ humanfriendly.terminal.ansi_strip(tteexxtt, rreeaaddlliinnee__hhiinnttss==TTrruuee)_¶ │ │ │ │ Strip ANSI escape sequences from the given string. │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text from which ANSI escape sequences should be │ │ │ │ removed (a string). │ │ │ │ - * rreeaaddlliinnee__hhiinnttss – If _T_r_u_e then _r_e_a_d_l_i_n_e___s_t_r_i_p_(_) is used to │ │ │ │ + * rreeaaddlliinnee__hhiinnttss – If True then _r_e_a_d_l_i_n_e___s_t_r_i_p_(_) is used to │ │ │ │ remove _r_e_a_d_l_i_n_e_ _h_i_n_t_s from the string. │ │ │ │ Returns: │ │ │ │ The text without ANSI escape sequences (a string). │ │ │ │ humanfriendly.terminal.ansi_style(****kkww)_¶ │ │ │ │ Generate ANSI escape sequences for the given color and/or style(s). │ │ │ │ Returns: │ │ │ │ The ANSI escape sequences to enable the requested text styles or an │ │ │ │ empty string if no styles were requested. │ │ │ │ Raises: │ │ │ │ - _V_a_l_u_e_E_r_r_o_r when an invalid color name is given. │ │ │ │ + ValueError when an invalid color name is given. │ │ │ │ Even though only eight named colors are supported, the use │ │ │ │ ofbright=Trueandfaint=Trueincreases the number of available colors to │ │ │ │ around 24 (it may be slightly lower, for example because faint black is │ │ │ │ just black). │ │ │ │ SSuuppppoorrtt ffoorr 88--bbiitt ccoolloorrss │ │ │ │ In _r_e_l_e_a_s_e_ _4_._7 support for 256 color mode was added. While this │ │ │ │ significantly increases the available colors it’s not very human friendly │ │ │ │ @@ -2208,42 +2210,42 @@ │ │ │ │ given string and returns the length of the resulting string. │ │ │ │ humanfriendly.terminal.ansi_wrap(tteexxtt, ****kkww)_¶ │ │ │ │ Wrap text in ANSI escape sequences for the given color and/or style(s). │ │ │ │ humanfriendly.terminal.auto_encode(ssttrreeaamm, tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ Reliably write Unicode strings to the terminal. │ │ │ │ Parameters: │ │ │ │ * ssttrreeaamm – The file-like object to write to (a value like │ │ │ │ - _s_y_s_._s_t_d_o_u_t or _s_y_s_._s_t_d_e_r_r). │ │ │ │ + sys.stdout or sys.stderr). │ │ │ │ * tteexxtt – The text to write to the stream (a string). │ │ │ │ * aarrggss – Refer to _f_o_r_m_a_t_(_). │ │ │ │ * kkww – Refer to _f_o_r_m_a_t_(_). │ │ │ │ Renders the text using _f_o_r_m_a_t_(_) and writes it to the given stream. If an │ │ │ │ - _U_n_i_c_o_d_e_E_n_c_o_d_e_E_r_r_o_r is encountered in doing so, the text is encoded using │ │ │ │ + UnicodeEncodeError is encountered in doing so, the text is encoded using │ │ │ │ _D_E_F_A_U_L_T___E_N_C_O_D_I_N_G and the write is retried. The reasoning behind this │ │ │ │ rather blunt approach is that it’s preferable to get output on the │ │ │ │ command line in the wrong encoding then to have the Python program blow │ │ │ │ - up with a _U_n_i_c_o_d_e_E_n_c_o_d_e_E_r_r_o_r exception. │ │ │ │ + up with a UnicodeEncodeError exception. │ │ │ │ humanfriendly.terminal.clean_terminal_output(tteexxtt)_¶ │ │ │ │ Clean up the terminal output of a command. │ │ │ │ Parameters: │ │ │ │ tteexxtt – The raw text with special characters (a Unicode string). │ │ │ │ Returns: │ │ │ │ A list of Unicode strings (one for each line). │ │ │ │ This function emulates the effect of backspace (0x08), carriage return │ │ │ │ (0x0D) and line feed (0x0A) characters and the ANSI ‘erase line’ escape │ │ │ │ sequence on interactive terminals. It’s intended to clean up command │ │ │ │ output that was originally meant to be rendered on an interactive │ │ │ │ terminal and that has been captured using e.g. the _s_c_r_i_p_t program _[_3_] or │ │ │ │ - the _p_t_y module _[_4_]. │ │ │ │ + the pty module _[_4_]. │ │ │ │ [_3] │ │ │ │ My _c_o_l_o_r_e_d_l_o_g_s package supports the coloredlogs --to-html command which │ │ │ │ uses _s_c_r_i_p_t to fool a subprocess into thinking that it’s connected to an │ │ │ │ interactive terminal (in order to get it to emit ANSI escape sequences). │ │ │ │ [_4] │ │ │ │ - My _c_a_p_t_u_r_e_r package uses the _p_t_y module to fool the current process and │ │ │ │ + My _c_a_p_t_u_r_e_r package uses the pty module to fool the current process and │ │ │ │ subprocesses into thinking they are connected to an interactive terminal │ │ │ │ (in order to get them to emit ANSI escape sequences). │ │ │ │ SSoommee ccaavveeaattss aabboouutt tthhee uussee ooff tthhiiss ffuunnccttiioonn:: │ │ │ │ * Strictly speaking the effect of carriage returns cannot be emulated │ │ │ │ outside of an actual terminal due to the interaction between │ │ │ │ overlapping output, terminal widths and line wrapping. The goal of │ │ │ │ this function is to sanitize noise in terminal output while │ │ │ │ @@ -2255,26 +2257,26 @@ │ │ │ │ resulting string will contain only the closing end of the ANSI │ │ │ │ escape sequence pair. Tracking this kind of complexity requires a │ │ │ │ state machine and proper parsing. │ │ │ │ humanfriendly.terminal.connected_to_terminal(ssttrreeaamm==NNoonnee)_¶ │ │ │ │ Check if a stream is connected to a terminal. │ │ │ │ Parameters: │ │ │ │ ssttrreeaamm – The stream to check (a file-like object, defaults to │ │ │ │ - _s_y_s_._s_t_d_o_u_t). │ │ │ │ + sys.stdout). │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the stream is connected to a terminal, _F_a_l_s_e otherwise. │ │ │ │ + True if the stream is connected to a terminal, False otherwise. │ │ │ │ See also _t_e_r_m_i_n_a_l___s_u_p_p_o_r_t_s___c_o_l_o_r_s_(_). │ │ │ │ humanfriendly.terminal.enable_ansi_support()_¶ │ │ │ │ Try to enable support for ANSI escape sequences (required on Windows). │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if ANSI is supported, _F_a_l_s_e otherwise. │ │ │ │ + True if ANSI is supported, False otherwise. │ │ │ │ This functions checks for the following supported configurations, in the │ │ │ │ given order: │ │ │ │ 1. On Windows, if _h_a_v_e___w_i_n_d_o_w_s___n_a_t_i_v_e___a_n_s_i___s_u_p_p_o_r_t_(_) confirms native │ │ │ │ - support for ANSI escape sequences _c_t_y_p_e_s will be used to enable │ │ │ │ + support for ANSI escape sequences ctypes will be used to enable │ │ │ │ this support. │ │ │ │ 2. On Windows, if the environment variable $ANSICON is set nothing is │ │ │ │ done because it is assumed that support for ANSI escape sequences │ │ │ │ has already been enabled via _a_n_s_i_c_o_n. │ │ │ │ 3. On Windows, an attempt is made to import and initialize the Python │ │ │ │ package _c_o_l_o_r_a_m_a instead (of course for this to work _c_o_l_o_r_a_m_a has │ │ │ │ to be installed). │ │ │ │ @@ -2297,19 +2299,19 @@ │ │ │ │ 3. finally _D_E_F_A_U_L_T___L_I_N_E_S and _D_E_F_A_U_L_T___C_O_L_U_M_N_S are returned. │ │ │ │ Note │ │ │ │ The _f_i_n_d___t_e_r_m_i_n_a_l___s_i_z_e_(_) function performs the steps above every time it │ │ │ │ is called, the result is not cached. This is because the size of a │ │ │ │ virtual terminal can change at any time and the result of │ │ │ │ _f_i_n_d___t_e_r_m_i_n_a_l___s_i_z_e_(_) should be correct. │ │ │ │ _P_r_e_-_e_m_p_t_i_v_e_ _s_n_a_r_k_y_ _c_o_m_m_e_n_t: It’s possible to cache the result of this │ │ │ │ - function and use _s_i_g_n_a_l_._S_I_G_W_I_N_C_H to refresh the cached values! │ │ │ │ + function and use signal.SIGWINCH to refresh the cached values! │ │ │ │ Response: As a library I don’t consider it the role of the │ │ │ │ _h_u_m_a_n_f_r_i_e_n_d_l_y_._t_e_r_m_i_n_a_l module to install a process wide signal handler … │ │ │ │ humanfriendly.terminal.find_terminal_size_using_ioctl(ssttrreeaamm)_¶ │ │ │ │ - Find the terminal size using _f_c_n_t_l_._i_o_c_t_l_(_). │ │ │ │ + Find the terminal size using fcntl.ioctl(). │ │ │ │ Parameters: │ │ │ │ ssttrreeaamm – A stream connected to the terminal (a file object with a │ │ │ │ fileno attribute). │ │ │ │ Returns: │ │ │ │ A tuple of two integers with the line and column count. │ │ │ │ Raises: │ │ │ │ This function can raise exceptions but I’m not going to document │ │ │ │ @@ -2345,28 +2347,28 @@ │ │ │ │ This ensures that the operator gets a chance to review the text │ │ │ │ (for example a usage message) after quitting the pager, while │ │ │ │ composing the next command. │ │ │ │ humanfriendly.terminal.have_windows_native_ansi_support()_¶ │ │ │ │ Check if we’re running on a Windows 10 release with native support for │ │ │ │ ANSI escape sequences. │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if so, _F_a_l_s_e otherwise. │ │ │ │ + True if so, False otherwise. │ │ │ │ The _c_a_c_h_e_d_(_) decorator is used as a minor performance optimization. │ │ │ │ Semantically this should have zero impact because the answer doesn’t │ │ │ │ change in the lifetime of a computer process. │ │ │ │ humanfriendly.terminal.message(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ Print a formatted message to the standard error stream. │ │ │ │ For details about argument handling please refer to _f_o_r_m_a_t_(_). │ │ │ │ Renders the message using _f_o_r_m_a_t_(_) and writes the resulting string │ │ │ │ - (followed by a newline) to _s_y_s_._s_t_d_e_r_r using _a_u_t_o___e_n_c_o_d_e_(_). │ │ │ │ + (followed by a newline) to sys.stderr using _a_u_t_o___e_n_c_o_d_e_(_). │ │ │ │ humanfriendly.terminal.output(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ Print a formatted message to the standard output stream. │ │ │ │ For details about argument handling please refer to _f_o_r_m_a_t_(_). │ │ │ │ Renders the message using _f_o_r_m_a_t_(_) and writes the resulting string │ │ │ │ - (followed by a newline) to _s_y_s_._s_t_d_o_u_t using _a_u_t_o___e_n_c_o_d_e_(_). │ │ │ │ + (followed by a newline) to sys.stdout using _a_u_t_o___e_n_c_o_d_e_(_). │ │ │ │ humanfriendly.terminal.readline_strip(eexxpprr)_¶ │ │ │ │ Remove _r_e_a_d_l_i_n_e_ _h_i_n_t_s from a string. │ │ │ │ Parameters: │ │ │ │ tteexxtt – The text to strip (a string). │ │ │ │ Returns: │ │ │ │ The stripped text. │ │ │ │ humanfriendly.terminal.readline_wrap(eexxpprr)_¶ │ │ │ │ @@ -2379,47 +2381,47 @@ │ │ │ │ Print a large text to the terminal using a pager. │ │ │ │ Parameters: │ │ │ │ * ffoorrmmaatttteedd__tteexxtt – The text to print to the terminal (a │ │ │ │ string). │ │ │ │ * eennccooddiinngg – The name of the text encoding used to encode the │ │ │ │ formatted text if the formatted text is a Unicode string (a │ │ │ │ string, defaults to _D_E_F_A_U_L_T___E_N_C_O_D_I_N_G). │ │ │ │ - When _c_o_n_n_e_c_t_e_d___t_o___t_e_r_m_i_n_a_l_(_) returns _T_r_u_e a pager is used to show the │ │ │ │ + When _c_o_n_n_e_c_t_e_d___t_o___t_e_r_m_i_n_a_l_(_) returns True a pager is used to show the │ │ │ │ text on the terminal, otherwise the text is printed directly without │ │ │ │ invoking a pager. │ │ │ │ The use of a pager helps to avoid the wall of text effect where the user │ │ │ │ has to scroll up to see where the output began (not very user friendly). │ │ │ │ Refer to _g_e_t___p_a_g_e_r___c_o_m_m_a_n_d_(_) for details about the command line that’s │ │ │ │ used to invoke the pager. │ │ │ │ humanfriendly.terminal.terminal_supports_colors(ssttrreeaamm==NNoonnee)_¶ │ │ │ │ Check if a stream is connected to a terminal that supports ANSI escape │ │ │ │ sequences. │ │ │ │ Parameters: │ │ │ │ ssttrreeaamm – The stream to check (a file-like object, defaults to │ │ │ │ - _s_y_s_._s_t_d_o_u_t). │ │ │ │ + sys.stdout). │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the terminal supports ANSI escape sequences, _F_a_l_s_e │ │ │ │ + True if the terminal supports ANSI escape sequences, False │ │ │ │ otherwise. │ │ │ │ This function was originally inspired by the implementation of │ │ │ │ _d_j_a_n_g_o_._c_o_r_e_._m_a_n_a_g_e_m_e_n_t_._c_o_l_o_r_._s_u_p_p_o_r_t_s___c_o_l_o_r_(_) but has since evolved │ │ │ │ significantly. │ │ │ │ humanfriendly.terminal.usage(uussaaggee__tteexxtt)_¶ │ │ │ │ Print a human friendly usage message to the terminal. │ │ │ │ Parameters: │ │ │ │ tteexxtt – The usage message to print (a string). │ │ │ │ This function does two things: │ │ │ │ - 1. If _s_y_s_._s_t_d_o_u_t is connected to a terminal (see _c_o_n_n_e_c_t_e_d___t_o___t_e_r_m_i_n_a_l │ │ │ │ + 1. If sys.stdout is connected to a terminal (see _c_o_n_n_e_c_t_e_d___t_o___t_e_r_m_i_n_a_l │ │ │ │ _(_)) then the usage message is formatted using _f_o_r_m_a_t___u_s_a_g_e_(_). │ │ │ │ 2. The usage message is shown using a pager (see _s_h_o_w___p_a_g_e_r_(_)). │ │ │ │ humanfriendly.terminal.warning(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ Show a warning message on the terminal. │ │ │ │ For details about argument handling please refer to _f_o_r_m_a_t_(_). │ │ │ │ Renders the message using _f_o_r_m_a_t_(_) and writes the resulting string │ │ │ │ - (followed by a newline) to _s_y_s_._s_t_d_e_r_r using _a_u_t_o___e_n_c_o_d_e_(_). │ │ │ │ - If _s_y_s_._s_t_d_e_r_r is connected to a terminal that supports colors, _a_n_s_i___w_r_a_p │ │ │ │ + (followed by a newline) to sys.stderr using _a_u_t_o___e_n_c_o_d_e_(_). │ │ │ │ + If sys.stderr is connected to a terminal that supports colors, _a_n_s_i___w_r_a_p │ │ │ │ _(_) is used to color the message in a red font (to make the warning stand │ │ │ │ out from surrounding text). │ │ │ │ humanfriendly.terminal.cached(ffuunnccttiioonn)_¶ │ │ │ │ Rudimentary caching decorator for functions. │ │ │ │ Parameters: │ │ │ │ ffuunnccttiioonn – The function whose return value should be cached. │ │ │ │ Returns: │ │ │ │ @@ -2429,43 +2431,43 @@ │ │ │ │ an attribute of the given function and returned on each subsequent call. │ │ │ │ Note │ │ │ │ Currently no function arguments are supported because only a single │ │ │ │ return value can be cached. Accepting any function arguments at all would │ │ │ │ imply that the cache is parametrized on function arguments, which is not │ │ │ │ currently the case. │ │ │ │ humanfriendly.terminal.coerce_string(vvaalluuee)_¶ │ │ │ │ - Coerce any value to a Unicode string (_u_n_i_c_o_d_e_(_) in Python 2 and _s_t_r in │ │ │ │ - Python 3). │ │ │ │ + Coerce any value to a Unicode string (python2:unicode() in Python 2 and │ │ │ │ + python3:str in Python 3). │ │ │ │ Parameters: │ │ │ │ vvaalluuee – The value to coerce. │ │ │ │ Returns: │ │ │ │ The value coerced to a Unicode string. │ │ │ │ humanfriendly.terminal.concatenate(iitteemmss, ccoonnjjuunnccttiioonn==''aanndd'', │ │ │ │ sseerriiaall__ccoommmmaa==FFaallssee)_¶ │ │ │ │ Concatenate a list of items in a human friendly way. │ │ │ │ Parameters: │ │ │ │ * iitteemmss – A sequence of strings. │ │ │ │ * ccoonnjjuunnccttiioonn – The word to use before the last item (a string, │ │ │ │ defaults to “and”). │ │ │ │ - * sseerriiaall__ccoommmmaa – _T_r_u_e to use a _s_e_r_i_a_l_ _c_o_m_m_a, _F_a_l_s_e otherwise │ │ │ │ - (defaults to _F_a_l_s_e). │ │ │ │ + * sseerriiaall__ccoommmmaa – True to use a _s_e_r_i_a_l_ _c_o_m_m_a, False otherwise │ │ │ │ + (defaults to False). │ │ │ │ Returns: │ │ │ │ A single string. │ │ │ │ >>> from humanfriendly.text import concatenate │ │ │ │ >>> concatenate(["eggs", "milk", "bread"]) │ │ │ │ 'eggs, milk and bread' │ │ │ │ humanfriendly.terminal.define_aliases(mmoodduullee__nnaammee, ****aalliiaasseess)_¶ │ │ │ │ Update a module with backwards compatible aliases. │ │ │ │ Parameters: │ │ │ │ * mmoodduullee__nnaammee – The __name__ of the module (a string). │ │ │ │ * aalliiaasseess – Each keyword argument defines an alias. The values │ │ │ │ are expected to be “dotted paths” (strings). │ │ │ │ The behavior of this function depends on whether the Sphinx documentation │ │ │ │ generator is active, because the use of DeprecationProxy to shadow the │ │ │ │ - real module in _s_y_s_._m_o_d_u_l_e_s has the unintended side effect of breaking │ │ │ │ + real module in sys.modules has the unintended side effect of breaking │ │ │ │ autodoc support for :data: members (module variables). │ │ │ │ To avoid breaking Sphinx the proxy object is omitted and instead the │ │ │ │ aliased names are injected into the original module namespace, to make │ │ │ │ sure that imports can be satisfied when the documentation is being │ │ │ │ rendered. │ │ │ │ If you run into cyclic dependencies caused by _d_e_f_i_n_e___a_l_i_a_s_e_s_(_) when │ │ │ │ running Sphinx, you can try moving the call to _d_e_f_i_n_e___a_l_i_a_s_e_s_(_) to the │ │ │ │ @@ -2477,22 +2479,22 @@ │ │ │ │ Returns: │ │ │ │ A list of strings with any meta variables found in the usage │ │ │ │ message. │ │ │ │ When a command line option requires an argument, the convention is to │ │ │ │ format such options as --option=ARG. The text ARG in this example is the │ │ │ │ meta variable. │ │ │ │ humanfriendly.terminal.format(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ - Format a string using the string formatting operator and/or _s_t_r_._f_o_r_m_a_t_(_). │ │ │ │ + Format a string using the string formatting operator and/or str.format(). │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text to format (a string). │ │ │ │ * aarrggss – Any positional arguments are interpolated into the │ │ │ │ text using the string formatting operator (%). If no │ │ │ │ positional arguments are given no interpolation is done. │ │ │ │ * kkww – Any keyword arguments are interpolated into the text │ │ │ │ - using the _s_t_r_._f_o_r_m_a_t_(_) function. If no keyword arguments are │ │ │ │ + using the str.format() function. If no keyword arguments are │ │ │ │ given no interpolation is done. │ │ │ │ Returns: │ │ │ │ The text with any positional and/or keyword arguments interpolated │ │ │ │ (a string). │ │ │ │ The implementation of this function is so trivial that it seems silly to │ │ │ │ even bother writing and documenting it. Justifying this requires some │ │ │ │ context :-). │ │ │ │ @@ -2511,28 +2513,28 @@ │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ >>> # The format() function. │ │ │ │ >>> print(format('the magic number is %s', 42)) │ │ │ │ the magic number is 42 │ │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ * When you interpolate a single value and someone accidentally passes │ │ │ │ - in a tuple your code raises a _T_y_p_e_E_r_r_o_r. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ + in a tuple your code raises a TypeError. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ _v_a_r_i_a_b_l_e_ _n_u_m_b_e_r_ _o_f_ _a_r_g_u_m_e_n_t_s it always receives a tuple so this can │ │ │ │ never happen. Here’s an example: │ │ │ │ >>> # How expecting to interpolate a single value can fail. │ │ │ │ >>> value = (12, 42) │ │ │ │ >>> print('the magic value is %s' % value) │ │ │ │ Traceback (most recent call last): │ │ │ │ File "", line 1, in │ │ │ │ TypeError: not all arguments converted during string formatting │ │ │ │ >>> # The following line works as intended, no surprises here! │ │ │ │ >>> print(format('the magic value is %s', value)) │ │ │ │ the magic value is (12, 42) │ │ │ │ WWhhyy ffoorrmmaatt(()) iinnsstteeaadd ooff tthhee ssttrr..ffoorrmmaatt(()) mmeetthhoodd?? │ │ │ │ - When you’re doing complex string interpolation the _s_t_r_._f_o_r_m_a_t_(_) function │ │ │ │ + When you’re doing complex string interpolation the str.format() function │ │ │ │ results in more readable code, however I frequently find myself adding │ │ │ │ parentheses to force evaluation order. The _f_o_r_m_a_t_(_) function avoids this │ │ │ │ because of the relative priority between the comma and dot operators. │ │ │ │ Here’s an example: │ │ │ │ >>> "{adjective} example" + " " + "(can't think of anything less │ │ │ │ {adjective})".format(adjective='silly') │ │ │ │ "{adjective} example (can't think of anything less silly)" │ │ │ │ @@ -2565,24 +2567,24 @@ │ │ │ │ * ccaallllbbaacckk – Optional callback to pass to _H_T_M_L_C_o_n_v_e_r_t_e_r. │ │ │ │ Returns: │ │ │ │ Text with ANSI escape sequences (a string). │ │ │ │ Please refer to the documentation of the _H_T_M_L_C_o_n_v_e_r_t_e_r class for details │ │ │ │ about the conversion process (like which tags are supported) and an │ │ │ │ example with a screenshot. │ │ │ │ humanfriendly.terminal.is_unicode(vvaalluuee)_¶ │ │ │ │ - Check if a value is a _u_n_i_c_o_d_e_(_) (in Python 2) or _s_t_r (in Python 3) │ │ │ │ - object. │ │ │ │ + Check if a value is a python2:unicode() (in Python 2) or python2:str (in │ │ │ │ + Python 3) object. │ │ │ │ Parameters: │ │ │ │ vvaalluuee – The value to check. │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the value is a Unicode string, _F_a_l_s_e otherwise. │ │ │ │ + True if the value is a Unicode string, False otherwise. │ │ │ │ humanfriendly.terminal.on_windows()_¶ │ │ │ │ Check if we’re running on the Microsoft Windows OS. │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if running Windows, _F_a_l_s_e otherwise. │ │ │ │ + True if running Windows, False otherwise. │ │ │ │ humanfriendly.terminal.which(ccmmdd, mmooddee==11, ppaatthh==NNoonnee)_¶ │ │ │ │ Given a command, mode, and a PATH string, return the path which conforms │ │ │ │ to the given mode on the PATH, or None if there is no such file. │ │ │ │ modedefaults to os.F_OK | os.X_OK.pathdefaults to the result of │ │ │ │ os.environ.get(“PATH”), or can be overridden with a custom search path. │ │ │ │ ********** _hh_uu_mm_aa_nn_ff_rr_ii_ee_nn_dd_ll_yy_.._tt_ee_rr_mm_ii_nn_aa_ll_.._hh_tt_mm_ll_?¶ ********** │ │ │ │ Convert HTML with simple text formatting to text with ANSI escape sequences. │ │ │ │ @@ -2627,15 +2629,15 @@ │ │ │ │ underline. │ │ │ │ *

    ,

    and

     tags are considered block level tags and are
    │ │ │ │              wrapped in vertical whitespace to prevent their content from
    │ │ │ │              “running into” surrounding text. This may cause runs of multiple
    │ │ │ │              empty lines to be emitted. As a wwoorrkkaarroouunndd the _____c_a_l_l_____(_) method
    │ │ │ │              will automatically call _c_o_m_p_a_c_t___e_m_p_t_y___l_i_n_e_s_(_) on the generated
    │ │ │ │              output before returning it to the caller. Of course this won’t work
    │ │ │ │ -            whenoutputis set to something like _s_y_s_._s_t_d_o_u_t.
    │ │ │ │ +            whenoutputis set to something like sys.stdout.
    │ │ │ │            * 
    is converted to a single plain text line break. │ │ │ │ Implementation notes: │ │ │ │ * A list of dictionaries with style information is used as a stack │ │ │ │ where new styling can be pushed and a pop will restore the previous │ │ │ │ styling. When new styling is pushed, it is merged with (but │ │ │ │ overrides) the current styling. │ │ │ │ * If you’re going to be converting a lot of HTML it might be useful │ │ │ │ @@ -2656,35 +2658,35 @@ │ │ │ │ * ccaallllbbaacckk – Optional keyword argument to specify a │ │ │ │ function that will be called to process text fragments │ │ │ │ before they are emitted on the output stream. Note that │ │ │ │ link text and preformatted text fragments are not │ │ │ │ processed by this callback. │ │ │ │ * oouuttppuutt – Optional keyword argument to redirect the │ │ │ │ output to the given file-like object. If this is not │ │ │ │ - given a new _S_t_r_i_n_g_I_O object is created. │ │ │ │ + given a new StringIO object is created. │ │ │ │ __call__(ddaattaa)_¶ │ │ │ │ Reset the parser, convert some HTML and get the text with ANSI │ │ │ │ escape sequences. │ │ │ │ Parameters: │ │ │ │ ddaattaa – The HTML to convert to text (a string). │ │ │ │ Returns: │ │ │ │ - The converted text (only in caseoutputis a _S_t_r_i_n_g_I_O object). │ │ │ │ + The converted text (only in caseoutputis a StringIO object). │ │ │ │ pprrooppeerrttyy current_style_¶ │ │ │ │ Get the current style from the top of the stack (a dictionary). │ │ │ │ close()_¶ │ │ │ │ Close previously opened ANSI escape sequences. │ │ │ │ This method overrides the same method in the superclass to ensure │ │ │ │ that an _A_N_S_I___R_E_S_E_T code is emitted when parsing reaches the end of │ │ │ │ the input but a style is still active. This is intended to prevent │ │ │ │ malformed HTML from messing up terminal output. │ │ │ │ emit_style(ssttyyllee==NNoonnee)_¶ │ │ │ │ Emit an ANSI escape sequence for the given or current style to the │ │ │ │ output stream. │ │ │ │ Parameters: │ │ │ │ - ssttyyllee – A dictionary with arguments for _a_n_s_i___s_t_y_l_e_(_) or _N_o_n_e, │ │ │ │ + ssttyyllee – A dictionary with arguments for _a_n_s_i___s_t_y_l_e_(_) or None, │ │ │ │ in which case the style at the top of the stack is emitted. │ │ │ │ handle_charref(vvaalluuee)_¶ │ │ │ │ Process a decimal or hexadecimal numeric character reference. │ │ │ │ Parameters: │ │ │ │ vvaalluuee – The decimal or hexadecimal value (a string). │ │ │ │ handle_data(ddaattaa)_¶ │ │ │ │ Process textual data. │ │ │ │ @@ -2710,15 +2712,15 @@ │ │ │ │ Returns: │ │ │ │ The normalized URL (a string). │ │ │ │ parse_color(vvaalluuee)_¶ │ │ │ │ Convert a CSS color to something that _a_n_s_i___s_t_y_l_e_(_) understands. │ │ │ │ Parameters: │ │ │ │ vvaalluuee – A string like rgb(1,2,3), #AABBCC or yellow. │ │ │ │ Returns: │ │ │ │ - A color value supported by _a_n_s_i___s_t_y_l_e_(_) or _N_o_n_e. │ │ │ │ + A color value supported by _a_n_s_i___s_t_y_l_e_(_) or None. │ │ │ │ push_styles(****cchhaannggeess)_¶ │ │ │ │ Push new style information onto the stack. │ │ │ │ Parameters: │ │ │ │ cchhaannggeess – Any keyword arguments are passed on to _a_n_s_i___s_t_y_l_e │ │ │ │ _(_). │ │ │ │ This method is a helper for _h_a_n_d_l_e___s_t_a_r_t_t_a_g_(_) that does the │ │ │ │ following: │ │ │ │ @@ -2737,23 +2739,23 @@ │ │ │ │ This method pre-processes a URL before rendering on the terminal. │ │ │ │ The following modifications are made: │ │ │ │ * The mailto: prefix is stripped. │ │ │ │ * Spaces are converted to %20. │ │ │ │ * A trailing parenthesis is converted to %29. │ │ │ │ reset()_¶ │ │ │ │ Reset the state of the HTML parser and ANSI converter. │ │ │ │ - Whenoutputis a _S_t_r_i_n_g_I_O object a new instance will be created (and │ │ │ │ + Whenoutputis a StringIO object a new instance will be created (and │ │ │ │ the old one garbage collected). │ │ │ │ urls_match(aa, bb)_¶ │ │ │ │ Compare two URLs for equality using _n_o_r_m_a_l_i_z_e___u_r_l_(_). │ │ │ │ Parameters: │ │ │ │ * aa – A string containing a URL. │ │ │ │ * bb – A string containing a URL. │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the URLs are the same, _F_a_l_s_e otherwise. │ │ │ │ + True if the URLs are the same, False otherwise. │ │ │ │ This method is used by _h_a_n_d_l_e___e_n_d_t_a_g_(_) to omit the URL of a │ │ │ │ hyperlink () when the link text is that same URL. │ │ │ │ humanfriendly.terminal.html.html_to_ansi(ddaattaa, ccaallllbbaacckk==NNoonnee)_¶ │ │ │ │ Convert HTML with simple text formatting to text with ANSI escape │ │ │ │ sequences. │ │ │ │ Parameters: │ │ │ │ * ddaattaa – The HTML to convert (a string). │ │ │ │ @@ -2765,15 +2767,15 @@ │ │ │ │ example with a screenshot. │ │ │ │ humanfriendly.terminal.html.ansi_style(****kkww)_¶ │ │ │ │ Generate ANSI escape sequences for the given color and/or style(s). │ │ │ │ Returns: │ │ │ │ The ANSI escape sequences to enable the requested text styles or an │ │ │ │ empty string if no styles were requested. │ │ │ │ Raises: │ │ │ │ - _V_a_l_u_e_E_r_r_o_r when an invalid color name is given. │ │ │ │ + ValueError when an invalid color name is given. │ │ │ │ Even though only eight named colors are supported, the use │ │ │ │ ofbright=Trueandfaint=Trueincreases the number of available colors to │ │ │ │ around 24 (it may be slightly lower, for example because faint black is │ │ │ │ just black). │ │ │ │ SSuuppppoorrtt ffoorr 88--bbiitt ccoolloorrss │ │ │ │ In _r_e_l_e_a_s_e_ _4_._7 support for 256 color mode was added. While this │ │ │ │ significantly increases the available colors it’s not very human friendly │ │ │ │ @@ -2857,30 +2859,30 @@ │ │ │ │ used as context managers to automatically call _S_p_i_n_n_e_r_._c_l_e_a_r_(_) when the spinner │ │ │ │ ends. │ │ │ │ ccllaassss humanfriendly.terminal.spinners.AutomaticSpinner(llaabbeell, │ │ │ │ sshhooww__ttiimmee==TTrruuee)_¶ │ │ │ │ Show a spinner on the terminal that automatically starts animating. │ │ │ │ This class shows a spinner on the terminal (just like _S_p_i_n_n_e_r does) that │ │ │ │ automatically starts animating. This class should be used as a context │ │ │ │ - manager using the _w_i_t_h statement. The animation continues for as long as │ │ │ │ + manager using the with statement. The animation continues for as long as │ │ │ │ the context is active. │ │ │ │ _A_u_t_o_m_a_t_i_c_S_p_i_n_n_e_r provides an alternative to _S_p_i_n_n_e_r for situations where │ │ │ │ it is not practical for the caller to periodically call _s_t_e_p_(_) to advance │ │ │ │ the animation, e.g. because you’re performing a blocking call and don’t │ │ │ │ fancy implementing threading or subprocess handling just to provide some │ │ │ │ user feedback. │ │ │ │ - This works using the _m_u_l_t_i_p_r_o_c_e_s_s_i_n_g module by spawning a subprocess to │ │ │ │ + This works using the multiprocessing module by spawning a subprocess to │ │ │ │ render the spinner while the main process is busy doing something more │ │ │ │ - useful. By using the _w_i_t_h statement you’re guaranteed that the subprocess │ │ │ │ + useful. By using the with statement you’re guaranteed that the subprocess │ │ │ │ is properly terminated at the appropriate time. │ │ │ │ __init__(llaabbeell, sshhooww__ttiimmee==TTrruuee)_¶ │ │ │ │ Initialize an automatic spinner. │ │ │ │ Parameters: │ │ │ │ * llaabbeell – The label for the spinner (a string). │ │ │ │ - * sshhooww__ttiimmee – If this is _T_r_u_e (the default) then the │ │ │ │ + * sshhooww__ttiimmee – If this is True (the default) then the │ │ │ │ spinner shows elapsed time. │ │ │ │ __enter__()_¶ │ │ │ │ Enable the use of automatic spinners as context managers. │ │ │ │ __exit__(eexxcc__ttyyppee==NNoonnee, eexxcc__vvaalluuee==NNoonnee, ttrraacceebbaacckk==NNoonnee)_¶ │ │ │ │ Enable the use of automatic spinners as context managers. │ │ │ │ humanfriendly.terminal.spinners.GLYPHS == [[''--'',, ''\\\\'',, ''||'',, ''//'']]_¶ │ │ │ │ A list of strings with characters that together form a crude animation :- │ │ │ │ @@ -2889,23 +2891,23 @@ │ │ │ │ Spinners are redrawn with a frequency no higher than this number (a │ │ │ │ floating point number of seconds). │ │ │ │ ccllaassss humanfriendly.terminal.spinners.Spinner(****ooppttiioonnss)_¶ │ │ │ │ Show a spinner on the terminal as a simple means of feedback to the user. │ │ │ │ __init__(****ooppttiioonnss)_¶ │ │ │ │ Initialize a _S_p_i_n_n_e_r object. │ │ │ │ Parameters: │ │ │ │ - * llaabbeell – The label for the spinner (a string or _N_o_n_e, │ │ │ │ - defaults to _N_o_n_e). │ │ │ │ + * llaabbeell – The label for the spinner (a string or None, │ │ │ │ + defaults to None). │ │ │ │ * ttoottaall – The expected number of steps (an integer or │ │ │ │ - _N_o_n_e). If this is provided the spinner will show a │ │ │ │ + None). If this is provided the spinner will show a │ │ │ │ progress percentage. │ │ │ │ * ssttrreeaamm – The output stream to show the spinner on (a │ │ │ │ - file-like object, defaults to _s_y_s_._s_t_d_e_r_r). │ │ │ │ - * iinntteerraaccttiivvee – _T_r_u_e to enable rendering of the spinner, │ │ │ │ - _F_a_l_s_e to disable (defaults to the result of │ │ │ │ + file-like object, defaults to sys.stderr). │ │ │ │ + * iinntteerraaccttiivvee – True to enable rendering of the spinner, │ │ │ │ + False to disable (defaults to the result of │ │ │ │ stream.isatty()). │ │ │ │ * ttiimmeerr – A _T_i_m_e_r object (optional). If this is given the │ │ │ │ spinner will show the elapsed time according to the │ │ │ │ timer. │ │ │ │ * iinntteerrvvaall – The spinner will be updated at most once │ │ │ │ every this many seconds (a floating point number, │ │ │ │ defaults to _M_I_N_I_M_U_M___I_N_T_E_R_V_A_L). │ │ │ │ @@ -2985,24 +2987,24 @@ │ │ │ │ please switch to keyword arguments │ │ │ │ this will give a deprecation warning │ │ │ │ But when the function is called with keyword arguments no deprecation │ │ │ │ warning is emitted: │ │ │ │ >>> report_choice(text='this will not give a deprecation warning') │ │ │ │ this will not give a deprecation warning │ │ │ │ ********** _hh_uu_mm_aa_nn_ff_rr_ii_ee_nn_dd_ll_yy_.._tt_ee_ss_tt_ii_nn_gg_?¶ ********** │ │ │ │ -Utility classes and functions that make it easy to write _u_n_i_t_t_e_s_t compatible │ │ │ │ +Utility classes and functions that make it easy to write unittest compatible │ │ │ │ test suites. │ │ │ │ Over the years I’ve developed the habit of writing test suites for Python │ │ │ │ -projects using the _u_n_i_t_t_e_s_t module. During those years I’ve come to know _p_y_t_e_s_t │ │ │ │ +projects using the unittest module. During those years I’ve come to know _p_y_t_e_s_t │ │ │ │ and in fact I use _p_y_t_e_s_t to run my test suites (due to its much better error │ │ │ │ reporting) but I’ve yet to publish a test suite that rreeqquuiirreess _p_y_t_e_s_t. I have │ │ │ │ several reasons for doing so: │ │ │ │ * It’s nice to keep my test suites as simple and accessible as possible and │ │ │ │ not requiring a specific test runner is part of that attitude. │ │ │ │ - * Whereas _u_n_i_t_t_e_s_t is quite explicit, _p_y_t_e_s_t contains a lot of magic, which │ │ │ │ + * Whereas unittest is quite explicit, _p_y_t_e_s_t contains a lot of magic, which │ │ │ │ kind of contradicts the Python mantra “explicit is better than implicit” │ │ │ │ (IMHO). │ │ │ │ eexxcceeppttiioonn humanfriendly.testing.CallableTimedOut_¶ │ │ │ │ Raised by _r_e_t_r_y_(_) when the timeout expires. │ │ │ │ ccllaassss humanfriendly.testing.CaptureBuffer(iinniittiiaall__vvaalluuee=='''', nneewwlliinnee==''\\nn'')_¶ │ │ │ │ Helper for _C_a_p_t_u_r_e_O_u_t_p_u_t to provide an easy to use API. │ │ │ │ The two methods defined by this subclass were specifically chosen to │ │ │ │ @@ -3011,195 +3013,195 @@ │ │ │ │ interactive terminal (tty). │ │ │ │ get_lines()_¶ │ │ │ │ Get the contents of the buffer split into separate lines. │ │ │ │ get_text()_¶ │ │ │ │ Get the contents of the buffer as a Unicode string. │ │ │ │ ccllaassss humanfriendly.testing.CaptureOutput(mmeerrggeedd==FFaallssee, iinnppuutt=='''', │ │ │ │ eennaabblleedd==TTrruuee)_¶ │ │ │ │ - Context manager that captures what’s written to _s_y_s_._s_t_d_o_u_t and │ │ │ │ - _s_y_s_._s_t_d_e_r_r. │ │ │ │ + Context manager that captures what’s written to sys.stdout and │ │ │ │ + sys.stderr. │ │ │ │ stdin_¶ │ │ │ │ The _S_t_r_i_n_g_I_O object used to feed the standard input stream. │ │ │ │ stdout_¶ │ │ │ │ The _C_a_p_t_u_r_e_B_u_f_f_e_r object used to capture the standard output │ │ │ │ stream. │ │ │ │ stderr_¶ │ │ │ │ The _C_a_p_t_u_r_e_B_u_f_f_e_r object used to capture the standard error stream. │ │ │ │ __init__(mmeerrggeedd==FFaallssee, iinnppuutt=='''', eennaabblleedd==TTrruuee)_¶ │ │ │ │ Initialize a _C_a_p_t_u_r_e_O_u_t_p_u_t object. │ │ │ │ Parameters: │ │ │ │ - * mmeerrggeedd – _T_r_u_e to merge the streams, _F_a_l_s_e to capture │ │ │ │ + * mmeerrggeedd – True to merge the streams, False to capture │ │ │ │ them separately. │ │ │ │ - * iinnppuutt – The data that reads from _s_y_s_._s_t_d_i_n should │ │ │ │ + * iinnppuutt – The data that reads from sys.stdin should │ │ │ │ return (a string). │ │ │ │ - * eennaabblleedd – _T_r_u_e to enable capturing (the default), _F_a_l_s_e │ │ │ │ + * eennaabblleedd – True to enable capturing (the default), False │ │ │ │ otherwise. This makes it easy to unconditionally use │ │ │ │ - _C_a_p_t_u_r_e_O_u_t_p_u_t in a _w_i_t_h block while preserving the │ │ │ │ + _C_a_p_t_u_r_e_O_u_t_p_u_t in a with block while preserving the │ │ │ │ choice to opt out of capturing output. │ │ │ │ __enter__()_¶ │ │ │ │ - Start capturing what’s written to _s_y_s_._s_t_d_o_u_t and _s_y_s_._s_t_d_e_r_r. │ │ │ │ + Start capturing what’s written to sys.stdout and sys.stderr. │ │ │ │ __exit__(eexxcc__ttyyppee==NNoonnee, eexxcc__vvaalluuee==NNoonnee, ttrraacceebbaacckk==NNoonnee)_¶ │ │ │ │ - Stop capturing what’s written to _s_y_s_._s_t_d_o_u_t and _s_y_s_._s_t_d_e_r_r. │ │ │ │ + Stop capturing what’s written to sys.stdout and sys.stderr. │ │ │ │ get_lines()_¶ │ │ │ │ Get the contents of _s_t_d_o_u_t split into separate lines. │ │ │ │ get_text()_¶ │ │ │ │ Get the contents of _s_t_d_o_u_t as a Unicode string. │ │ │ │ getvalue()_¶ │ │ │ │ - Get the text written to _s_y_s_._s_t_d_o_u_t. │ │ │ │ + Get the text written to sys.stdout. │ │ │ │ ccllaassss humanfriendly.testing.ContextManager_¶ │ │ │ │ Base class to enable composition of context managers. │ │ │ │ __enter__()_¶ │ │ │ │ Enable use as context managers. │ │ │ │ __exit__(eexxcc__ttyyppee==NNoonnee, eexxcc__vvaalluuee==NNoonnee, ttrraacceebbaacckk==NNoonnee)_¶ │ │ │ │ Enable use as context managers. │ │ │ │ ccllaassss humanfriendly.testing.CustomSearchPath(iissoollaatteedd==FFaallssee)_¶ │ │ │ │ Context manager to temporarily customize $PATH (the executable search │ │ │ │ path). │ │ │ │ This class is a composition of the _P_a_t_c_h_e_d_I_t_e_m and _T_e_m_p_o_r_a_r_y_D_i_r_e_c_t_o_r_y │ │ │ │ context managers. │ │ │ │ __init__(iissoollaatteedd==FFaallssee)_¶ │ │ │ │ Initialize a _C_u_s_t_o_m_S_e_a_r_c_h_P_a_t_h object. │ │ │ │ Parameters: │ │ │ │ - iissoollaatteedd – _T_r_u_e to clear the original search path, _F_a_l_s_e to │ │ │ │ + iissoollaatteedd – True to clear the original search path, False to │ │ │ │ add the temporary directory to the start of the search path. │ │ │ │ __enter__()_¶ │ │ │ │ Activate the custom $PATH. │ │ │ │ Returns: │ │ │ │ The pathname of the directory that has been added to $PATH (a │ │ │ │ string). │ │ │ │ __exit__(eexxcc__ttyyppee==NNoonnee, eexxcc__vvaalluuee==NNoonnee, ttrraacceebbaacckk==NNoonnee)_¶ │ │ │ │ Deactivate the custom $PATH. │ │ │ │ pprrooppeerrttyy current_search_path_¶ │ │ │ │ - The value of $PATH or _o_s_._d_e_f_p_a_t_h (a string). │ │ │ │ + The value of $PATH or os.defpath (a string). │ │ │ │ ccllaassss humanfriendly.testing.MockedProgram(nnaammee, rreettuurrnnccooddee==00, ssccrriipptt==NNoonnee)_¶ │ │ │ │ Context manager to mock the existence of a program (executable). │ │ │ │ This class extends the functionality of _C_u_s_t_o_m_S_e_a_r_c_h_P_a_t_h. │ │ │ │ __init__(nnaammee, rreettuurrnnccooddee==00, ssccrriipptt==NNoonnee)_¶ │ │ │ │ Initialize a _M_o_c_k_e_d_P_r_o_g_r_a_m object. │ │ │ │ Parameters: │ │ │ │ * nnaammee – The name of the program (a string). │ │ │ │ * rreettuurrnnccooddee – The return code that the program should │ │ │ │ emit (a number, defaults to zero). │ │ │ │ * ssccrriipptt – Shell script code to include in the mocked │ │ │ │ - program (a string or _N_o_n_e). This can be used to mock a │ │ │ │ + program (a string or None). This can be used to mock a │ │ │ │ program that is expected to generate specific output. │ │ │ │ __enter__()_¶ │ │ │ │ Create the mock program. │ │ │ │ Returns: │ │ │ │ The pathname of the directory that has been added to $PATH (a │ │ │ │ string). │ │ │ │ __exit__(**aarrggss, ****kkww)_¶ │ │ │ │ Ensure that the mock program was run. │ │ │ │ Raises: │ │ │ │ - _A_s_s_e_r_t_i_o_n_E_r_r_o_r when the mock program hasn’t been run. │ │ │ │ + AssertionError when the mock program hasn’t been run. │ │ │ │ ccllaassss humanfriendly.testing.PatchedAttribute(oobbjj, nnaammee, vvaalluuee)_¶ │ │ │ │ - Context manager that temporary replaces an object attribute using _s_e_t_a_t_t_r │ │ │ │ - _(_). │ │ │ │ + Context manager that temporary replaces an object attribute using setattr │ │ │ │ + (). │ │ │ │ __init__(oobbjj, nnaammee, vvaalluuee)_¶ │ │ │ │ Initialize a _P_a_t_c_h_e_d_A_t_t_r_i_b_u_t_e object. │ │ │ │ Parameters: │ │ │ │ * oobbjj – The object to patch. │ │ │ │ * nnaammee – An attribute name. │ │ │ │ * vvaalluuee – The value to set. │ │ │ │ __enter__()_¶ │ │ │ │ Replace (patch) the attribute. │ │ │ │ Returns: │ │ │ │ The object whose attribute was patched. │ │ │ │ __exit__(eexxcc__ttyyppee==NNoonnee, eexxcc__vvaalluuee==NNoonnee, ttrraacceebbaacckk==NNoonnee)_¶ │ │ │ │ Restore the attribute to its original value. │ │ │ │ ccllaassss humanfriendly.testing.PatchedItem(oobbjj, iitteemm, vvaalluuee)_¶ │ │ │ │ - Context manager that temporary replaces an object item using _____s_e_t_i_t_e_m____ │ │ │ │ - _(_). │ │ │ │ + Context manager that temporary replaces an object item using __setitem__ │ │ │ │ + (). │ │ │ │ __init__(oobbjj, iitteemm, vvaalluuee)_¶ │ │ │ │ Initialize a _P_a_t_c_h_e_d_I_t_e_m object. │ │ │ │ Parameters: │ │ │ │ * oobbjj – The object to patch. │ │ │ │ * iitteemm – The item to patch. │ │ │ │ * vvaalluuee – The value to set. │ │ │ │ __enter__()_¶ │ │ │ │ Replace (patch) the item. │ │ │ │ Returns: │ │ │ │ The object whose item was patched. │ │ │ │ __exit__(eexxcc__ttyyppee==NNoonnee, eexxcc__vvaalluuee==NNoonnee, ttrraacceebbaacckk==NNoonnee)_¶ │ │ │ │ Restore the item to its original value. │ │ │ │ ccllaassss humanfriendly.testing.TemporaryDirectory(****ooppttiioonnss)_¶ │ │ │ │ - Easy temporary directory creation & cleanup using the _w_i_t_h statement. │ │ │ │ + Easy temporary directory creation & cleanup using the with statement. │ │ │ │ Here’s an example of how to use this: │ │ │ │ with TemporaryDirectory() as directory: │ │ │ │ # Do something useful here. │ │ │ │ assert os.path.isdir(directory) │ │ │ │ __init__(****ooppttiioonnss)_¶ │ │ │ │ Initialize a _T_e_m_p_o_r_a_r_y_D_i_r_e_c_t_o_r_y object. │ │ │ │ Parameters: │ │ │ │ ooppttiioonnss – Any keyword arguments are passed on to │ │ │ │ - _t_e_m_p_f_i_l_e_._m_k_d_t_e_m_p_(_). │ │ │ │ + tempfile.mkdtemp(). │ │ │ │ __enter__()_¶ │ │ │ │ - Create the temporary directory using _t_e_m_p_f_i_l_e_._m_k_d_t_e_m_p_(_). │ │ │ │ + Create the temporary directory using tempfile.mkdtemp(). │ │ │ │ Returns: │ │ │ │ The pathname of the directory (a string). │ │ │ │ __exit__(eexxcc__ttyyppee==NNoonnee, eexxcc__vvaalluuee==NNoonnee, ttrraacceebbaacckk==NNoonnee)_¶ │ │ │ │ - Cleanup the temporary directory using _s_h_u_t_i_l_._r_m_t_r_e_e_(_). │ │ │ │ + Cleanup the temporary directory using shutil.rmtree(). │ │ │ │ ccllaassss humanfriendly.testing.TestCase(**aarrggss, ****kkww)_¶ │ │ │ │ - Subclass of _u_n_i_t_t_e_s_t_._T_e_s_t_C_a_s_e with automatic logging and other │ │ │ │ + Subclass of unittest.TestCase with automatic logging and other │ │ │ │ miscellaneous features. │ │ │ │ __init__(**aarrggss, ****kkww)_¶ │ │ │ │ Initialize a _T_e_s_t_C_a_s_e object. │ │ │ │ Any positional and/or keyword arguments are passed on to the │ │ │ │ initializer of the superclass. │ │ │ │ setUp(lloogg__lleevveell==llooggggiinngg..DDEEBBUUGG)_¶ │ │ │ │ Automatically configure logging to the terminal. │ │ │ │ Parameters: │ │ │ │ lloogg__lleevveell – Refer to _c_o_n_f_i_g_u_r_e___l_o_g_g_i_n_g_(_). │ │ │ │ - The _s_e_t_U_p_(_) method is automatically called by _u_n_i_t_t_e_s_t_._T_e_s_t_C_a_s_e │ │ │ │ + The _s_e_t_U_p_(_) method is automatically called by unittest.TestCase │ │ │ │ before each test method starts. It does two things: │ │ │ │ * Logging to the terminal is configured using _c_o_n_f_i_g_u_r_e___l_o_g_g_i_n_g │ │ │ │ _(_). │ │ │ │ * Before the test method starts a newline is emitted, to │ │ │ │ separate the name of the test method (which will be printed │ │ │ │ - to the terminal by _u_n_i_t_t_e_s_t or _p_y_t_e_s_t) from the first line of │ │ │ │ + to the terminal by unittest or _p_y_t_e_s_t) from the first line of │ │ │ │ logging output that the test method is likely going to │ │ │ │ generate. │ │ │ │ humanfriendly.testing.configure_logging(lloogg__lleevveell==llooggggiinngg..DDEEBBUUGG)_¶ │ │ │ │ Automatically configure logging to the terminal. │ │ │ │ Parameters: │ │ │ │ lloogg__lleevveell – The log verbosity (a number, defaults to │ │ │ │ - _l_o_g_g_i_n_g_._D_E_B_U_G). │ │ │ │ - When _c_o_l_o_r_e_d_l_o_g_s is installed _c_o_l_o_r_e_d_l_o_g_s_._i_n_s_t_a_l_l_(_) will be used to │ │ │ │ - configure logging to the terminal. When this fails with an _I_m_p_o_r_t_E_r_r_o_r │ │ │ │ - then _l_o_g_g_i_n_g_._b_a_s_i_c_C_o_n_f_i_g_(_) is used as a fall back. │ │ │ │ + logging.DEBUG). │ │ │ │ + When coloredlogs is installed coloredlogs.install() will be used to │ │ │ │ + configure logging to the terminal. When this fails with an ImportError │ │ │ │ + then logging.basicConfig() is used as a fall back. │ │ │ │ humanfriendly.testing.make_dirs(ppaatthhnnaammee)_¶ │ │ │ │ Create missing directories. │ │ │ │ Parameters: │ │ │ │ ppaatthhnnaammee – The pathname of a directory (a string). │ │ │ │ humanfriendly.testing.retry(ffuunncc, ttiimmeeoouutt==6600, eexxcc__ttyyppee==AAsssseerrttiioonnEErrrroorr)_¶ │ │ │ │ Retry a function until assertions no longer fail. │ │ │ │ Parameters: │ │ │ │ - * ffuunncc – A callable. When the callable returns _F_a_l_s_e it will │ │ │ │ + * ffuunncc – A callable. When the callable returns False it will │ │ │ │ also be retried. │ │ │ │ * ttiimmeeoouutt – The number of seconds after which to abort (a │ │ │ │ number, defaults to 60). │ │ │ │ * eexxcc__ttyyppee – The type of exceptions to retry (defaults to │ │ │ │ - _A_s_s_e_r_t_i_o_n_E_r_r_o_r). │ │ │ │ + AssertionError). │ │ │ │ Returns: │ │ │ │ The value returned byfunc. │ │ │ │ Raises: │ │ │ │ Once the timeout has expired _r_e_t_r_y_(_) will raise the previously │ │ │ │ - retried assertion error. Whenfunckeeps returning _F_a_l_s_e │ │ │ │ + retried assertion error. Whenfunckeeps returning False │ │ │ │ untiltimeoutexpires _C_a_l_l_a_b_l_e_T_i_m_e_d_O_u_t will be raised. │ │ │ │ This function sleeps between retries to avoid claiming CPU cycles we │ │ │ │ don’t need. It starts by sleeping for 0.1 second but adjusts this to one │ │ │ │ second as the number of retries grows. │ │ │ │ humanfriendly.testing.run_cli(eennttrryy__ppooiinntt, **aarrgguummeennttss, ****ooppttiioonnss)_¶ │ │ │ │ Test a command line entry point. │ │ │ │ humanfriendly.testing.skip_on_raise(**eexxcc__ttyyppeess)_¶ │ │ │ │ Decorate a test function to translation specific exception types to │ │ │ │ - _u_n_i_t_t_e_s_t_._S_k_i_p_T_e_s_t. │ │ │ │ + unittest.SkipTest. │ │ │ │ Parameters: │ │ │ │ eexxcc__ttyyppeess – One or more positional arguments give the exception │ │ │ │ - types to be translated to _u_n_i_t_t_e_s_t_._S_k_i_p_T_e_s_t. │ │ │ │ + types to be translated to unittest.SkipTest. │ │ │ │ Returns: │ │ │ │ A decorator function specialized toexc_types. │ │ │ │ humanfriendly.testing.touch(ffiilleennaammee)_¶ │ │ │ │ The equivalent of the UNIX _t_o_u_c_h program in Python. │ │ │ │ Parameters: │ │ │ │ ffiilleennaammee – The pathname of the file to touch (a string). │ │ │ │ Note that missing directories are automatically created using _m_a_k_e___d_i_r_s │ │ │ │ @@ -3211,15 +3213,15 @@ │ │ │ │ Generate a random string. │ │ │ │ Parameters: │ │ │ │ * lleennggtthh – The length of the string to be generated (a number │ │ │ │ or a tuple with two numbers). If this is a tuple then a │ │ │ │ random number between the two numbers given in the tuple is │ │ │ │ used. │ │ │ │ * cchhaarraacctteerrss – The characters to be used (a string, defaults to │ │ │ │ - _s_t_r_i_n_g_._a_s_c_i_i___l_e_t_t_e_r_s). │ │ │ │ + string.ascii_letters). │ │ │ │ Returns: │ │ │ │ A random string. │ │ │ │ The _r_a_n_d_o_m___s_t_r_i_n_g_(_) function is very useful in test suites; by the time I │ │ │ │ included it in _h_u_m_a_n_f_r_i_e_n_d_l_y_._t_e_x_t I had already included variants of this │ │ │ │ function in seven different test suites :-). │ │ │ │ ********** _hh_uu_mm_aa_nn_ff_rr_ii_ee_nn_dd_ll_yy_.._tt_ee_xx_tt_?¶ ********** │ │ │ │ Simple text manipulation functions. │ │ │ │ @@ -3260,47 +3262,47 @@ │ │ │ │ The text with empty lines compacted (a string). │ │ │ │ humanfriendly.text.concatenate(iitteemmss, ccoonnjjuunnccttiioonn==''aanndd'', sseerriiaall__ccoommmmaa==FFaallssee)_¶ │ │ │ │ Concatenate a list of items in a human friendly way. │ │ │ │ Parameters: │ │ │ │ * iitteemmss – A sequence of strings. │ │ │ │ * ccoonnjjuunnccttiioonn – The word to use before the last item (a string, │ │ │ │ defaults to “and”). │ │ │ │ - * sseerriiaall__ccoommmmaa – _T_r_u_e to use a _s_e_r_i_a_l_ _c_o_m_m_a, _F_a_l_s_e otherwise │ │ │ │ - (defaults to _F_a_l_s_e). │ │ │ │ + * sseerriiaall__ccoommmmaa – True to use a _s_e_r_i_a_l_ _c_o_m_m_a, False otherwise │ │ │ │ + (defaults to False). │ │ │ │ Returns: │ │ │ │ A single string. │ │ │ │ >>> from humanfriendly.text import concatenate │ │ │ │ >>> concatenate(["eggs", "milk", "bread"]) │ │ │ │ 'eggs, milk and bread' │ │ │ │ humanfriendly.text.dedent(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ Dedent a string (remove common leading whitespace from all lines). │ │ │ │ Removes common leading whitespace from all lines in the string using │ │ │ │ - _t_e_x_t_w_r_a_p_._d_e_d_e_n_t_(_), removes leading and trailing empty lines using │ │ │ │ + textwrap.dedent(), removes leading and trailing empty lines using │ │ │ │ _t_r_i_m___e_m_p_t_y___l_i_n_e_s_(_) and interpolates any arguments using _f_o_r_m_a_t_(_). │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text to dedent (a string). │ │ │ │ * aarrggss – Any positional arguments are interpolated using _f_o_r_m_a_t │ │ │ │ _(_). │ │ │ │ * kkww – Any keyword arguments are interpolated using _f_o_r_m_a_t_(_). │ │ │ │ Returns: │ │ │ │ The dedented text (a string). │ │ │ │ The _c_o_m_p_a_c_t_(_) function’s documentation contains an example of how I like │ │ │ │ to use the _c_o_m_p_a_c_t_(_) and _d_e_d_e_n_t_(_) functions. The main difference is that │ │ │ │ I use _c_o_m_p_a_c_t_(_) for text that will be presented to the user (where │ │ │ │ whitespace is not so significant) and _d_e_d_e_n_t_(_) for data file and code │ │ │ │ generation tasks (where newlines and indentation are very significant). │ │ │ │ humanfriendly.text.format(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ - Format a string using the string formatting operator and/or _s_t_r_._f_o_r_m_a_t_(_). │ │ │ │ + Format a string using the string formatting operator and/or str.format(). │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text to format (a string). │ │ │ │ * aarrggss – Any positional arguments are interpolated into the │ │ │ │ text using the string formatting operator (%). If no │ │ │ │ positional arguments are given no interpolation is done. │ │ │ │ * kkww – Any keyword arguments are interpolated into the text │ │ │ │ - using the _s_t_r_._f_o_r_m_a_t_(_) function. If no keyword arguments are │ │ │ │ + using the str.format() function. If no keyword arguments are │ │ │ │ given no interpolation is done. │ │ │ │ Returns: │ │ │ │ The text with any positional and/or keyword arguments interpolated │ │ │ │ (a string). │ │ │ │ The implementation of this function is so trivial that it seems silly to │ │ │ │ even bother writing and documenting it. Justifying this requires some │ │ │ │ context :-). │ │ │ │ @@ -3319,28 +3321,28 @@ │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ >>> # The format() function. │ │ │ │ >>> print(format('the magic number is %s', 42)) │ │ │ │ the magic number is 42 │ │ │ │ >>> print(format('the magic numbers are %s and %s', 12, 42)) │ │ │ │ the magic numbers are 12 and 42 │ │ │ │ * When you interpolate a single value and someone accidentally passes │ │ │ │ - in a tuple your code raises a _T_y_p_e_E_r_r_o_r. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ + in a tuple your code raises a TypeError. Because _f_o_r_m_a_t_(_) takes a │ │ │ │ _v_a_r_i_a_b_l_e_ _n_u_m_b_e_r_ _o_f_ _a_r_g_u_m_e_n_t_s it always receives a tuple so this can │ │ │ │ never happen. Here’s an example: │ │ │ │ >>> # How expecting to interpolate a single value can fail. │ │ │ │ >>> value = (12, 42) │ │ │ │ >>> print('the magic value is %s' % value) │ │ │ │ Traceback (most recent call last): │ │ │ │ File "", line 1, in │ │ │ │ TypeError: not all arguments converted during string formatting │ │ │ │ >>> # The following line works as intended, no surprises here! │ │ │ │ >>> print(format('the magic value is %s', value)) │ │ │ │ the magic value is (12, 42) │ │ │ │ WWhhyy ffoorrmmaatt(()) iinnsstteeaadd ooff tthhee ssttrr..ffoorrmmaatt(()) mmeetthhoodd?? │ │ │ │ - When you’re doing complex string interpolation the _s_t_r_._f_o_r_m_a_t_(_) function │ │ │ │ + When you’re doing complex string interpolation the str.format() function │ │ │ │ results in more readable code, however I frequently find myself adding │ │ │ │ parentheses to force evaluation order. The _f_o_r_m_a_t_(_) function avoids this │ │ │ │ because of the relative priority between the comma and dot operators. │ │ │ │ Here’s an example: │ │ │ │ >>> "{adjective} example" + " " + "(can't think of anything less │ │ │ │ {adjective})".format(adjective='silly') │ │ │ │ "{adjective} example (can't think of anything less silly)" │ │ │ │ @@ -3358,22 +3360,22 @@ │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The original text, for example Some Random Text!. │ │ │ │ * ddeelliimmiitteerr – The delimiter used to separate words (defaults to │ │ │ │ the - character). │ │ │ │ Returns: │ │ │ │ The slug text, for example some-random-text. │ │ │ │ Raises: │ │ │ │ - _V_a_l_u_e_E_r_r_o_r when the provided text is nonempty but results in an │ │ │ │ + ValueError when the provided text is nonempty but results in an │ │ │ │ empty slug. │ │ │ │ humanfriendly.text.is_empty_line(tteexxtt)_¶ │ │ │ │ Check if a text is empty or contains only whitespace. │ │ │ │ Parameters: │ │ │ │ tteexxtt – The text to check for “emptiness” (a string). │ │ │ │ Returns: │ │ │ │ - _T_r_u_e if the text is empty or contains only whitespace, _F_a_l_s_e │ │ │ │ + True if the text is empty or contains only whitespace, False │ │ │ │ otherwise. │ │ │ │ humanfriendly.text.join_lines(tteexxtt)_¶ │ │ │ │ Remove “hard wrapping” from the paragraphs in a string. │ │ │ │ Parameters: │ │ │ │ tteexxtt – The text to reformat (a string). │ │ │ │ Returns: │ │ │ │ The text without hard wrapping (a string). │ │ │ │ @@ -3383,24 +3385,24 @@ │ │ │ │ will break _j_o_i_n___l_i_n_e_s_(_) (in that case you can use _d_e_d_e_n_t_(_) before calling │ │ │ │ _j_o_i_n___l_i_n_e_s_(_)). │ │ │ │ humanfriendly.text.pluralize(ccoouunntt, ssiinngguullaarr, pplluurraall==NNoonnee)_¶ │ │ │ │ Combine a count with the singular or plural form of a word. │ │ │ │ Parameters: │ │ │ │ * ccoouunntt – The count (a number). │ │ │ │ * ssiinngguullaarr – The singular form of the word (a string). │ │ │ │ - * pplluurraall – The plural form of the word (a string or _N_o_n_e). │ │ │ │ + * pplluurraall – The plural form of the word (a string or None). │ │ │ │ Returns: │ │ │ │ The count and singular or plural word concatenated (a string). │ │ │ │ See _p_l_u_r_a_l_i_z_e___r_a_w_(_) for the logic underneath _p_l_u_r_a_l_i_z_e_(_). │ │ │ │ humanfriendly.text.pluralize_raw(ccoouunntt, ssiinngguullaarr, pplluurraall==NNoonnee)_¶ │ │ │ │ Select the singular or plural form of a word based on a count. │ │ │ │ Parameters: │ │ │ │ * ccoouunntt – The count (a number). │ │ │ │ * ssiinngguullaarr – The singular form of the word (a string). │ │ │ │ - * pplluurraall – The plural form of the word (a string or _N_o_n_e). │ │ │ │ + * pplluurraall – The plural form of the word (a string or None). │ │ │ │ Returns: │ │ │ │ The singular or plural form of the word (a string). │ │ │ │ When the given count is exactly 1.0 the singular form of the word is │ │ │ │ selected, in all other cases the plural form of the word is selected. │ │ │ │ If the plural form of the word is not provided it is obtained by │ │ │ │ concatenating the singular form of the word with the letter “s”. Of │ │ │ │ course this will not always be correct, which is why you have the option │ │ │ │ @@ -3410,28 +3412,28 @@ │ │ │ │ Generate a random string. │ │ │ │ Parameters: │ │ │ │ * lleennggtthh – The length of the string to be generated (a number │ │ │ │ or a tuple with two numbers). If this is a tuple then a │ │ │ │ random number between the two numbers given in the tuple is │ │ │ │ used. │ │ │ │ * cchhaarraacctteerrss – The characters to be used (a string, defaults to │ │ │ │ - _s_t_r_i_n_g_._a_s_c_i_i___l_e_t_t_e_r_s). │ │ │ │ + string.ascii_letters). │ │ │ │ Returns: │ │ │ │ A random string. │ │ │ │ The _r_a_n_d_o_m___s_t_r_i_n_g_(_) function is very useful in test suites; by the time I │ │ │ │ included it in _h_u_m_a_n_f_r_i_e_n_d_l_y_._t_e_x_t I had already included variants of this │ │ │ │ function in seven different test suites :-). │ │ │ │ humanfriendly.text.split(tteexxtt, ddeelliimmiitteerr=='',,'')_¶ │ │ │ │ Split a comma-separated list of strings. │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text to split (a string). │ │ │ │ * ddeelliimmiitteerr – The delimiter to split on (a string). │ │ │ │ Returns: │ │ │ │ A list of zero or more nonempty strings. │ │ │ │ - Here’s the default behavior of Python’s built in _s_t_r_._s_p_l_i_t_(_) function: │ │ │ │ + Here’s the default behavior of Python’s built in str.split() function: │ │ │ │ >>> 'foo,bar, baz,'.split(',') │ │ │ │ ['foo', 'bar', ' baz', ''] │ │ │ │ In contrast here’s the default behavior of the _s_p_l_i_t_(_) function: │ │ │ │ >>> from humanfriendly.text import split │ │ │ │ >>> split('foo,bar, baz,') │ │ │ │ ['foo', 'bar', 'baz'] │ │ │ │ Here is an example that parses a nested data structure (a mapping of │ │ │ │ @@ -3582,21 +3584,21 @@ │ │ │ │ Returns: │ │ │ │ The usage message rendered to _r_e_S_t_r_u_c_t_u_r_e_d_T_e_x_t (a string). │ │ │ │ humanfriendly.usage.USAGE_MARKER == ''UUssaaggee::''_¶ │ │ │ │ The string that starts the first line of a usage message. │ │ │ │ humanfriendly.usage.dedent(tteexxtt, **aarrggss, ****kkww)_¶ │ │ │ │ Dedent a string (remove common leading whitespace from all lines). │ │ │ │ Removes common leading whitespace from all lines in the string using │ │ │ │ - _t_e_x_t_w_r_a_p_._d_e_d_e_n_t_(_), removes leading and trailing empty lines using │ │ │ │ - _t_r_i_m___e_m_p_t_y___l_i_n_e_s_(_) and interpolates any arguments using _f_o_r_m_a_t_(_). │ │ │ │ + textwrap.dedent(), removes leading and trailing empty lines using │ │ │ │ + _t_r_i_m___e_m_p_t_y___l_i_n_e_s_(_) and interpolates any arguments using format(). │ │ │ │ Parameters: │ │ │ │ * tteexxtt – The text to dedent (a string). │ │ │ │ - * aarrggss – Any positional arguments are interpolated using _f_o_r_m_a_t │ │ │ │ - _(_). │ │ │ │ - * kkww – Any keyword arguments are interpolated using _f_o_r_m_a_t_(_). │ │ │ │ + * aarrggss – Any positional arguments are interpolated using format │ │ │ │ + (). │ │ │ │ + * kkww – Any keyword arguments are interpolated using format(). │ │ │ │ Returns: │ │ │ │ The dedented text (a string). │ │ │ │ The compact() function’s documentation contains an example of how I like │ │ │ │ to use the compact() and _d_e_d_e_n_t_(_) functions. The main difference is that │ │ │ │ I use compact() for text that will be presented to the user (where │ │ │ │ whitespace is not so significant) and _d_e_d_e_n_t_(_) for data file and code │ │ │ │ generation tasks (where newlines and indentation are very significant). │ │ ├── ./usr/share/doc/python-humanfriendly-doc/html/changelog.html.gz │ │ │ ├── changelog.html │ │ │ │ @@ -263,15 +263,15 @@ │ │ │ │ │ │ │ │
    │ │ │ │
    │ │ │ │

    Release 8.0 (2020-03-02)

    │ │ │ │

    This release is backwards incompatible in several ways, see the notes below.

    │ │ │ │

    Enhancements:

    │ │ │ │ │ │ │ │

    Tests:

    │ │ │ │ -

    Fixed unittest deprecation warnings in the test suite.

    │ │ │ │ +

    Fixed unittest deprecation warnings in the test suite.

    │ │ │ │
    │ │ │ │
    │ │ │ │

    Release 7.1.1 (2020-02-18)

    │ │ │ │

    Fix Python 3 incompatibility (distutils.spawn).

    │ │ │ │

    Much to my dismay this morning I ran into the following traceback on a Python │ │ │ │ 3.6 installation that is based on native Ubuntu (Debian) packages:

    │ │ │ │
    Traceback (most recent call last):
    │ │ │ │ @@ -402,15 +402,15 @@
    │ │ │ │  
    │ │ │ │
    │ │ │ │

    I took this to mean it would be available on all these versions. Furthermore │ │ │ │ the tests on Travis CI passed as well. I think this is because deadsnakes as │ │ │ │ well as Travis CI are closer to upstream (the official Python releases) whereas │ │ │ │ Debian and Ubuntu make significant customizations…

    │ │ │ │

    In any case this new commit should fix the issue by using │ │ │ │ -shutil.which() on Python 3 instead.

    │ │ │ │ +shutil.which() on Python 3 instead.

    │ │ │ │
    │ │ │ │
    │ │ │ │

    Release 7.1 (2020-02-16)

    │ │ │ │

    Enhancements:

    │ │ │ │
    │ │ │ │
    │ │ │ │

    Release 4.12 (2018-04-26)

    │ │ │ │ │ │ │ │
    │ │ │ │
    │ │ │ │

    Release 4.11 (2018-04-26)

    │ │ │ │

    Added this changelog as requested in #23.

    │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -196,15 +196,15 @@ │ │ │ │ │ IInntteerrnnaall cchhaannggeess:: │ │ │ │ │ * Refactored the test suite to import all names separately instead of │ │ │ │ │ referring to identifiers via their modules (my preferences have changed │ │ │ │ │ since this code was written a long time ago). │ │ │ │ │ ********** _RR_ee_ll_ee_aa_ss_ee_ _88_.._00 ((22002200--0033--0022))_?¶ ********** │ │ │ │ │ This release is backwards incompatible in several ways, see the notes below. │ │ │ │ │ EEnnhhaanncceemmeennttss:: │ │ │ │ │ - * Adopt _f_u_n_c_t_o_o_l_s_._w_r_a_p_s_(_) to make decorator functions more robust. │ │ │ │ │ + * Adopt functools.wraps() to make decorator functions more robust. │ │ │ │ │ * Make the _S_p_i_n_n_e_r class more customizable. The interval at which spinners │ │ │ │ │ are updated and the characters used to draw the animation of spinners can │ │ │ │ │ now be customized by callers. This was triggered by _e_x_e_c_u_t_o_r_ _i_s_s_u_e_ _#_2. │ │ │ │ │ Note │ │ │ │ │ The text cursor hiding behavior of spinners has been removed because it │ │ │ │ │ was found to be problematic (sometimes the text cursor would be hidden │ │ │ │ │ but not made visible again, which is disorienting to say the least). │ │ │ │ │ @@ -270,15 +270,15 @@ │ │ │ │ │ * Additionally the _h_u_m_a_n_f_r_i_e_n_d_l_y_._c_o_m_p_a_t module introduced a lot of noise │ │ │ │ │ into the generated documentation because imported classes and their │ │ │ │ │ members were being included in the documentation, this is now also fixed. │ │ │ │ │ * Finally I decided to start using sphinx-build -nW to complain loudly when │ │ │ │ │ even just one broken reference is found. This should encourage the │ │ │ │ │ discipline to never introduce broken references again! │ │ │ │ │ TTeessttss:: │ │ │ │ │ -Fixed _u_n_i_t_t_e_s_t deprecation warnings in the test suite. │ │ │ │ │ +Fixed unittest deprecation warnings in the test suite. │ │ │ │ │ ********** _RR_ee_ll_ee_aa_ss_ee_ _77_.._11_.._11 ((22002200--0022--1188))_?¶ ********** │ │ │ │ │ Fix Python 3 incompatibility (distutils.spawn). │ │ │ │ │ Much to my dismay this morning I ran into the following traceback on a Python │ │ │ │ │ 3.6 installation that is based on native Ubuntu (Debian) packages: │ │ │ │ │ Traceback (most recent call last): │ │ │ │ │ File "...", line 1, in │ │ │ │ │ from coloredlogs.syslog import enable_system_logging │ │ │ │ │ @@ -302,15 +302,15 @@ │ │ │ │ │ -rw-r--r-- 1 root root 7.3K Oct 28 17:30 /usr/lib/python3.6/distutils/spawn.py │ │ │ │ │ -rw-r--r-- 1 root root 7.7K Oct 28 17:30 /usr/lib/python3.7/distutils/spawn.py │ │ │ │ │ -rw-r--r-- 1 root root 7.7K Oct 28 17:30 /usr/lib/python3.8/distutils/spawn.py │ │ │ │ │ I took this to mean it would be available on all these versions. Furthermore │ │ │ │ │ the tests on Travis CI passed as well. I think this is because _d_e_a_d_s_n_a_k_e_s as │ │ │ │ │ well as Travis CI are closer to upstream (the official Python releases) whereas │ │ │ │ │ Debian and Ubuntu make significant customizations… │ │ │ │ │ -In any case this new commit should fix the issue by using _s_h_u_t_i_l_._w_h_i_c_h_(_) on │ │ │ │ │ +In any case this new commit should fix the issue by using shutil.which() on │ │ │ │ │ Python 3 instead. │ │ │ │ │ ********** _RR_ee_ll_ee_aa_ss_ee_ _77_.._11 ((22002200--0022--1166))_?¶ ********** │ │ │ │ │ EEnnhhaanncceemmeennttss:: │ │ │ │ │ * Enable Windows native support for ANSI escape sequences. This was brought │ │ │ │ │ to my attention in _c_o_l_o_r_e_d_l_o_g_s_ _i_s_s_u_e_ _#_7_1 and _c_o_l_o_r_e_d_l_o_g_s_ _p_u_l_l_ _r_e_q_u_e_s_t │ │ │ │ │ _#_7_2. My experiences with ANSI escape sequences started out as part of the │ │ │ │ │ _c_o_l_o_r_e_d_l_o_g_s package but eventually I moved the support for ANSI escape │ │ │ │ │ @@ -349,15 +349,15 @@ │ │ │ │ │ programs. This was added to make it easy to mock a program that is │ │ │ │ │ expected to generate specific output (I’m planning to use this in the │ │ │ │ │ _l_i_n_u_x_-_u_t_i_l_s test suite). │ │ │ │ │ * Defined __all__ for all public modules that previously lacked “export │ │ │ │ │ control” and decided to bump the major version number as a precaution: │ │ │ │ │ o These changes should not have any impact on backwards │ │ │ │ │ compatibility, unless I forgot entries, in which case callers can │ │ │ │ │ - get _I_m_p_o_r_t_E_r_r_o_r exceptions… │ │ │ │ │ + get ImportError exceptions… │ │ │ │ │ o Imports of public modules were previously exported (implicitly) and │ │ │ │ │ this pollutes code completion suggestions which in turn can │ │ │ │ │ encourage bad practices (not importing things using their │ │ │ │ │ “canonical” name). │ │ │ │ │ o I started developing the humanfriendly package years before I │ │ │ │ │ learned about the value of defining __all__ and so some modules │ │ │ │ │ lacked a definition until now. I decided that now was as good a │ │ │ │ │ @@ -455,15 +455,15 @@ │ │ │ │ │ ********** _RR_ee_ll_ee_aa_ss_ee_ _44_.._11_22_.._11 ((22001188--0055--1100))_?¶ ********** │ │ │ │ │ It was reported in issue _#_2_8 that humanfriendly --demo didn’t work on Python 3 │ │ │ │ │ due to two unrelated TypeError exceptions. First I added a failing regression │ │ │ │ │ test to the test suite (_h_e_r_e_’_s_ _t_h_e_ _f_a_i_l_i_n_g_ _b_u_i_l_d) and then I applied the │ │ │ │ │ changes suggested in issue _#_2_8, confirming that both issues are indeed fixed │ │ │ │ │ because the test now passes (_h_e_r_e_’_s_ _t_h_e_ _s_u_c_c_e_s_s_f_u_l_ _b_u_i_l_d). │ │ │ │ │ ********** _RR_ee_ll_ee_aa_ss_ee_ _44_.._11_22 ((22001188--0044--2266))_?¶ ********** │ │ │ │ │ - * Make _h_u_m_a_n_f_r_i_e_n_d_l_y_._f_o_r_m_a_t___t_i_m_e_s_p_a_n_(_) accept _d_a_t_e_t_i_m_e_._t_i_m_e_d_e_l_t_a objects │ │ │ │ │ + * Make _h_u_m_a_n_f_r_i_e_n_d_l_y_._f_o_r_m_a_t___t_i_m_e_s_p_a_n_(_) accept datetime.timedelta objects │ │ │ │ │ (fixes _#_2_7). │ │ │ │ │ * Add license key to setup.py script (pointed out to me in _c_o_l_o_r_e_d_l_o_g_s_ _p_u_l_l │ │ │ │ │ _r_e_q_u_e_s_t_ _#_5_3). │ │ │ │ │ ********** _RR_ee_ll_ee_aa_ss_ee_ _44_.._11_11 ((22001188--0044--2266))_?¶ ********** │ │ │ │ │ Added this changelog as requested in _#_2_3. │ │ │ │ │ I’ve held off on having to keep track of changelogs in my open source │ │ │ │ │ programming projects until now (2018) because it’s yet another piece of │ │ ├── ./usr/share/doc/python-humanfriendly-doc/html/searchindex.js │ │ │ ├── js-beautify {} │ │ │ │ @@ -3403,16 +3403,16 @@ │ │ │ │ "put": 1, │ │ │ │ "py": [0, 1], │ │ │ │ "pypi": [0, 1, 3], │ │ │ │ "pypi_rol": [0, 1, 2], │ │ │ │ "pyreadlin": 1, │ │ │ │ "pytest": [0, 1], │ │ │ │ "python": [0, 1], │ │ │ │ - "python2": 1, │ │ │ │ - "python3": 1, │ │ │ │ + "python2": [0, 1], │ │ │ │ + "python3": [0, 1], │ │ │ │ "qpass": 1, │ │ │ │ "qualifi": 0, │ │ │ │ "queri": 3, │ │ │ │ "question": [0, 3], │ │ │ │ "quirk": 0, │ │ │ │ "quit": [0, 1], │ │ │ │ "quot": [0, 1, 2],