Răsfoiți Sursa

Fix warnings

Jelmer Vernooij 2 luni în urmă
părinte
comite
111fe24228

+ 0 - 1
MANIFEST.in

@@ -5,7 +5,6 @@ include COPYING
 include CONTRIBUTING.rst
 include TODO
 include dulwich/contrib/README.swift.rst
-include dulwich/stdint.h
 include dulwich/py.typed
 recursive-include docs conf.py *.txt Makefile make.bat
 recursive-include examples *.py

+ 20 - 4
dulwich/filters.py

@@ -310,7 +310,7 @@ class ProcessFilterDriver:
             except FilterError as e:
                 if self.required:
                     raise
-                logging.warning(f"Process filter failed, falling back: {e}")
+                logging.warning("Process filter failed, falling back: %s", e)
 
         # Fall back to clean command
         if not self.clean_cmd:
@@ -332,7 +332,7 @@ class ProcessFilterDriver:
             if self.required:
                 raise FilterError(f"Required clean filter failed: {e}")
             # If not required, log warning and return original data on failure
-            logging.warning(f"Optional clean filter failed: {e}")
+            logging.warning("Optional clean filter failed: %s", e)
             return data
 
     def smudge(self, data: bytes, path: bytes = b"") -> bytes:
@@ -346,7 +346,7 @@ class ProcessFilterDriver:
             except FilterError as e:
                 if self.required:
                     raise
-                logging.warning(f"Process filter failed, falling back: {e}")
+                logging.warning("Process filter failed, falling back: %s", e)
 
         # Fall back to smudge command
         if not self.smudge_cmd:
@@ -371,7 +371,7 @@ class ProcessFilterDriver:
             if self.required:
                 raise FilterError(f"Required smudge filter failed: {e}")
             # If not required, log warning and return original data on failure
-            logging.warning(f"Optional smudge filter failed: {e}")
+            logging.warning("Optional smudge filter failed: %s", e)
             return data
 
     def cleanup(self) -> None:
@@ -428,6 +428,22 @@ class ProcessFilterDriver:
                 except ProcessLookupError:
                     # Process already dead
                     pass
+
+            # Close stdout and stderr to prevent resource leaks
+            if self._process.stdout and not self._process.stdout.closed:
+                try:
+                    self._process.stdout.close()
+                except (OSError, ValueError):
+                    # OSError: I/O operation on closed file
+                    # ValueError: I/O operation on closed file (some platforms)
+                    pass
+
+            if self._process.stderr and not self._process.stderr.closed:
+                try:
+                    self._process.stderr.close()
+                except (OSError, ValueError):
+                    pass
+
         self._process = None
         self._protocol = None
 

+ 5 - 2
dulwich/line_ending.py

@@ -147,7 +147,7 @@ if TYPE_CHECKING:
 
 from . import replace_me
 from .attrs import GitAttributes, Pattern
-from .filters import FilterBlobNormalizer, FilterDriver, FilterRegistry
+from .filters import FilterBlobNormalizer, FilterContext, FilterDriver, FilterRegistry
 from .object_store import iter_tree_contents
 from .objects import Blob, ObjectID
 from .patch import is_binary
@@ -517,9 +517,12 @@ class BlobNormalizer(FilterBlobNormalizer):
 
         git_attributes = GitAttributes(git_attrs_patterns)
 
+        # Create FilterContext for parent class
+        filter_context = FilterContext(filter_registry)
+
         # Initialize parent class with gitattributes
         # The filter infrastructure will handle gitattributes processing
-        super().__init__(config_stack, git_attributes, filter_registry)
+        super().__init__(config_stack, git_attributes, filter_context=filter_context)
 
         # Store original filters for backward compatibility
         self.fallback_read_filter = smudge_filter

+ 1 - 1
dulwich/tests/utils.py

