=== modified file 'breezy/bzr/tests/per_pack_repository.py'
--- old/breezy/bzr/tests/per_pack_repository.py	2020-06-10 02:56:53 +0000
+++ new/breezy/bzr/tests/per_pack_repository.py	2022-05-03 20:36:36 +0000
@@ -96,9 +96,10 @@
         self.check_databases(t)
 
     def check_format(self, t):
-        self.assertEqualDiff(
-            self.format_string.encode('ascii'),  # from scenario
-            t.get('format').read())
+        with t.get('format') as f:
+            self.assertEqualDiff(
+                self.format_string.encode('ascii'),  # from scenario
+                f.read())
 
     def assertHasNoKndx(self, t, knit_name):
         """Assert that knit_name has no index on t."""

=== modified file 'breezy/bzr/tests/test_repository.py'
--- old/breezy/bzr/tests/test_repository.py	2020-06-21 21:43:36 +0000
+++ new/breezy/bzr/tests/test_repository.py	2022-05-03 20:36:36 +0000
@@ -267,8 +267,9 @@
 
     def assertHasKnit(self, t, knit_name, extra_content=b''):
         """Assert that knit_name exists on t."""
-        self.assertEqualDiff(b'# bzr knit index 8\n' + extra_content,
-                             t.get(knit_name + '.kndx').read())
+        with t.get(knit_name + '.kndx') as f:
+            self.assertEqualDiff(b'# bzr knit index 8\n' + extra_content,
+                                 f.read())
 
     def check_knits(self, t):
         """check knit content for a repository."""
@@ -292,7 +293,8 @@
                                  f.read())
         # XXX: no locks left when unlocked at the moment
         # self.assertEqualDiff('', t.get('lock').read())
-        self.assertEqualDiff(b'', t.get('shared-storage').read())
+        with t.get('shared-storage') as f:
+            self.assertEqualDiff(b'', f.read())
         self.assertTrue(S_ISDIR(t.stat('knits').st_mode))
         self.check_knits(t)
 
@@ -314,8 +316,10 @@
                                  f.read())
         # XXX: no locks left when unlocked at the moment
         # self.assertEqualDiff('', t.get('lock').read())
-        self.assertEqualDiff(b'', t.get('shared-storage').read())
-        self.assertEqualDiff(b'', t.get('no-working-trees').read())
+        with t.get('shared-storage') as f:
+            self.assertEqualDiff(b'', f.read())
+        with t.get('no-working-trees') as f:
+            self.assertEqualDiff(b'', f.read())
         repo.set_make_working_trees(True)
         self.assertFalse(t.has('no-working-trees'))
         self.assertTrue(S_ISDIR(t.stat('knits').st_mode))

=== modified file 'breezy/bzr/tests/test_workingtree_4.py'
--- old/breezy/bzr/tests/test_workingtree_4.py	2020-06-10 21:13:00 +0000
+++ new/breezy/bzr/tests/test_workingtree_4.py	2022-05-03 20:36:36 +0000
@@ -47,8 +47,9 @@
         # format 'Bazaar Working Tree format 4'
         # stat-cache = ??
         t = control.get_workingtree_transport(None)
-        self.assertEqualDiff(b'Bazaar Working Tree Format 4 (bzr 0.15)\n',
-                             t.get('format').read())
+        with t.get('format') as f:
+            self.assertEqualDiff(b'Bazaar Working Tree Format 4 (bzr 0.15)\n',
+                                 f.read())
         self.assertFalse(t.has('inventory.basis'))
         # no last-revision file means 'None' or 'NULLREVISION'
         self.assertFalse(t.has('last-revision'))

=== modified file 'breezy/plugins/weave_fmt/test_store.py'
--- old/breezy/plugins/weave_fmt/test_store.py	2020-02-07 02:14:30 +0000
+++ new/breezy/plugins/weave_fmt/test_store.py	2022-05-03 20:36:36 +0000
@@ -36,8 +36,8 @@
     """Mixin template class that provides some common tests for stores"""
 
     def check_content(self, store, fileid, value):
-        f = store.get(fileid)
-        self.assertEqual(f.read(), value)
+        with store.get(fileid) as f:
+            self.assertEqual(f.read(), value)
 
     def fill_store(self, store):
         store.add(BytesIO(b'hello'), b'a')

=== modified file 'breezy/tests/blackbox/test_bisect.py'
--- old/breezy/tests/blackbox/test_bisect.py	2020-06-19 21:26:53 +0000
+++ new/breezy/tests/blackbox/test_bisect.py	2022-05-03 20:36:36 +0000
@@ -41,8 +41,8 @@
                         1.3: "one dot three", 2: "two", 3: "three",
                         4: "four", 5: "five"}
 
