Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 597e1a6

Browse filesBrowse files
authored
Merge pull request #1787 from EliahKagan/deprecation
Deprecate Git.USE_SHELL
2 parents 86d0177 + 3af3d43 commit 597e1a6
Copy full SHA for 597e1a6

File tree

6 files changed

+114
-70
lines changed
Filter options

6 files changed

+114
-70
lines changed

‎git/cmd.py

Copy file name to clipboardExpand all lines: git/cmd.py
+15-7Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -280,20 +280,20 @@ def __setstate__(self, d: Dict[str, Any]) -> None:
280280
"""Enables debugging of GitPython's git commands."""
281281

282282
USE_SHELL = False
283-
"""If True, a shell will be used when executing git commands.
283+
"""Deprecated. If set to True, a shell will be used when executing git commands.
284284
285-
This exists to avoid breaking old code that may access it, but it is no longer
286-
needed and should rarely if ever be used. Prior to GitPython 2.0.8, it had a narrow
287-
purpose in suppressing console windows in graphical Windows applications. In 2.0.8
288-
and higher, it provides no benefit, as GitPython solves that problem more robustly
289-
and safely by using the ``CREATE_NO_WINDOW`` process creation flag on Windows.
285+
Prior to GitPython 2.0.8, this had a narrow purpose in suppressing console windows
286+
in graphical Windows applications. In 2.0.8 and higher, it provides no benefit, as
287+
GitPython solves that problem more robustly and safely by using the
288+
``CREATE_NO_WINDOW`` process creation flag on Windows.
290289
291290
Code that uses ``USE_SHELL = True`` or that passes ``shell=True`` to any GitPython
292291
functions should be updated to use the default value of ``False`` instead. ``True``
293292
is unsafe unless the effect of shell expansions is fully considered and accounted
294293
for, which is not possible under most circumstances.
295294
296295
See:
296+
- :meth:`Git.execute` (on the ``shell`` parameter).
297297
- https://github.com/gitpython-developers/GitPython/commit/0d9390866f9ce42870d3116094cd49e0019a970a
298298
- https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags
299299
"""
@@ -919,7 +919,15 @@ def execute(
919919
920920
:param shell:
921921
Whether to invoke commands through a shell (see `Popen(..., shell=True)`).
922-
It overrides :attr:`USE_SHELL` if it is not `None`.
922+
If this is not `None`, it overrides :attr:`USE_SHELL`.
923+
924+
Passing ``shell=True`` to this or any other GitPython function should be
925+
avoided, as it is unsafe under most circumstances. This is because it is
926+
typically not feasible to fully consider and account for the effect of shell
927+
expansions, especially when passing ``shell=True`` to other methods that
928+
forward it to :meth:`Git.execute`. Passing ``shell=True`` is also no longer
929+
needed (nor useful) to work around any known operating system specific
930+
issues.
923931
924932
:param env:
925933
A dictionary of environment variables to be passed to :class:`subprocess.Popen`.

‎git/compat.py

Copy file name to clipboardExpand all lines: git/compat.py
+30-7Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,41 @@
2828
# ---------------------------------------------------------------------------
2929

3030

31-
# DEPRECATED attributes providing shortcuts to operating system checks based on os.name.
32-
#
33-
# These are deprecated because it is clearer, and helps avoid bugs, to write out the
34-
# os.name or sys.platform checks explicitly, especially in cases where it matters which
35-
# is used. For example, is_win is False on Cygwin, but is often assumed True. To detect
36-
# Cygwin, use sys.platform == "cygwin". (Also, in the past, is_darwin was unreliable.)
37-
#
3831
is_win = os.name == "nt"
32+
"""Deprecated alias for ``os.name == "nt"`` to check for native Windows.
33+
34+
This is deprecated because it is clearer to write out :attr:`os.name` or
35+
:attr:`sys.platform` checks explicitly, especially in cases where it matters which is
36+
used.
37+
38+
:note: ``is_win`` is ``False`` on Cygwin, but is often wrongly assumed ``True``. To
39+
detect Cygwin, use ``sys.platform == "cygwin"``.
40+
"""
41+
3942
is_posix = os.name == "posix"
43+
"""Deprecated alias for ``os.name == "posix"`` to check for Unix-like ("POSIX") systems.
44+
45+
This is deprecated because it clearer to write out :attr:`os.name` or
46+
:attr:`sys.platform` checks explicitly, especially in cases where it matters which is
47+
used.
48+
49+
:note: For POSIX systems, more detailed information is available in
50+
:attr:`sys.platform`, while :attr:`os.name` is always ``"posix"`` on such systems,
51+
including macOS (Darwin).
52+
"""
53+
4054
is_darwin = sys.platform == "darwin"
55+
"""Deprecated alias for ``sys.platform == "darwin"`` to check for macOS (Darwin).
56+
57+
This is deprecated because it clearer to write out :attr:`os.name` or
58+
:attr:`sys.platform` checks explicitly.
59+
60+
:note: For macOS (Darwin), ``os.name == "posix"`` as in other Unix-like systems, while
61+
``sys.platform == "darwin"`.
62+
"""
4163

4264
defenc = sys.getfilesystemencoding()
65+
"""The encoding used to convert between Unicode and bytes filenames."""
4366

4467

4568
@overload

‎git/diff.py

Copy file name to clipboardExpand all lines: git/diff.py
+9-6Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/
55

66
import re
7+
78
from git.cmd import handle_process_output
89
from git.compat import defenc
910
from git.util import finalize_process, hex_to_bin
@@ -208,13 +209,15 @@ class DiffIndex(List[T_Diff]):
208209
The class improves the diff handling convenience.
209210
"""
210211

211-
# Change type invariant identifying possible ways a blob can have changed:
212-
# A = Added
213-
# D = Deleted
214-
# R = Renamed
215-
# M = Modified
216-
# T = Changed in the type
217212
change_type = ("A", "C", "D", "R", "M", "T")
213+
"""Change type invariant identifying possible ways a blob can have changed:
214+
215+
* ``A`` = Added
216+
* ``D`` = Deleted
217+
* ``R`` = Renamed
218+
* ``M`` = Modified
219+
* ``T`` = Changed in the type
220+
"""
218221

219222
def iter_change_type(self, change_type: Lit_change_type) -> Iterator[T_Diff]:
220223
"""

‎git/objects/commit.py

Copy file name to clipboardExpand all lines: git/objects/commit.py
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,8 @@ def stats(self) -> Stats:
352352
def trailers(self) -> Dict[str, str]:
353353
"""Get the trailers of the message as a dictionary
354354
355-
:note: This property is deprecated, please use either ``Commit.trailers_list``
356-
or ``Commit.trailers_dict``.
355+
:note: This property is deprecated, please use either :attr:`trailers_list` or
356+
:attr:`trailers_dict``.
357357
358358
:return:
359359
Dictionary containing whitespace stripped trailer information. Only contains