@@ -234,7 +234,7 @@ def build_pack(
     """
     sf = SHA1Writer(f)
     num_objects = len(objects_spec)
-    write_pack_header(sf, num_objects)
+    write_pack_header(sf.write, num_objects)
 
     full_objects: dict[int, tuple[int, bytes, bytes]] = {}
     offsets: dict[int, int] = {}

+ 2 - 2
tests/test_index.py

@@ -877,8 +877,8 @@ class GetUnstagedChangesTests(TestCase):
                     f.write(b"origstuff" + str(i).encode())
                 files.append(filename)
 
-            repo.stage(files)
-            repo.do_commit(
+            repo.get_worktree().stage(files)
+            repo.get_worktree().commit(
                 b"test status",
                 author=b"author <email>",
                 committer=b"committer <email>",

+ 4 - 1
tests/test_lfs_integration.py

@@ -61,8 +61,11 @@ class LFSFilterIntegrationTests(TestCase):
         ]
         self.gitattributes = GitAttributes(patterns)
 
+        from dulwich.filters import FilterContext
+
+        filter_context = FilterContext(self.registry)
         self.normalizer = FilterBlobNormalizer(
-            self.config, self.gitattributes, self.registry
+            self.config, self.gitattributes, filter_context=filter_context
         )
 
     def tearDown(self) -> None:

+ 10 - 4
tests/test_line_ending.py

@@ -486,9 +486,12 @@ class LineEndingIntegrationTests(TestCase):
         gitattributes = GitAttributes(patterns)
 
         # Create normalizer
-        from dulwich.filters import FilterBlobNormalizer
+        from dulwich.filters import FilterBlobNormalizer, FilterContext
 
-        normalizer = FilterBlobNormalizer(self.config, gitattributes, self.registry)
+        filter_context = FilterContext(self.registry)
+        normalizer = FilterBlobNormalizer(
+            self.config, gitattributes, filter_context=filter_context
+        )
 
         # Test round trip
         blob = Blob()
@@ -537,9 +540,12 @@ class LineEndingIntegrationTests(TestCase):
         ]
         gitattributes = GitAttributes(patterns)
 
-        from dulwich.filters import FilterBlobNormalizer
+        from dulwich.filters import FilterBlobNormalizer, FilterContext
 
-        normalizer = FilterBlobNormalizer(self.config, gitattributes, self.registry)
+        filter_context = FilterContext(self.registry)
+        normalizer = FilterBlobNormalizer(
+            self.config, gitattributes, filter_context=filter_context
+        )
 
         # Text file gets line ending conversion
         text_blob = Blob()

+ 16 - 16
tests/test_porcelain.py

@@ -10505,7 +10505,7 @@ class CherryTests(PorcelainTestCase):
     def test_cherry_no_changes(self):
         """Test cherry when head and upstream are the same."""
         # Create a simple commit
-        commit_sha = self.repo.do_commit(
+        commit_sha = self.repo.get_worktree().commit(
             b"Initial commit", committer=b"Test <test@example.com>"
         )
 
@@ -10520,16 +10520,16 @@ class CherryTests(PorcelainTestCase):
         # Create initial commit
         with open(os.path.join(self.repo_path, "file1.txt"), "w") as f:
             f.write("base content\n")
-        self.repo.stage(["file1.txt"])
-        base_commit = self.repo.do_commit(
+        self.repo.get_worktree().stage(["file1.txt"])
+        base_commit = self.repo.get_worktree().commit(
             b"Base commit", committer=b"Test <test@example.com>"
         )
 
         # Create a new commit on head
         with open(os.path.join(self.repo_path, "file2.txt"), "w") as f:
             f.write("new content\n")
-        self.repo.stage(["file2.txt"])
-        head_commit = self.repo.do_commit(
+        self.repo.get_worktree().stage(["file2.txt"])
+        head_commit = self.repo.get_worktree().commit(
             b"New commit", committer=b"Test <test@example.com>"
         )
 
@@ -10548,16 +10548,16 @@ class CherryTests(PorcelainTestCase):
         # Create initial commit
         with open(os.path.join(self.repo_path, "file1.txt"), "w") as f:
             f.write("base content\n")
-        self.repo.stage(["file1.txt"])
-        base_commit = self.repo.do_commit(
+        self.repo.get_worktree().stage(["file1.txt"])
+        base_commit = self.repo.get_worktree().commit(
             b"Base commit", committer=b"Test <test@example.com>"
         )
 
         # Create a new commit on head
         with open(os.path.join(self.repo_path, "file2.txt"), "w") as f:
             f.write("new content\n")
-        self.repo.stage(["file2.txt"])
-        head_commit = self.repo.do_commit(
+        self.repo.get_worktree().stage(["file2.txt"])
+        head_commit = self.repo.get_worktree().commit(
             b"New commit on head", committer=b"Test <test@example.com>"
         )
 
@@ -10579,26 +10579,26 @@ class CherryTests(PorcelainTestCase):
         # Create base commit
         with open(os.path.join(self.repo_path, "file.txt"), "w") as f:
             f.write("line1\n")
-        self.repo.stage(["file.txt"])
-        base_commit = self.repo.do_commit(
+        self.repo.get_worktree().stage(["file.txt"])
+        base_commit = self.repo.get_worktree().commit(
             b"Base commit", committer=b"Test <test@example.com>"
         )
 
         # Create upstream branch with a change
         with open(os.path.join(self.repo_path, "file.txt"), "w") as f:
             f.write("line1\nline2\n")
-        self.repo.stage(["file.txt"])
-        upstream_commit = self.repo.do_commit(
+        self.repo.get_worktree().stage(["file.txt"])
+        upstream_commit = self.repo.get_worktree().commit(
             b"Add line2", committer=b"Test <test@example.com>"
         )
 
         # Reset to base and create same change on head branch
         self.repo.refs[b"HEAD"] = base_commit
-        self.repo.reset_index()
+        self.repo.get_worktree().reset_index()
         with open(os.path.join(self.repo_path, "file.txt"), "w") as f:
             f.write("line1\nline2\n")
-        self.repo.stage(["file.txt"])
-        head_commit = self.repo.do_commit(
+        self.repo.get_worktree().stage(["file.txt"])
+        head_commit = self.repo.get_worktree().commit(
             b"Add line2 (different metadata)",
             committer=b"Different <different@example.com>",
         )

+ 16 - 10
tests/test_repository.py

@@ -839,7 +839,7 @@ exit 0
 
         self.assertRaises(
             errors.CommitError,
-            r.do_commit,
+            r.get_worktree().commit,
             b"failed commit",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
@@ -889,7 +889,7 @@ exit 0
 
         self.assertRaises(
             errors.CommitError,
-            r.do_commit,
+            r.get_worktree().commit,
             b"failed commit",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
@@ -927,7 +927,7 @@ with open('foo', 'w') as f:
     f.write('newfile')
 
 r = Repo('.')
-r.stage(['foo'])
+r.get_worktree().stage(['foo'])
 """.format(
             executable=sys.executable,
             path=[os.path.join(os.path.dirname(__file__), "..", ".."), *sys.path],
@@ -1415,10 +1415,13 @@ class BuildRepoRootTests(TestCase):
         r.object_store.add_object(tree)
 
         # Use do_commit for MemoryRepo since it doesn't support worktree
-        commit_sha = r.do_commit(
-            message=b"message",
-            tree=tree.id,
-        )
+        # Suppress deprecation warning since we're intentionally testing the deprecated method
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore", DeprecationWarning)
+            commit_sha = r.do_commit(
+                message=b"message",
+                tree=tree.id,
+            )
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].author)
         self.assertEqual(b"Jelmer <jelmer@apache.org>", r[commit_sha].committer)
 
