diff --git a/NEWS b/NEWS index eda6774a4..9835ad21c 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,11 @@ * Fixed failing test-cases on windows. (Koen Martens) + API CHANGES + + * Repo is now a context manager, so that it can be easily + closed using a ``with`` statement. + TEST FIXES * Only run worktree list compat tests against git 2.7.0, diff --git a/dulwich/repo.py b/dulwich/repo.py index 4b6180ab0..f1b58f593 100644 --- a/dulwich/repo.py +++ b/dulwich/repo.py @@ -1057,6 +1057,12 @@ def close(self): """Close any files opened by this repository.""" self.object_store.close() + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + class MemoryRepo(BaseRepo): """Repo that stores refs, objects, and named files in memory. diff --git a/dulwich/tests/compat/test_client.py b/dulwich/tests/compat/test_client.py index 85c22a238..368a4ba29 100644 --- a/dulwich/tests/compat/test_client.py +++ b/dulwich/tests/compat/test_client.py @@ -20,7 +20,6 @@ """Compatibilty tests between the Dulwich client and the cgit server.""" -from contextlib import closing import copy from io import BytesIO import os @@ -87,8 +86,8 @@ def tearDown(self): def assertDestEqualsSrc(self): repo_dir = os.path.join(self.gitroot, 'server_new.export') dest_repo_dir = os.path.join(self.gitroot, 'dest') - with closing(repo.Repo(repo_dir)) as src: - with closing(repo.Repo(dest_repo_dir)) as dest: + with repo.Repo(repo_dir) as src: + with repo.Repo(dest_repo_dir) as dest: self.assertReposEqual(src, dest) def _client(self): @@ -100,7 +99,7 @@ def _build_path(self): def _do_send_pack(self): c = self._client() srcpath = os.path.join(self.gitroot, 'server_new.export') - with closing(repo.Repo(srcpath)) as src: + with repo.Repo(srcpath) as src: sendrefs = dict(src.get_refs()) del sendrefs[b'HEAD'] c.send_pack(self._build_path(b'/dest'), lambda _: sendrefs, @@ -120,7 +119,7 @@ def test_send_without_report_status(self): c = self._client() c._send_capabilities.remove(b'report-status') srcpath = os.path.join(self.gitroot, 'server_new.export') - with closing(repo.Repo(srcpath)) as src: + with repo.Repo(srcpath) as src: sendrefs = dict(src.get_refs()) del sendrefs[b'HEAD'] c.send_pack(self._build_path(b'/dest'), lambda _: sendrefs, @@ -157,7 +156,7 @@ def test_send_pack_one_error(self): dest, dummy_commit = self.disable_ff_and_make_dummy_commit() dest.refs[b'refs/heads/master'] = dummy_commit repo_dir = os.path.join(self.gitroot, 'server_new.export') - with closing(repo.Repo(repo_dir)) as src: + with repo.Repo(repo_dir) as src: sendrefs, gen_pack = self.compute_send(src) c = self._client() try: @@ -175,7 +174,7 @@ def test_send_pack_multiple_errors(self): branch, master = b'refs/heads/branch', b'refs/heads/master' dest.refs[branch] = dest.refs[master] = dummy repo_dir = os.path.join(self.gitroot, 'server_new.export') - with closing(repo.Repo(repo_dir)) as src: + with repo.Repo(repo_dir) as src: sendrefs, gen_pack = self.compute_send(src) c = self._client() try: @@ -200,7 +199,7 @@ def test_archive(self): def test_fetch_pack(self): c = self._client() - with closing(repo.Repo(os.path.join(self.gitroot, 'dest'))) as dest: + with repo.Repo(os.path.join(self.gitroot, 'dest')) as dest: refs = c.fetch(self._build_path(b'/server_new.export'), dest) for r in refs.items(): dest.refs.set_if_equals(r[0], None, r[1]) @@ -212,7 +211,7 @@ def test_incremental_fetch_pack(self): dest.refs[b'refs/heads/master'] = dummy c = self._client() repo_dir = os.path.join(self.gitroot, 'server_new.export') - with closing(repo.Repo(repo_dir)) as dest: + with repo.Repo(repo_dir) as dest: refs = c.fetch(self._build_path(b'/dest'), dest) for r in refs.items(): dest.refs.set_if_equals(r[0], None, r[1]) @@ -221,7 +220,7 @@ def test_incremental_fetch_pack(self): def test_fetch_pack_no_side_band_64k(self): c = self._client() c._fetch_capabilities.remove(b'side-band-64k') - with closing(repo.Repo(os.path.join(self.gitroot, 'dest'))) as dest: + with repo.Repo(os.path.join(self.gitroot, 'dest')) as dest: refs = c.fetch(self._build_path(b'/server_new.export'), dest) for r in refs.items(): dest.refs.set_if_equals(r[0], None, r[1]) @@ -231,14 +230,14 @@ def test_fetch_pack_zero_sha(self): # zero sha1s are already present on the client, and should # be ignored c = self._client() - with closing(repo.Repo(os.path.join(self.gitroot, 'dest'))) as dest: + with repo.Repo(os.path.join(self.gitroot, 'dest')) as dest: refs = c.fetch(self._build_path(b'/server_new.export'), dest, lambda refs: [protocol.ZERO_SHA]) for r in refs.items(): dest.refs.set_if_equals(r[0], None, r[1]) def test_send_remove_branch(self): - with closing(repo.Repo(os.path.join(self.gitroot, 'dest'))) as dest: + with repo.Repo(os.path.join(self.gitroot, 'dest')) as dest: dummy_commit = self.make_dummy_commit(dest) dest.refs[b'refs/heads/master'] = dummy_commit dest.refs[b'refs/heads/abranch'] = dummy_commit @@ -256,7 +255,7 @@ def test_get_refs(self): refs = c.get_refs(self._build_path(b'/server_new.export')) repo_dir = os.path.join(self.gitroot, 'server_new.export') - with closing(repo.Repo(repo_dir)) as dest: + with repo.Repo(repo_dir) as dest: self.assertDictEqual(dest.refs.as_dict(), refs) diff --git a/dulwich/tests/test_client.py b/dulwich/tests/test_client.py index 9ac5f95a9..59ac959fd 100644 --- a/dulwich/tests/test_client.py +++ b/dulwich/tests/test_client.py @@ -18,7 +18,6 @@ # License, Version 2.0. # -from contextlib import closing from io import BytesIO import sys import shutil @@ -753,7 +752,7 @@ def test_send_pack_with_changes(self): target_path = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, target_path) - with closing(Repo.init_bare(target_path)) as target: + with Repo.init_bare(target_path) as target: self.send_and_verify(b"master", local, target) def test_get_refs(self): diff --git a/dulwich/tests/test_index.py b/dulwich/tests/test_index.py index 45e31a32c..2e55bdde8 100644 --- a/dulwich/tests/test_index.py +++ b/dulwich/tests/test_index.py @@ -23,7 +23,6 @@ """Tests for the index.""" -from contextlib import closing from io import BytesIO import os import shutil @@ -267,7 +266,7 @@ def assertFileContents(self, path, contents, symlink=False): def test_empty(self): repo_dir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, repo_dir) - with closing(Repo.init(repo_dir)) as repo: + with Repo.init(repo_dir) as repo: tree = Tree() repo.object_store.add_object(tree) @@ -284,7 +283,7 @@ def test_empty(self): def test_git_dir(self): repo_dir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, repo_dir) - with closing(Repo.init(repo_dir)) as repo: + with Repo.init(repo_dir) as repo: # Populate repo filea = Blob.from_string(b'file a') @@ -318,7 +317,7 @@ def test_git_dir(self): def test_nonempty(self): repo_dir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, repo_dir) - with closing(Repo.init(repo_dir)) as repo: + with Repo.init(repo_dir) as repo: # Populate repo filea = Blob.from_string(b'file a') @@ -371,7 +370,7 @@ def test_nonempty(self): def test_symlink(self): repo_dir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, repo_dir) - with closing(Repo.init(repo_dir)) as repo: + with Repo.init(repo_dir) as repo: # Populate repo filed = Blob.from_string(b'file d') @@ -403,7 +402,7 @@ def test_no_decode_encode(self): repo_dir = tempfile.mkdtemp() repo_dir_bytes = repo_dir.encode(sys.getfilesystemencoding()) self.addCleanup(shutil.rmtree, repo_dir) - with closing(Repo.init(repo_dir)) as repo: + with Repo.init(repo_dir) as repo: # Populate repo file = Blob.from_string(b'foo') @@ -438,7 +437,7 @@ def test_get_unstaged_changes(self): repo_dir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, repo_dir) - with closing(Repo.init(repo_dir)) as repo: + with Repo.init(repo_dir) as repo: # Commit a dummy file then modify it foo1_fullpath = os.path.join(repo_dir, 'foo1') diff --git a/dulwich/tests/test_porcelain.py b/dulwich/tests/test_porcelain.py index 45b1c4a05..2198df13b 100644 --- a/dulwich/tests/test_porcelain.py +++ b/dulwich/tests/test_porcelain.py @@ -20,7 +20,6 @@ """Tests for dulwich.porcelain.""" -from contextlib import closing from io import BytesIO try: from StringIO import StringIO @@ -148,11 +147,11 @@ def test_simple_local_with_checkout(self): target_path = tempfile.mkdtemp() errstream = BytesIO() self.addCleanup(shutil.rmtree, target_path) - with closing(porcelain.clone(self.repo.path, target_path, - checkout=True, - errstream=errstream)) as r: + with porcelain.clone(self.repo.path, target_path, + checkout=True, + errstream=errstream) as r: self.assertEqual(r.path, target_path) - with closing(Repo(target_path)) as r: + with Repo(target_path) as r: self.assertEqual(r.head(), c3.id) self.assertTrue('f1' in os.listdir(target_path)) self.assertTrue('f2' in os.listdir(target_path)) @@ -519,7 +518,7 @@ def test_simple(self): errstream=errstream) # Check that the target and source - with closing(Repo(clone_path)) as r_clone: + with Repo(clone_path) as r_clone: self.assertEqual({ b'HEAD': new_id, b'refs/heads/foo': r_clone[b'HEAD'].id, @@ -606,7 +605,7 @@ def test_simple(self): outstream=outstream, errstream=errstream) # Check the target repo for pushed changes - with closing(Repo(self.target_path)) as r: + with Repo(self.target_path) as r: self.assertEqual(r[b'HEAD'].id, self.repo[b'HEAD'].id) def test_no_refspec(self): @@ -618,7 +617,7 @@ def test_no_refspec(self): errstream=errstream) # Check the target repo for pushed changes - with closing(Repo(self.target_path)) as r: + with Repo(self.target_path) as r: self.assertEqual(r[b'HEAD'].id, self.repo[b'HEAD'].id) @@ -838,7 +837,7 @@ def test_simple(self): errstream=errstream) # Check the target repo for pushed changes - with closing(Repo(target_path)) as r: + with Repo(target_path) as r: self.assertTrue(self.repo[b'HEAD'].id in r) diff --git a/dulwich/tests/test_repository.py b/dulwich/tests/test_repository.py index de37253cc..2719f2041 100644 --- a/dulwich/tests/test_repository.py +++ b/dulwich/tests/test_repository.py @@ -21,7 +21,6 @@ """Tests for the repository.""" -from contextlib import closing import locale import os import stat @@ -239,7 +238,7 @@ def test_clone(self): r = self.open_repo('a.git') tmp_dir = self.mkdtemp() self.addCleanup(shutil.rmtree, tmp_dir) - with closing(r.clone(tmp_dir, mkdir=False)) as t: + with r.clone(tmp_dir, mkdir=False) as t: self.assertEqual({ b'HEAD': b'a90fa2d900a17e99b433217e988c4eb4a2e9a097', b'refs/remotes/origin/master': @@ -330,7 +329,7 @@ def test_submodule(self): os.path.join(temp_dir, 'a.git'), symlinks=True) rel = os.path.relpath(os.path.join(repo_dir, 'submodule'), temp_dir) os.symlink(os.path.join(rel, 'dotgit'), os.path.join(temp_dir, '.git')) - with closing(Repo(temp_dir)) as r: + with Repo(temp_dir) as r: self.assertEqual(r.head(), b'a90fa2d900a17e99b433217e988c4eb4a2e9a097') def test_common_revisions(self): @@ -531,7 +530,7 @@ def check(repo): bare = self.open_repo('a.git') tmp_dir = self.mkdtemp() self.addCleanup(shutil.rmtree, tmp_dir) - with closing(bare.clone(tmp_dir, mkdir=False)) as nonbare: + with bare.clone(tmp_dir, mkdir=False) as nonbare: check(nonbare) check(bare)