Skip to content

Commit

Permalink
Merge pull request #153 from hugovk/update-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
hugovk authored Sep 10, 2020
2 parents 0397654 + aca3e04 commit 345f58b
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 74 deletions.
10 changes: 4 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ jobs:
tox -e py
- name: Upload coverage
if: success()
run: |
curl --retry 8 -s https://codecov.io/bash -o codecov.sh
bash codecov.sh -F ${{ matrix.codecov-flag }}
env:
CODECOV_NAME: ${{ matrix.os }} Python ${{ matrix.python-version }}
uses: codecov/codecov-action@v1
with:
flags: ${{ matrix.codecov-flag }}
name: ${{ matrix.os }} Python ${{ matrix.python-version }}
7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,10 @@ repos:
- id: check-merge-conflict
- id: check-toml
- id: check-yaml

- repo: https://github.com/PyCQA/pydocstyle
rev: 5.1.1
hooks:
- id: pydocstyle
args: ["--convention", "google"]
files: "src/"
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,15 @@ If seconds are too large, set `minimum_unit` to milliseconds or microseconds:
>>> humanize.naturaldelta(delta, minimum_unit="milliseconds")
'4 milliseconds'
>>> humanize.naturaldelta(delta, minimum_unit="microseconds")
'4000 microseconds'
'4 milliseconds'
```
```pycon
>>> humanize.naturaltime(delta)
'now'
>>> humanize.naturaltime(delta, minimum_unit="milliseconds")
'4 milliseconds ago'
>>> humanize.naturaltime(delta, minimum_unit="microseconds")
'4000 microseconds ago'
'4 milliseconds ago'
```

### File size humanization
Expand Down Expand Up @@ -208,3 +208,7 @@ Where `<locale name>` is a locale abbreviation, eg. `en_GB`, `pt_BR` or just `ru
etc.

List the language at the top of this README.

## API reference