-        test_file = open("test_file")
-        content = test_file.read().strip()
+        with open("test_file") as test_file:
+            content = test_file.read().strip()
         if content != rev_contents[rev]:
             rev_ids = dict((rev_contents[k], k) for k in rev_contents.keys())
             found_rev = rev_ids[content]
@@ -60,14 +60,12 @@
 
         self.tree = self.make_branch_and_tree(".")
 
-        test_file = open("test_file", "w")
-        test_file.write("one")
-        test_file.close()
+        with open("test_file", "w") as test_file:
+            test_file.write("one")
         self.tree.add(self.tree.relpath(os.path.join(os.getcwd(),
                                                      'test_file')))
-        test_file_append = open("test_file_append", "a")
-        test_file_append.write("one\n")
-        test_file_append.close()
+        with open("test_file_append", "a") as test_file_append:
+            test_file_append.write("one\n")
         self.tree.add(self.tree.relpath(os.path.join(os.getcwd(),
                                                      'test_file_append')))
         self.tree.commit(message="add test files")
@@ -76,22 +74,18 @@
         clone_controldir = ControlDir.open("../temp-clone")
         clone_tree = clone_controldir.open_workingtree()
         for content in ["one dot one", "one dot two", "one dot three"]:
-            test_file = open("../temp-clone/test_file", "w")
-            test_file.write(content)
-            test_file.close()
-            test_file_append = open("../temp-clone/test_file_append", "a")
-            test_file_append.write(content + "\n")
-            test_file_append.close()
+            with open("../temp-clone/test_file", "w") as test_file:
+                test_file.write(content)
+            with open("../temp-clone/test_file_append", "a") as test_file_append:
+                test_file_append.write(content + "\n")
             clone_tree.commit(message="make branch test change")
             saved_subtree_revid = clone_tree.branch.last_revision()
 
         self.tree.merge_from_branch(clone_tree.branch)
-        test_file = open("test_file", "w")
-        test_file.write("two")
-        test_file.close()
-        test_file_append = open("test_file_append", "a")
-        test_file_append.write("two\n")
-        test_file_append.close()
+        with open("test_file", "w") as test_file:
+            test_file.write("two")
+        with open("test_file_append", "a") as test_file_append:
+            test_file_append.write("two\n")
         self.tree.commit(message="merge external branch")
         shutil.rmtree("../temp-clone")
 
@@ -99,12 +93,10 @@
 
         file_contents = ["three", "four", "five"]
         for content in file_contents:
-            test_file = open("test_file", "w")
-            test_file.write(content)
-            test_file.close()
-            test_file_append = open("test_file_append", "a")
-            test_file_append.write(content + "\n")
-            test_file_append.close()
+            with open("test_file", "w") as test_file:
+                test_file.write(content)
+            with open("test_file_append", "a") as test_file_append:
+                test_file_append.write(content + "\n")
             self.tree.commit(message="make test change")
 
     def testWorkflow(self):
@@ -205,16 +197,14 @@
         # Check that reset doesn't do anything unless there's a
         # bisection in progress.
 
-        test_file = open("test_file", "w")
-        test_file.write("keep me")
-        test_file.close()
+        with open("test_file", "w") as test_file:
+            test_file.write("keep me")
 
         out, err = self.run_bzr(['bisect', 'reset'], retcode=3)
         self.assertIn("No bisection in progress.", err)
 
-        test_file = open("test_file")
-        content = test_file.read().strip()
-        test_file.close()
+        with open("test_file") as test_file:
+            content = test_file.read().strip()
         self.assertEqual(content, "keep me")
 
     def testLog(self):
@@ -248,10 +238,9 @@
 
     def testRunScript(self):
         """Make a test script and run it."""
-        test_script = open("test_script", "w")
-        test_script.write("#!/bin/sh\n"
-                          "grep -q '^four' test_file_append\n")
-        test_script.close()
+        with open("test_script", "w") as test_script:
+            test_script.write("#!/bin/sh\n"
+                              "grep -q '^four' test_file_append\n")
         os.chmod("test_script", stat.S_IRWXU)
         self.run_bzr(['bisect', 'start'])
         self.run_bzr(['bisect', 'yes'])
@@ -263,10 +252,9 @@
         """Make a test script and run it."""
         if sys.platform == "win32":
             raise TestSkipped("Unable to run shell script on windows")
