Skip to content

Commit 513bc00

Browse files
mgedmingaborbernat
authored andcommitted
Fix over-precise float formatting on Python 3 (#1241)
* Fix over-precise float formatting on Python 3 Sometimes tox would tell me things like ✔ OK py27 in 4.1370000000000005 seconds ✔ OK py36 in 14.5 seconds ✔ OK py37 in 15.029 seconds ✔ OK py35 in 17.519 seconds ✔ OK py34 in 18.85 seconds the almost-rounded-to-3-decimals value was both funny and sad, but mostly irritating. This was happening because on Python 3 float.__str__ was changed to be more precise, and now >>> print(4 + 0.137) 4.1370000000000005 We can avoid the problem if we round the result of the addition instead of adding a rounded number to the integer number of seconds: >>> print(4.137) 4.137 I've also corrected the plural logic because "0.5 second" is wrong[*]: https://ell.stackexchange.com/questions/7817/singular-or-plural-for-seconds * Add myself to CONTRIBUTORS Also sorted the CONTRIBUTORS file to make sure I've preserved the alphabetical order, which adjusted some existing names. * Add a news fragment * Make the linter happy
1 parent 5e565ce commit 513bc00

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
lines changed

CONTRIBUTORS

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
Alexander Schepanovski
21
Alex Grönholm
32
Alexander Loechel
3+
Alexander Schepanovski
44
Alexandre Conrad
55
Allan Feldman
66
Andrii Soldatenko
@@ -47,6 +47,7 @@ Lukasz Rogalski
4747
Manuel Jacob
4848
Marc Abramowitz
4949
Marc Schlaich
50+
Marius Gedminas
5051
Mariusz Rusiniak
5152
Mark Hirota
5253
Matt Good
@@ -65,8 +66,8 @@ Pierre-Luc Tessier Gagné
6566
Ronald Evers
6667
Ronny Pfannschmidt
6768
Selim Belhaouane
68-
Stephen Finucane
6969
Sridhar Ratnakumar
70+
Stephen Finucane
7071
Sviatoslav Sydorenko
7172
Tim Laurence
7273
Ville Skyttä

docs/changelog/1241.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Do not print timings with more than 3 decimal digits on Python 3 - by :user:`mgedmin`.

src/tox/util/spinner.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def td_human_readable(delta):
167167
period_value, seconds = divmod(seconds, period_seconds)
168168
if period_name == "second":
169169
ms = delta.total_seconds() - int(delta.total_seconds())
170-
period_value += round(ms, 3)
171-
has_s = "s" if period_value > 1 else ""
170+
period_value = round(period_value + ms, 3)
171+
has_s = "s" if period_value != 1 else ""
172172
texts.append("{} {}{}".format(period_value, period_name, has_s))
173173
return ", ".join(texts)

tests/unit/util/test_spinner.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import absolute_import, unicode_literals
33

4+
import datetime
45
import os
56
import sys
67
import time
78

9+
import pytest
810
from freezegun import freeze_time
911

1012
from tox.util import spinner
@@ -70,9 +72,9 @@ def test_spinner_report(capfd, monkeypatch):
7072
lines = out.split(os.linesep)
7173
del lines[0]
7274
expected = [
73-
"\r{}✔ OK ok in 0.0 second".format(spin.CLEAR_LINE),
74-
"\r{}✖ FAIL fail in 0.0 second".format(spin.CLEAR_LINE),
75-
"\r{}⚠ SKIP skip in 0.0 second".format(spin.CLEAR_LINE),
75+
"\r{}✔ OK ok in 0.0 seconds".format(spin.CLEAR_LINE),
76+
"\r{}✖ FAIL fail in 0.0 seconds".format(spin.CLEAR_LINE),
77+
"\r{}⚠ SKIP skip in 0.0 seconds".format(spin.CLEAR_LINE),
7678
"\r{}".format(spin.CLEAR_LINE),
7779
]
7880
assert lines == expected
@@ -106,3 +108,20 @@ def test_spinner_stdout_not_unicode(capfd, monkeypatch):
106108
out, err = capfd.readouterr()
107109
assert not err
108110
assert all(f in out for f in spin.frames)
111+
112+
113+
@pytest.mark.parametrize(
114+
"seconds, expected",
115+
[
116+
(0, "0.0 seconds"),
117+
(1.0, "1.0 second"),
118+
(4.0, "4.0 seconds"),
119+
(4.130, "4.13 seconds"),
120+
(4.137, "4.137 seconds"),
121+
(42.12345, "42.123 seconds"),
122+
(61, "1 minute, 1.0 second"),
123+
],
124+
)
125+
def test_td_human_readable(seconds, expected):
126+
dt = datetime.timedelta(seconds=seconds)
127+
assert spinner.td_human_readable(dt) == expected

0 commit comments

Comments
 (0)