@@ -1453,7 +1456,7 @@ class BuildRepoRootTests(TestCase):
         old_shas = set(r.object_store)
         self.assertRaises(
             errors.CommitError,
-            r.do_commit,
+            r.get_worktree().commit,
             b"failed commit",
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
@@ -1504,7 +1507,7 @@ class BuildRepoRootTests(TestCase):
 
         self.assertRaises(
             ValueError,
-            r.do_commit,
+            r.get_worktree().commit,
             message_callback,
             committer=b"Test Committer <test@nodomain.com>",
             author=b"Test Author <test@nodomain.com>",
@@ -1658,7 +1661,10 @@ class BuildRepoRootTests(TestCase):
     def test_stage_absolute(self) -> None:
         r = self._repo
         os.remove(os.path.join(r.path, "a"))
-        self.assertRaises(ValueError, r.stage, [os.path.join(r.path, "a")])
+        # Suppress deprecation warning since we're intentionally testing the deprecated method
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore", DeprecationWarning)
+            self.assertRaises(ValueError, r.stage, [os.path.join(r.path, "a")])
 
     def test_stage_deleted(self) -> None:
         r = self._repo

+ 3 - 1
tests/test_sparse_patterns.py

@@ -565,7 +565,9 @@ class ApplyIncludedPathsTests(TestCase):
 
         # Add and commit .gitattributes
         self.repo.get_worktree().stage([b".gitattributes"])
-        self.repo.do_commit(b"Add gitattributes", committer=b"Test <test@example.com>")
+        self.repo.get_worktree().commit(
+            b"Add gitattributes", committer=b"Test <test@example.com>"
+        )
 
         # Initialize the filter context and register the filter
         _ = self.repo.get_blob_normalizer()