-        test_script = open("test_script", "w")
-        test_script.write("#!/bin/sh\n"
-                          "grep -q '^two' test_file_append\n")
-        test_script.close()
+        with open("test_script", "w") as test_script:
+            test_script.write("#!/bin/sh\n"
+                              "grep -q '^two' test_file_append\n")
         os.chmod("test_script", stat.S_IRWXU)
         self.run_bzr(['bisect', 'start'])
         self.run_bzr(['bisect', 'yes'])
@@ -282,10 +270,9 @@
         """Make a test script and run it."""
         if sys.platform == "win32":
             raise TestSkipped("Unable to run shell script on windows")
-        test_script = open("test_script", "w")
-        test_script.write("#!/bin/sh\n"
-                          "grep -q '^one dot two' test_file_append\n")
-        test_script.close()
+        with open("test_script", "w") as test_script:
+            test_script.write("#!/bin/sh\n"
+                              "grep -q '^one dot two' test_file_append\n")
         os.chmod("test_script", stat.S_IRWXU)
         self.run_bzr(['bisect', 'start'])
         self.run_bzr(['bisect', 'yes'])

=== modified file 'breezy/tests/blackbox/test_export.py'
--- old/breezy/tests/blackbox/test_export.py	2022-01-03 16:41:02 +0000
+++ new/breezy/tests/blackbox/test_export.py	2022-05-03 20:36:36 +0000
@@ -93,11 +93,11 @@
         self.assertTrue(tree.has_filename('.bzr-adir'))
         self.assertTrue(tree.has_filename('.bzr-adir/afile'))
         self.run_bzr('export test.tar.gz -d tree')
-        ball = tarfile.open('test.tar.gz')
-        # Make sure the tarball contains 'a', but does not contain
-        # '.bzrignore'.
-        self.assertEqual(['test/a'],
-                         sorted(ball.getnames()))
+        with tarfile.open('test.tar.gz') as ball:
+            # Make sure the tarball contains 'a', but does not contain
+            # '.bzrignore'.
+            self.assertEqual(['test/a'],
+                             sorted(ball.getnames()))
 
     def test_tar_export_unicode_filename(self):
         self.requireFeature(features.UnicodeFilenameFeature)
@@ -111,10 +111,10 @@
         tree.commit('first')
 
         self.run_bzr('export test.tar -d tar')
-        ball = tarfile.open('test.tar')
-        # all paths are prefixed with the base name of the tarball
-        self.assertEqual([u'test/' + fname],
-                         [osutils.safe_unicode(n) for n in ball.getnames()])
+        with tarfile.open('test.tar') as ball:
+            # all paths are prefixed with the base name of the tarball
+            self.assertEqual([u'test/' + fname],
+                             [osutils.safe_unicode(n) for n in ball.getnames()])
 
     def test_tar_export_unicode_basedir(self):
         """Test for bug #413406"""
@@ -179,12 +179,12 @@
         fname = 'test.%s' % (extension,)
         self.run_bzr('export -d tree %s' % (fname,))
         mode = 'r|%s' % (tarfile_flags,)
-        ball = tarfile.open(fname, mode=mode)
-        self.assertTarANameAndContent(ball, root='test/')
+        with tarfile.open(fname, mode=mode) as ball:
+            self.assertTarANameAndContent(ball, root='test/')
         content = self.run_bzr_raw(
             'export -d tree --format=%s -' % (extension,))[0]
-        ball = tarfile.open(mode=mode, fileobj=BytesIO(content))
-        self.assertTarANameAndContent(ball, root='')
+        with tarfile.open(mode=mode, fileobj=BytesIO(content)) as ball:
+            self.assertTarANameAndContent(ball, root='')
 
     def test_tar_export(self):
         self.run_tar_export_disk_and_stdout('tar', '')

=== modified file 'tools/generate_docs.py'
--- old/tools/generate_docs.py	2020-01-31 17:43:44 +0000
+++ new/tools/generate_docs.py	2022-05-03 20:36:36 +0000
@@ -43,6 +43,7 @@
     commands,
     doc_generate,
     )
+from contextlib import ExitStack
 
 
 def main(argv):
@@ -76,7 +77,7 @@
         parser.print_help()
         sys.exit(1)
 
-    with breezy.initialize():
+    with breezy.initialize(), ExitStack() as es:
         # Import breezy.bzr for format registration, see <http://pad.lv/956860>
         from breezy import bzr as _
         commands.install_bzr_command_hooks()
@@ -89,7 +90,7 @@
         if outfilename == "-":
             outfile = sys.stdout
         else:
-            outfile = open(outfilename, "w")
+            outfile = es.enter_context(open(outfilename, "w"))
         if options.show_filename and (outfilename != "-"):
             sys.stdout.write(outfilename)
             sys.stdout.write('\n')