[https://python-humanize.readthedocs.io](https://python-humanize.readthedocs.io)
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ Welcome to the humanize API reference.
* [Filesize](filesize)
* [I18n](i18n)

Or see [README.md](https://github.com/jmoiron/humanize/blob/master/README.md)
for usage examples.
For usage examples see
[README.md](https://github.com/jmoiron/humanize/blob/master/README.md).
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
[flake8]
max_line_length = 88

[pydocstyle]
convention = google

[tool:isort]
known_third_party = freezegun,humanize,pkg_resources,pytest,setuptools
force_grid_wrap = 0
Expand Down
1 change: 1 addition & 0 deletions src/humanize/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Main package for humanize."""
import pkg_resources
from humanize.filesize import naturalsize
from humanize.i18n import activate, deactivate
Expand Down
3 changes: 3 additions & 0 deletions src/humanize/filesize.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ def naturalsize(value, binary=False, gnu=False, format="%.1f"):
gnu (bool): If `True`, the binary argument is ignored and GNU-style
(`ls -sh` style) prefixes are used (K, M) with the 2**10 definition.
format (str): Custom formatter.
Returns:
str: Human readable representation of a filesize.
"""
if gnu:
suffix = suffixes["gnu"]
Expand Down
6 changes: 5 additions & 1 deletion src/humanize/i18n.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Activate, get and deactivate translations."""
import gettext as gettext_module
import os.path
from threading import local
Expand Down Expand Up @@ -35,6 +36,9 @@ def activate(locale, path=None):
Returns:
dict: Translations.
Raises:
Exception: If humanize cannot find the locale folder.
"""
if path is None:
path = _get_default_locale_path()
Expand Down Expand Up @@ -69,7 +73,7 @@ def gettext(message):


def pgettext(msgctxt, message):
"""'Particular gettext' function.
"""Fetches a particular translation.
It works with `msgctxt` .po modifiers and allows duplicate keys with different
translations.
Expand Down
120 changes: 57 additions & 63 deletions src/humanize/time.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/usr/bin/env python

"""Time humanizing functions. These are largely borrowed from Django's
`contrib.humanize`."""
"""Time humanizing functions.
These are largely borrowed from Django's `contrib.humanize`.
"""

import datetime as dt
import math
Expand Down Expand Up @@ -42,8 +44,7 @@ def _now():


def abs_timedelta(delta):
"""Return an "absolute" value for a timedelta, always representing a
time distance.
"""Return an "absolute" value for a timedelta, always representing a time distance.
Args:
delta (datetime.timedelta): Input timedelta.
Expand Down Expand Up @@ -207,9 +208,12 @@ def naturaltime(value, future=False, months=True, minimum_unit="seconds"):


def naturalday(value, format="%b %d"):
"""For date values that are tomorrow, today or yesterday compared to
present day returns representing string. Otherwise, returns a string
formatted according to `format`."""
"""Return a natural day.
For date values that are tomorrow, today or yesterday compared to
present day return representing string. Otherwise, return a string
formatted according to `format`.
"""
try:
value = dt.date(value.year, value.month, value.day)
except AttributeError:
Expand All @@ -229,8 +233,7 @@ def naturalday(value, format="%b %d"):


def naturaldate(value):
"""Like `naturalday`, but append a year for dates more than about five months away.
"""
"""Like `naturalday`, but append a year for dates more than ~five months away."""
try:
value = dt.date(value.year, value.month, value.day)
except AttributeError:
Expand All @@ -246,35 +249,30 @@ def naturaldate(value):


def _quotient_and_remainder(value, divisor, unit, minimum_unit, suppress):
"""Divide `value` by `divisor` returning the quotient and
the remainder as follows:
"""Divide `value` by `divisor` returning the quotient and remainder.
If `unit` is `minimum_unit`, makes the quotient a float number
and the remainder will be zero. The rational is that if unit
is the unit of the quotient, we cannot
represent the remainder because it would require a unit smaller
than the minimum_unit.
If `unit` is `minimum_unit`, makes the quotient a float number and the remainder
will be zero. The rational is that if `unit` is the unit of the quotient, we cannot
represent the remainder because it would require a unit smaller than the
`minimum_unit`.
>>> from humanize.time import _quotient_and_remainder, Unit
>>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.DAYS, [])
(1.5, 0)
>>> from humanize.time import _quotient_and_remainder, Unit
>>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.DAYS, [])
(1.5, 0)
If unit is in suppress, the quotient will be zero and the
remainder will be the initial value. The idea is that if we
cannot use unit, we are forced to use a lower unit so we cannot
do the division.
If unit is in `suppress`, the quotient will be zero and the remainder will be the
initial value. The idea is that if we cannot use `unit`, we are forced to use a
lower unit so we cannot do the division.
>>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, [Unit.DAYS])
(0, 36)
>>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, [Unit.DAYS])
(0, 36)
In other case return quotient and remainder as `divmod` would
do it.
In other case return quotient and remainder as `divmod` would do it.
>>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, [])
(1, 12)
>>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, [])
(1, 12)
"""

if unit == minimum_unit:
return (value / divisor, 0)
elif unit in suppress:
Expand All @@ -284,29 +282,27 @@ def _quotient_and_remainder(value, divisor, unit, minimum_unit, suppress):


def _carry(value1, value2, ratio, unit, min_unit, suppress):
"""Return a tuple with two values as follows:
"""Return a tuple with two values.
If the unit is in suppress multiplies value1
by ratio and add it to value2 (carry to right).
The idea is that if we cannot represent value1 we need
to represent it in a lower unit.
If the unit is in `suppress`, multiply `value1` by `ratio` and add it to `value2`
(carry to right). The idea is that if we cannot represent `value1` we need to
represent it in a lower unit.
>>> from humanize.time import _carry, Unit
>>> _carry(2, 6, 24, Unit.DAYS, Unit.SECONDS, [Unit.DAYS])
(0, 54)
>>> from humanize.time import _carry, Unit
>>> _carry(2, 6, 24, Unit.DAYS, Unit.SECONDS, [Unit.DAYS])
(0, 54)
If the unit is the minimum unit, value2 is divided
by ratio and added to value1 (carry to left).
We assume that value2 has a lower unit so we need to
carry it to value1.
If the unit is the minimum unit, `value2` is divided by `ratio` and added to
`value1` (carry to left). We assume that `value2` has a lower unit so we need to
carry it to `value1`.
>>> _carry(2, 6, 24, Unit.DAYS, Unit.DAYS, [])
(2.25, 0)
>>> _carry(2, 6, 24, Unit.DAYS, Unit.DAYS, [])
(2.25, 0)
Otherwise, just return the same input:
Otherwise, just return the same input:
>>> _carry(2, 6, 24, Unit.DAYS, Unit.SECONDS, [])
(2, 6)
>>> _carry(2, 6, 24, Unit.DAYS, Unit.SECONDS, [])
(2, 6)
"""
if unit == min_unit:
return (value1 + value2 / ratio, 0)
Expand All @@ -319,20 +315,20 @@ def _carry(value1, value2, ratio, unit, min_unit, suppress):
def _suitable_minimum_unit(min_unit, suppress):
"""Return a minimum unit suitable that is not suppressed.
If not suppressed, return the same unit:
If not suppressed, return the same unit:
>>> from humanize.time import _suitable_minimum_unit, Unit
>>> _suitable_minimum_unit(Unit.HOURS, [])
<Unit.HOURS: 4>
>>> from humanize.time import _suitable_minimum_unit, Unit
>>> _suitable_minimum_unit(Unit.HOURS, [])
<Unit.HOURS: 4>
But if suppressed, find a unit greather than the original one
that is not suppressed:
But if suppressed, find a unit greather than the original one that is not
suppressed:
>>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS])
<Unit.DAYS: 5>
>>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS])
<Unit.DAYS: 5>
>>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS, Unit.DAYS])
<Unit.MONTHS: 6>
>>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS, Unit.DAYS])
<Unit.MONTHS: 6>
"""
if min_unit in suppress:
for unit in Unit:
Expand All @@ -347,12 +343,11 @@ def _suitable_minimum_unit(min_unit, suppress):


def _suppress_lower_units(min_unit, suppress):
"""Extend the suppressed units (if any) with all the units that are
lower than the minimum unit.
"""Extend suppressed units (if any) with all units lower than the minimum unit.
>>> from humanize.time import _suppress_lower_units, Unit
>>> list(sorted(_suppress_lower_units(Unit.SECONDS, [Unit.DAYS])))
[<Unit.MICROSECONDS: 0>, <Unit.MILLISECONDS: 1>, <Unit.DAYS: 5>]
>>> from humanize.time import _suppress_lower_units, Unit
>>> list(sorted(_suppress_lower_units(Unit.SECONDS, [Unit.DAYS])))
[<Unit.MICROSECONDS: 0>, <Unit.MILLISECONDS: 1>, <Unit.DAYS: 5>]
"""
suppress = set(suppress)
for u in Unit:
Expand Down Expand Up @@ -411,7 +406,6 @@ def precisedelta(value, minimum_unit="seconds", suppress=(), format="%0.2f"):
'1.50 minutes'
```
"""

date, delta = date_and_delta(value)
if date is None:
return value
Expand Down

0 comments on commit 345f58b

Please sign in to comment.