‎git/objects/util.py

Copy file name to clipboardExpand all lines: git/objects/util.py
+54-44Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ class TraverseNT(NamedTuple):
6262
T_TIobj = TypeVar("T_TIobj", bound="TraversableIterableObj") # For TraversableIterableObj.traverse()
6363

6464
TraversedTup = Union[
65-
Tuple[Union["Traversable", None], "Traversable"], # For commit, submodule
66-
"TraversedTreeTup",
67-
] # for tree.traverse()
65+
Tuple[Union["Traversable", None], "Traversable"], # For Commit, Submodule.
66+
"TraversedTreeTup", # For Tree.traverse().
67+
]
6868

6969
# --------------------------------------------------------------------
7070

@@ -380,11 +380,15 @@ class Tree:: (cls, Tree) -> Tuple[Tree, ...]
380380

381381
@abstractmethod
382382
def list_traverse(self, *args: Any, **kwargs: Any) -> Any:
383-
""" """
383+
"""Traverse self and collect all items found.
384+
385+
Calling this directly only the abstract base class, including via a ``super()``
386+
proxy, is deprecated. Only overridden implementations should be called.
387+
"""
384388
warnings.warn(
385389
"list_traverse() method should only be called from subclasses."
386-
"Calling from Traversable abstract class will raise NotImplementedError in 3.1.20"
387-
"Builtin sublclasses are 'Submodule', 'Tree' and 'Commit",
390+
" Calling from Traversable abstract class will raise NotImplementedError in 4.0.0."
391+
" The concrete subclasses in GitPython itself are 'Commit', 'RootModule', 'Submodule', and 'Tree'.",
388392
DeprecationWarning,
389393
stacklevel=2,
390394
)
@@ -393,12 +397,14 @@ def list_traverse(self, *args: Any, **kwargs: Any) -> Any:
393397
def _list_traverse(
394398
self, as_edge: bool = False, *args: Any, **kwargs: Any
395399
) -> IterableList[Union["Commit", "Submodule", "Tree", "Blob"]]:
396-
"""
400+
"""Traverse self and collect all items found.
401+
397402
:return: IterableList with the results of the traversal as produced by
398-
traverse()
399-
Commit -> IterableList['Commit']
400-
Submodule -> IterableList['Submodule']
401-
Tree -> IterableList[Union['Submodule', 'Tree', 'Blob']]
403+
:meth:`traverse`::
404+
405+
Commit -> IterableList['Commit']
406+
Submodule -> IterableList['Submodule']
407+
Tree -> IterableList[Union['Submodule', 'Tree', 'Blob']]
402408
"""
403409
# Commit and Submodule have id.__attribute__ as IterableObj.
404410
# Tree has id.__attribute__ inherited from IndexObject.
@@ -421,11 +427,15 @@ def _list_traverse(
421427

422428
@abstractmethod
423429
def traverse(self, *args: Any, **kwargs: Any) -> Any:
424-
""" """
430+
"""Iterator yielding items found when traversing self.
431+
432+
Calling this directly on the abstract base class, including via a ``super()``
433+
proxy, is deprecated. Only overridden implementations should be called.
434+
"""
425435
warnings.warn(
426436
"traverse() method should only be called from subclasses."
427-
"Calling from Traversable abstract class will raise NotImplementedError in 3.1.20"
428-
"Builtin sublclasses are 'Submodule', 'Tree' and 'Commit",
437+
" Calling from Traversable abstract class will raise NotImplementedError in 4.0.0."
438+
" The concrete subclasses in GitPython itself are 'Commit', 'RootModule', 'Submodule', and 'Tree'.",
429439
DeprecationWarning,
430440
stacklevel=2,
431441
)
@@ -441,7 +451,7 @@ def _traverse(
441451
ignore_self: int = 1,
442452
as_edge: bool = False,
443453
) -> Union[Iterator[Union["Traversable", "Blob"]], Iterator[TraversedTup]]:
444-
""":return: Iterator yielding items found when traversing self
454+
"""Iterator yielding items found when traversing self.
445455
446456
:param predicate: f(i,d) returns False if item i at depth d should not be
447457
included in the result.
@@ -471,18 +481,18 @@ def _traverse(
471481
if True, return a pair of items, first being the source, second the
472482
destination, i.e. tuple(src, dest) with the edge spanning from source to
473483
destination
474-
"""
475484
476-
"""
477-
Commit -> Iterator[Union[Commit, Tuple[Commit, Commit]]
478-
Submodule -> Iterator[Submodule, Tuple[Submodule, Submodule]]
479-
Tree -> Iterator[Union[Blob, Tree, Submodule,
480-
Tuple[Union[Submodule, Tree], Union[Blob, Tree, Submodule]]]
481-
482-
ignore_self=True is_edge=True -> Iterator[item]
483-
ignore_self=True is_edge=False --> Iterator[item]
484-
ignore_self=False is_edge=True -> Iterator[item] | Iterator[Tuple[src, item]]
485-
ignore_self=False is_edge=False -> Iterator[Tuple[src, item]]
485+
:return: Iterator yielding items found when traversing self::
486+
487+
Commit -> Iterator[Union[Commit, Tuple[Commit, Commit]]
488+
Submodule -> Iterator[Submodule, Tuple[Submodule, Submodule]]
489+
Tree -> Iterator[Union[Blob, Tree, Submodule,
490+
Tuple[Union[Submodule, Tree], Union[Blob, Tree, Submodule]]]
491+
492+
ignore_self=True is_edge=True -> Iterator[item]
493+
ignore_self=True is_edge=False --> Iterator[item]
494+
ignore_self=False is_edge=True -> Iterator[item] | Iterator[Tuple[src, item]]
495+
ignore_self=False is_edge=False -> Iterator[Tuple[src, item]]
486496
"""
487497

