From 9b8b0b19468662bc6e00067dcb9aed0456080a39 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Tue, 17 Nov 2020 09:33:44 -0500 Subject: [PATCH 1/4] News fragment. --- newsfragments/3509.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/3509.bugfix diff --git a/newsfragments/3509.bugfix b/newsfragments/3509.bugfix new file mode 100644 index 000000000..4d633feab --- /dev/null +++ b/newsfragments/3509.bugfix @@ -0,0 +1 @@ +Fix regression that broke flogtool results on Python 2. \ No newline at end of file From bb7ed3afc96e2bd573449d02e9e793f42f7f0718 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Tue, 17 Nov 2020 11:25:24 -0500 Subject: [PATCH 2/4] Fix the bug. --- src/allmydata/node.py | 4 ++-- src/allmydata/test/test_node.py | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/allmydata/node.py b/src/allmydata/node.py index 9e7143fd4..4725ff813 100644 --- a/src/allmydata/node.py +++ b/src/allmydata/node.py @@ -79,9 +79,9 @@ def _common_valid_config(): }) # Add our application versions to the data that Foolscap's LogPublisher -# reports. +# reports. Foolscap requires native strings. for thing, things_version in list(get_package_versions().items()): - app_versions.add_version(thing, things_version) + app_versions.add_version(ensure_str(thing), ensure_str(things_version)) # group 1 will be addr (dotted quad string), group 3 if any will be portnum (string) ADDR_RE = re.compile("^([1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*)(:([1-9][0-9]*))?$") diff --git a/src/allmydata/test/test_node.py b/src/allmydata/test/test_node.py index 693183ea4..010030a6f 100644 --- a/src/allmydata/test/test_node.py +++ b/src/allmydata/test/test_node.py @@ -6,7 +6,7 @@ from __future__ import division from __future__ import print_function from __future__ import unicode_literals -from future.utils import PY2 +from future.utils import PY2, native_str if PY2: from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 @@ -46,6 +46,7 @@ from allmydata.node import ( _tub_portlocation, formatTimeTahoeStyle, UnescapedHashError, + get_app_versions, ) from allmydata.introducer.server import create_introducer from allmydata import client @@ -100,6 +101,16 @@ class TestCase(testutil.SignalMixin, unittest.TestCase): # conflict with another service to prove it. self._available_port = 22 + def test_application_versions(self): + """ + Application versions should all have the same type, the native string. + + This test is due to the Foolscap limitations, if Foolscap is fixed or + removed it can be deleted. + """ + app_types = set(type(o) for o in get_app_versions()) + self.assertEqual(app_types, {native_str}) + def _test_location( self, expected_addresses, From dd5092f6566608d4eb8fb45004d0244ae48ece31 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Tue, 17 Nov 2020 13:15:52 -0500 Subject: [PATCH 3/4] News fragment. --- newsfragments/3510.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/3510.bugfix diff --git a/newsfragments/3510.bugfix b/newsfragments/3510.bugfix new file mode 100644 index 000000000..d4a2bd5dc --- /dev/null +++ b/newsfragments/3510.bugfix @@ -0,0 +1 @@ +Fix a logging regression on Python 2 involving unicode strings. \ No newline at end of file From feb85f4c4a060b37b51d5b73d07863344b3d74dc Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Tue, 17 Nov 2020 13:15:57 -0500 Subject: [PATCH 4/4] Always use native strings as keys. --- src/allmydata/test/test_log.py | 16 +++++++++++++++- src/allmydata/util/log.py | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/allmydata/test/test_log.py b/src/allmydata/test/test_log.py index eecbda9e3..bf079aaeb 100644 --- a/src/allmydata/test/test_log.py +++ b/src/allmydata/test/test_log.py @@ -9,7 +9,7 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function -from future.utils import PY2 +from future.utils import PY2, native_str if PY2: from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 @@ -154,3 +154,17 @@ class Log(unittest.TestCase): obj.log("four") self.assertEqual([m[2] for m in self.messages], ["grand", "par1", "par2", "msg1", "msg1"]) + + def test_native_string_keys(self): + """Keyword argument keys are all native strings.""" + class LoggingObject17(tahoe_log.PrefixingLogMixin): + pass + + obj = LoggingObject17() + # Native string by default: + obj.log(hello="world") + # Will be Unicode on Python 2: + obj.log(**{"my": "message"}) + for message in self.messages: + for k in message[-1].keys(): + self.assertIsInstance(k, native_str) diff --git a/src/allmydata/util/log.py b/src/allmydata/util/log.py index 11c78a5a2..509deb6a4 100644 --- a/src/allmydata/util/log.py +++ b/src/allmydata/util/log.py @@ -11,6 +11,7 @@ from __future__ import unicode_literals from future.utils import PY2 if PY2: from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 +from six import ensure_str from pyutil import nummedobj @@ -55,6 +56,7 @@ class LogMixin(object): pmsgid = self._parentmsgid if pmsgid is None: pmsgid = self._grandparentmsgid + kwargs = {ensure_str(k): v for (k, v) in kwargs.items()} msgid = log.msg(msg, facility=facility, parent=pmsgid, *args, **kwargs) if self._parentmsgid is None: self._parentmsgid = msgid