From 61506f87bb1f46f46eac30577be5df9413526883 Mon Sep 17 00:00:00 2001
From: Itamar Turner-Trauring <itamar@itamarst.org>
Date: Fri, 16 Apr 2021 11:55:20 -0400
Subject: [PATCH 1/4] Make BytesWarning->exception global, to ease use in
 integration tests.

---
 src/allmydata/__init__.py      | 17 ++++++++++++++++-
 src/allmydata/test/__init__.py |  6 ------
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/allmydata/__init__.py b/src/allmydata/__init__.py
index b29868c05..333394fc5 100644
--- a/src/allmydata/__init__.py
+++ b/src/allmydata/__init__.py
@@ -8,7 +8,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, PY3
 if PY2:
     # Don't import future str() so we don't break Foolscap serialization on Python 2.
     from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, max, min  # noqa: F401
@@ -62,3 +62,18 @@ standard_library.install_aliases()
 from ._monkeypatch import patch
 patch()
 del patch
+
+
+# On Python 3, turn BytesWarnings into exceptions. This can have potential
+# production impact... if BytesWarnings are actually present in the codebase.
+# Given that this has been enabled before Python 3 Tahoe-LAFS was publicly
+# released, no such code should exist, and this will ensure it doesn't get
+# added either.
+#
+# Also note that BytesWarnings only happen if Python is run with -b option, so
+# in practice this should only affect tests.
+if PY3:
+    import warnings
+    # Error on BytesWarnings, to catch things like str(b""), but only for
+    # allmydata code.
+    warnings.filterwarnings("error", category=BytesWarning, module=".*allmydata.*")
diff --git a/src/allmydata/test/__init__.py b/src/allmydata/test/__init__.py
index e9c47bd69..45536a6c6 100644
--- a/src/allmydata/test/__init__.py
+++ b/src/allmydata/test/__init__.py
@@ -24,7 +24,6 @@ from future.utils import PY2, PY3
 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
 
-import warnings
 from traceback import extract_stack, format_list
 
 from foolscap.pb import Listener
@@ -33,11 +32,6 @@ from twisted.application import service
 
 from foolscap.logging.incident import IncidentQualifier
 
-if PY3:
-    # Error on BytesWarnings, to catch things like str(b""), but only for
-    # allmydata code.
-    warnings.filterwarnings("error", category=BytesWarning, module=".*allmydata.*")
-
 
 class NonQualifier(IncidentQualifier, object):
     def check_event(self, ev):

From fa46efdb3aae72df3f0ecc2987d42b70c92927c7 Mon Sep 17 00:00:00 2001
From: Itamar Turner-Trauring <itamar@itamarst.org>
Date: Fri, 16 Apr 2021 11:58:37 -0400
Subject: [PATCH 2/4] Enable BytesWarnings in integration tests.

---
 integration/test_servers_of_happiness.py | 2 +-
 integration/test_tor.py                  | 6 +++---
 integration/util.py                      | 4 ++--
 src/allmydata/test/cli_node_api.py       | 1 +
 src/allmydata/test/test_runner.py        | 2 +-
 src/allmydata/test/test_system.py        | 2 +-
 6 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/integration/test_servers_of_happiness.py b/integration/test_servers_of_happiness.py