488498
visited = set()
@@ -547,7 +557,7 @@ class Serializable(Protocol):
547557
def _serialize(self, stream: "BytesIO") -> "Serializable":
548558
"""Serialize the data of this object into the given data stream.
549559
550-
:note: A serialized object would ``_deserialize`` into the same object.
560+
:note: A serialized object would :meth:`_deserialize` into the same object.
551561
552562
:param stream: a file-like object
553563
@@ -627,24 +637,24 @@ def traverse(
627637
ignore_self: int = 1,
628638
as_edge: bool = False,
629639
) -> Union[Iterator[T_TIobj], Iterator[Tuple[T_TIobj, T_TIobj]], Iterator[TIobj_tuple]]:
630-
"""For documentation, see util.Traversable._traverse()"""
640+
"""For documentation, see :meth:`Traversable._traverse`."""
641+
642+
## To typecheck instead of using cast:
643+
#
644+
# import itertools
645+
# from git.types import TypeGuard
646+
# def is_commit_traversed(inp: Tuple) -> TypeGuard[Tuple[Iterator[Tuple['Commit', 'Commit']]]]:
647+
# for x in inp[1]:
648+
# if not isinstance(x, tuple) and len(x) != 2:
649+
# if all(isinstance(inner, Commit) for inner in x):
650+
# continue
651+
# return True
652+
#
653+
# ret = super(Commit, self).traverse(predicate, prune, depth, branch_first, visit_once, ignore_self, as_edge)
654+
# ret_tup = itertools.tee(ret, 2)
655+
# assert is_commit_traversed(ret_tup), f"{[type(x) for x in list(ret_tup[0])]}"
656+
# return ret_tup[0]
631657

632-
"""
633-
# To typecheck instead of using cast.
634-
import itertools
635-
from git.types import TypeGuard
636-
def is_commit_traversed(inp: Tuple) -> TypeGuard[Tuple[Iterator[Tuple['Commit', 'Commit']]]]:
637-
for x in inp[1]:
638-
if not isinstance(x, tuple) and len(x) != 2:
639-
if all(isinstance(inner, Commit) for inner in x):
640-
continue
641-
return True
642-
643-
ret = super(Commit, self).traverse(predicate, prune, depth, branch_first, visit_once, ignore_self, as_edge)
644-
ret_tup = itertools.tee(ret, 2)
645-
assert is_commit_traversed(ret_tup), f"{[type(x) for x in list(ret_tup[0])]}"
646-
return ret_tup[0]
647-
"""
648658
return cast(
649659
Union[Iterator[T_TIobj], Iterator[Tuple[Union[None, T_TIobj], T_TIobj]]],
650660
super()._traverse(predicate, prune, depth, branch_first, visit_once, ignore_self, as_edge), # type: ignore

‎git/util.py

Copy file name to clipboardExpand all lines: git/util.py
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,10 +1233,10 @@ def __init__(cls, name: str, bases: Tuple, clsdict: Dict) -> None:
12331233
for base in bases:
12341234
if type(base) is IterableClassWatcher:
12351235
warnings.warn(
1236-
f"GitPython Iterable subclassed by {name}. "
1237-
"Iterable is deprecated due to naming clash since v3.1.18"
1238-
" and will be removed in 3.1.20, "
1239-
"Use IterableObj instead \n",
1236+
f"GitPython Iterable subclassed by {name}."
1237+
" Iterable is deprecated due to naming clash since v3.1.18"
1238+
" and will be removed in 4.0.0."
1239+
" Use IterableObj instead.",
12401240
DeprecationWarning,
12411241
stacklevel=2,
12421242
)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.