Преглед на файлове

Use dissolve to manage deprecations

Jelmer Vernooij преди 2 месеца
родител
ревизия
11a3cd5314
променени са 7 файла, в които са добавени 50 реда и са изтрити 19 реда
  1. 11 0
      CONTRIBUTING.rst
  2. 2 0
      NEWS
  3. 27 0
      dulwich/__init__.py
  4. 3 7
      dulwich/objects.py
  5. 2 3
      dulwich/pack.py
  6. 3 8
      dulwich/porcelain.py
  7. 2 1
      pyproject.toml

+ 11 - 0
CONTRIBUTING.rst

@@ -49,6 +49,17 @@ Merge requests
 Please either send pull requests to the maintainer (jelmer@jelmer.uk) or create
 new pull requests on GitHub.
 
+Deprecating functionality
+-------------------------
+Dulwich uses the `dissolve` package to manage deprecations. If you want to deprecate
+functionality, please use the `@replace_me` decorator from the root of the
+dulwich package. This will ensure that the deprecation is handled correctly:
+
+* It will be logged as a warning
+* When the version of Dulwich is bumped, the deprecation will be removed
+* Users can use `dissolve migrate` to automatically replace deprecated
+  functionality in their code
+
 Licensing
 ---------
 All contributions should be made under the same license that Dulwich itself

+ 2 - 0
NEWS

@@ -37,6 +37,8 @@
 
  * Update working tree in pull. (Jelmer Vernooij, #452)
 
+ * Use ``dissolve`` to manage deprecations. (Jelmer Vernooij)
+
 0.22.8	2025-03-02
 
  * Allow passing in plain strings to ``dulwich.porcelain.tag_create``

+ 27 - 0
dulwich/__init__.py

@@ -24,3 +24,30 @@
 """Python implementation of the Git file formats and protocols."""
 
 __version__ = (0, 22, 9)
+
+__all__ = ["replace_me"]
+
+try:
+    from dissolve import replace_me
+except ModuleNotFoundError:
+    # if dissolve is not installed, then just provide a basic implementation
+    # of its replace_me decorator
+    def replace_me(since=None):
+        def decorator(func):
+            import warnings
+
+            if since is not None:
+                warnings.warn(
+                    f"{func.__name__} is deprecated since {since}; use 'dissolve migrate' to update your code",
+                    DeprecationWarning,
+                    stacklevel=2,
+                )
+            else:
+                warnings.warn(
+                    f"{func.__name__} is deprecated; use 'dissolve migrate' to update your code",
+                    DeprecationWarning,
+                    stacklevel=2,
+                )
+            return func
+
+        return decorator

+ 3 - 7
dulwich/objects.py

@@ -26,7 +26,6 @@ import binascii
 import os
 import posixpath
 import stat
-import warnings
 import zlib
 from collections import namedtuple
 from collections.abc import Callable, Iterable, Iterator
@@ -39,6 +38,7 @@ from typing import (
     Union,
 )
 
+from . import replace_me
 from .errors import (
     ChecksumMismatch,
     FileFormatException,
@@ -1320,6 +1320,7 @@ def format_time_entry(person, time, timezone_info):
     )
 
 
+@replace_me(since="0.21.0")
 def parse_commit(chunks):
     """Parse a commit object from chunks.
 
@@ -1328,7 +1329,6 @@ def parse_commit(chunks):
     Returns: Tuple of (tree, parents, author_info, commit_info,
         encoding, mergetag, gpgsig, message, extra)
     """
-    warnings.warn("parse_commit will be removed in 0.22", DeprecationWarning)
     parents = []
     extra = []
     tree = None
@@ -1616,13 +1616,9 @@ class Commit(ShaFile):
         doc="Parents of this commit, by their SHA1.",
     )
 
+    @replace_me(since="0.21.0")
     def _get_extra(self):
         """Return extra settings of this commit."""
-        warnings.warn(
-            "Commit.extra is deprecated. Use Commit._extra instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
         return self._extra
 
     extra = property(

+ 2 - 3
dulwich/pack.py

@@ -74,6 +74,7 @@ else:
 if sys.platform == "Plan9":
     has_mmap = False
 
+from . import replace_me
 from .errors import ApplyDeltaError, ChecksumMismatch
 from .file import GitFile
 from .lru_cache import LRUSizeCache
@@ -484,10 +485,8 @@ class PackIndex:
         """
         raise NotImplementedError(self.get_pack_checksum)
 
+    @replace_me(since="0.21.0")
     def object_index(self, sha: bytes) -> int:
-        warnings.warn(
-            "Please use object_offset instead", DeprecationWarning, stacklevel=2
-        )
         return self.object_offset(sha)
 
     def object_offset(self, sha: bytes) -> int:

+ 3 - 8
dulwich/porcelain.py

@@ -82,6 +82,7 @@ from io import BytesIO, RawIOBase
 from pathlib import Path
 from typing import Optional, Union
 
+from . import replace_me
 from .archive import tar_stream
 from .client import get_transport_and_path
 from .config import Config, ConfigFile, StackedConfig, read_submodules
@@ -2209,6 +2210,7 @@ def reset_file(repo, file_path: str, target: bytes = b"HEAD", symlink_fn=None) -
     build_file_from_blob(blob, mode, full_path, symlink_fn=symlink_fn)
 
 
+@replace_me(since="0.22.9")
 def checkout_branch(repo, target: Union[bytes, str], force: bool = False) -> None:
     """Switch branches or restore working tree files.
 
@@ -2220,15 +2222,8 @@ def checkout_branch(repo, target: Union[bytes, str], force: bool = False) -> Non
       target: branch name or commit sha to checkout
       force: true or not to force checkout
     """
-    import warnings
-
-    warnings.warn(
-        "checkout_branch is deprecated, use checkout instead.",
-        DeprecationWarning,
-        stacklevel=2,
-    )
     # Simply delegate to the new checkout function
-    checkout(repo, target, force=force)
+    return checkout(repo, target, force=force)
 
 
 def sparse_checkout(

+ 2 - 1
pyproject.toml

@@ -42,7 +42,8 @@ pgp = ["gpg"]
 paramiko = ["paramiko"]
 dev = [
     "ruff==0.11.11",
-    "mypy==1.15.0"
+    "mypy==1.15.0",
+    "dissolve"
 ]
 merge = ["merge3"]