index 97392bf00..1f350eb8e 100644
--- a/integration/test_servers_of_happiness.py
+++ b/integration/test_servers_of_happiness.py
@@ -30,7 +30,7 @@ def test_upload_immutable(reactor, temp_dir, introducer_furl, flog_gatherer, sto
         proto,
         sys.executable,
         [
-            sys.executable, '-m', 'allmydata.scripts.runner',
+            sys.executable, '-b', '-m', 'allmydata.scripts.runner',
             '-d', node_dir,
             'put', __file__,
         ]
diff --git a/integration/test_tor.py b/integration/test_tor.py
index dcbfb1151..3b374f669 100644
--- a/integration/test_tor.py
+++ b/integration/test_tor.py
@@ -46,7 +46,7 @@ def test_onion_service_storage(reactor, request, temp_dir, flog_gatherer, tor_ne
         proto,
         sys.executable,
         (
-            sys.executable, '-m', 'allmydata.scripts.runner',
+            sys.executable, '-b', '-m', 'allmydata.scripts.runner',
             '-d', join(temp_dir, 'carol'),
             'put', gold_path,
         )
@@ -60,7 +60,7 @@ def test_onion_service_storage(reactor, request, temp_dir, flog_gatherer, tor_ne
         proto,
         sys.executable,
         (
-            sys.executable, '-m', 'allmydata.scripts.runner',
+            sys.executable, '-b', '-m', 'allmydata.scripts.runner',
             '-d', join(temp_dir, 'dave'),
             'get', cap,
         )
@@ -84,7 +84,7 @@ def _create_anonymous_node(reactor, name, control_port, request, temp_dir, flog_
             proto,
             sys.executable,
             (
-                sys.executable, '-m', 'allmydata.scripts.runner',
+                sys.executable, '-b', '-m', 'allmydata.scripts.runner',
                 'create-node',
                 '--nickname', name,
                 '--introducer', introducer_furl,
diff --git a/integration/util.py b/integration/util.py
index 256fd68c1..b72e11c72 100644
--- a/integration/util.py
+++ b/integration/util.py
@@ -152,9 +152,9 @@ def _tahoe_runner_optional_coverage(proto, reactor, request, other_args):
     `--coverage` option if the `request` indicates we should.
     """
     if request.config.getoption('coverage'):
-        args = [sys.executable, '-m', 'coverage', 'run', '-m', 'allmydata.scripts.runner', '--coverage']
+        args = [sys.executable, '-b', '-m', 'coverage', 'run', '-m', 'allmydata.scripts.runner', '--coverage']
     else:
-        args = [sys.executable, '-m', 'allmydata.scripts.runner']
+        args = [sys.executable, '-b', '-m', 'allmydata.scripts.runner']
     args += other_args
     return reactor.spawnProcess(
         proto,
diff --git a/src/allmydata/test/cli_node_api.py b/src/allmydata/test/cli_node_api.py
index 4e4173924..be0381e11 100644
--- a/src/allmydata/test/cli_node_api.py
+++ b/src/allmydata/test/cli_node_api.py
@@ -154,6 +154,7 @@ class CLINodeAPI(object):
         exe = sys.executable
         argv = [
             exe,
+            "-b",
             u"-m",
             u"allmydata.scripts.runner",
         ] + argv
diff --git a/src/allmydata/test/test_runner.py b/src/allmydata/test/test_runner.py
index c80b5dc9c..7cc89c287 100644
--- a/src/allmydata/test/test_runner.py
+++ b/src/allmydata/test/test_runner.py
@@ -88,7 +88,7 @@ def run_bintahoe(extra_argv, python_options=None):
     argv = [executable]
     if python_options is not None:
         argv.extend(python_options)
-    argv.extend([u"-m", u"allmydata.scripts.runner"])
+    argv.extend([u"-b", u"-m", u"allmydata.scripts.runner"])
     argv.extend(extra_argv)
     argv = list(unicode_to_argv(arg) for arg in argv)
     p = Popen(argv, stdout=PIPE, stderr=PIPE)
diff --git a/src/allmydata/test/test_system.py b/src/allmydata/test/test_system.py
index 040104b4c..0ff1e06e9 100644
--- a/src/allmydata/test/test_system.py
+++ b/src/allmydata/test/test_system.py
@@ -76,7 +76,7 @@ class RunBinTahoeMixin(object):
         # support env yet and is also synchronous.  If we could get rid of
         # this in favor of that, though, it would probably be an improvement.
         command = sys.executable
-        argv = python_options + ["-m", "allmydata.scripts.runner"] + args
+        argv = python_options + ["-b", "-m", "allmydata.scripts.runner"] + args
 
         if env is None:
             env = os.environ

From 08772c5a86b3f3b360e17891e3d3bf887bb68462 Mon Sep 17 00:00:00 2001
From: Itamar Turner-Trauring <itamar@itamarst.org>
Date: Fri, 16 Apr 2021 11:58:55 -0400
Subject: [PATCH 3/4] News file.

---
 newsfragments/3619.minor | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 newsfragments/3619.minor

diff --git a/newsfragments/3619.minor b/newsfragments/3619.minor
new file mode 100644
index 000000000..e69de29bb

From abb247b3cc120568a9765c89d7f0ea61faea3072 Mon Sep 17 00:00:00 2001
From: Itamar Turner-Trauring <itamar@itamarst.org>
Date: Fri, 16 Apr 2021 12:01:07 -0400
Subject: [PATCH 4/4] Fix flake.

---
 src/allmydata/test/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/allmydata/test/__init__.py b/src/allmydata/test/__init__.py
index 45536a6c6..abf23a301 100644
--- a/src/allmydata/test/__init__.py
+++ b/src/allmydata/test/__init__.py
@@ -20,7 +20,7 @@ from __future__ import division
 from __future__ import print_function
 from __future__ import unicode_literals
 
-from future.utils import PY2, PY3
+from future.utils import PY2
 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