-
-
Notifications
You must be signed in to change notification settings - Fork 33.5k
gh-102402: Fix floating point math issue by using time.time_ns() in logging.LogRecord
#102412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 21 commits
2f046c2
2460f88
059f856
997bd41
2e7cde3
5505cea
411a421
d3a1f78
5fa370b
39cab9d
920bf74
8bdc406
bf68b26
e404ca0
9661499
ec74b0e
710f3ac
ff8140c
fd45694
84b931b
5a604f9
dc90919
502ff65
65ea1b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,7 @@ | |
| import tempfile | ||
| from test.support.script_helper import assert_python_ok, assert_python_failure | ||
| from test import support | ||
| from test.support import import_helper | ||
| from test.support import os_helper | ||
| from test.support import socket_helper | ||
| from test.support import threading_helper | ||
|
|
@@ -58,6 +59,7 @@ | |
| import weakref | ||
|
|
||
| from http.server import HTTPServer, BaseHTTPRequestHandler | ||
| from unittest.mock import patch | ||
| from urllib.parse import urlparse, parse_qs | ||
| from socketserver import (ThreadingUDPServer, DatagramRequestHandler, | ||
| ThreadingTCPServer, StreamRequestHandler) | ||
|
|
@@ -4310,6 +4312,43 @@ def test_issue_89047(self): | |
| s = f.format(r) | ||
| self.assertNotIn('.1000', s) | ||
|
|
||
| def test_msecs_has_no_floating_point_precision_loss(self): | ||
| # See issue gh-102402 | ||
| tests = ( | ||
| # time_ns is approx. 2023-03-04 04:25:20 UTC | ||
| # (time_ns, expected_msecs_value) | ||
| (1_677_902_297_100_000_000, 100.0), # exactly 100ms | ||
| (1_677_903_920_999_998_503, 999.0), # check truncating doesn't round | ||
| (1_677_903_920_000_998_503, 0.0), # check truncating doesn't round | ||
| ) | ||
| for ns, want in tests: | ||
| with patch('time.time_ns') as patched_ns: | ||
| patched_ns.return_value = ns | ||
| record = logging.makeLogRecord({'msg': 'test'}) | ||
| self.assertEqual(record.msecs, want) | ||
serhiy-storchaka marked this conversation as resolved.
Show resolved
Hide resolved
serhiy-storchaka marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| self.assertEqual(record.created, ns / 1e9) | ||
|
|
||
| def test_relativeCreated_has_higher_precision(self): | ||
| # See issue gh-102402 | ||
| ns = 1_677_903_920_000_998_503 # approx. 2023-03-04 04:25:20 UTC | ||
| for offset_ns in (200, 500, 12_354, 99_999, 1_677_903_456_999_123_456): | ||
| new_ns = ns + offset_ns | ||
| with patch("time.time_ns") as patched_ns: | ||
| orig_modules = import_helper._save_and_remove_modules(['logging']) | ||
| try: | ||
| # mock for module import | ||
| patched_ns.return_value = ns | ||
| import logging | ||
|
||
| # mock for log record creation | ||
| patched_ns.return_value = new_ns | ||
| record = logging.makeLogRecord({'msg': 'test'}) | ||
| finally: | ||
| import_helper._save_and_remove_modules(['logging']) | ||
| sys.modules.update(orig_modules) | ||
|
|
||
| self.assertAlmostEqual(record.created, new_ns / 1e9, places=6) | ||
| # After PR gh-102412, precision (places) increases from 3 to 7 | ||
| self.assertAlmostEqual(record.relativeCreated, offset_ns / 1e6, places=7) | ||
|
|
||
| class TestBufferingFormatter(logging.BufferingFormatter): | ||
| def formatHeader(self, records): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Adjust ``logging.LogRecord`` to use ``time.time_ns()`` and fix minor bug | ||
| related to floating point math. |
Uh oh!
There was an error while loading. Please reload this page.