Skip to content

Commit 3b69dde

Browse files
authored
Merge pull request #208 from tarasko/main
Fix asctime formatting, don't print uninitialized buffer's content (issue #203)
2 parents 4b455d4 + 8d22ce2 commit 3b69dde

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

src/picologging/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ def setLoggerClass(self, klass):
177177
self.cls = klass
178178

179179
def setLogRecordFactory(self, factory):
180-
raise NotImplementedError("setLogRecordFactory is not supported in picologging.")
180+
raise NotImplementedError(
181+
"setLogRecordFactory is not supported in picologging."
182+
)
181183

182184

183185
root = Logger(name="root", level=WARNING)

src/picologging/formatter.cxx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <ctime>
2+
#include <charconv>
23
#include "picologging.hxx"
34
#include "formatter.hxx"
45
#include "formatstyle.hxx"
@@ -90,15 +91,19 @@ PyObject* Formatter_format(Formatter *self, PyObject *record){
9091
}
9192
if (self->usesTime){
9293
PyObject * asctime = Py_None;
93-
std::time_t created = (std::time_t)logRecord->created;
94+
double createdInt;
95+
int createdFrac = std::modf(logRecord->created, &createdInt) * 1e3;
96+
std::time_t created = static_cast<std::time_t>(createdInt);
9497
std::tm *ct = localtime(&created);
9598
if (self->dateFmt != Py_None){
9699
char buf[100];
97-
size_t len = strftime(buf, 100, self->dateFmtStr, ct);
100+
size_t len = strftime(buf, sizeof(buf), self->dateFmtStr, ct);
98101
asctime = PyUnicode_FromStringAndSize(buf, len);
99102
} else {
100103
char buf[100];
101-
asctime = PyUnicode_FromFormat("%s,%03d", buf, logRecord->msecs);
104+
size_t len = strftime(buf, sizeof(buf), "%F %T" , ct);
105+
len += snprintf(buf + len, sizeof(buf) - len, ",%03d", createdFrac);
106+
asctime = PyUnicode_FromStringAndSize(buf, len);
102107
}
103108

104109
Py_XDECREF(logRecord->asctime);
@@ -349,4 +354,4 @@ PyTypeObject FormatterType = {
349354
0, /* tp_alloc */
350355
Formatter_new, /* tp_new */
351356
PyObject_Del, /* tp_free */
352-
};
357+
};

tests/unit/test_formatter.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import logging
44
import sys
55
import traceback
6+
from logging import Formatter as LoggingFormatter
67

78
import pytest
89
from utils import filter_gc
@@ -147,6 +148,18 @@ def test_asctime_field():
147148
assert pico_f.usesTime()
148149

149150

151+
@pytest.mark.limit_leaks("192B", filter_fn=filter_gc)
152+
def test_asctime_field_buffer():
153+
pico_f = Formatter("%(asctime)s")
154+
record = LogRecord(
155+
"hello", logging.WARNING, __file__, 123, "bork bork bork", (), None
156+
)
157+
logging_f = LoggingFormatter("%(asctime)s")
158+
159+
assert pico_f.format(record).split(",")[0] == logging_f.format(record).split(",")[0]
160+
assert pico_f.usesTime()
161+
162+
150163
@pytest.mark.limit_leaks("192B", filter_fn=filter_gc)
151164
def test_record_with_stack_info():
152165
pico_f = Formatter("%(message)s")

0 commit comments

Comments
 (0)