Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

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

Sign up
Appearance settings

Commit04eb09c

Browse files
committed
Have USE_SHELL warn but work like normal via super()
This reimplements Git.USE_SHELL with no properties or descriptors.The metaclass is still needed, but instad of defining properties itdefines __getattribute__ and __setattr__, which check for USE_SHELLand warn, then invoke the default attribute access via super().Likewise, in the Git class itself, a __getatttribute__ override isintroduced (not to be confused with __getattr__, which was alreadypresent and handles attribute access when an attribute is otherwiseabsent, unlike __getattribute__ which is always used). This checksfor reading USE_SHELL on an instance and warns, then invokes thedefault attribute access via super().Advantages:- Git.USE_SHELL is again unittest.mock.patch patchable.- AttributeError messages are automatically as before.- It effectively is a simple attribute, yet with warning, so other unanticipated ways of accessing it may be less likely to break.- The code is simpler, cleaner, and clearer. There is some overhead, but it is small, especially compared to a subprocess invocation as is done for performing most git operations.However, this does introduce disadvantages that must be addressed:- Although attribute access on Git instances was already highly dynamic, as "methods" are synthesized for git subcommands, this was and is not the case for the Git class itself, whose attributes remain exactly those that can be inferred without considering the existence of __getattribute__ and __setattr__ on the metaclass. So static type checkers need to be prevented from accounting for those metaclass methods in a way that causes them to infer that arbitrary class attribute access is allowed.- The occurrence of Git.USE_SHELL in the Git.execute method (where the USE_SHELL attribute is actually examined) should be changed so it does not itself issue DeprecationWarning (it is not enough that by default a DeprecationWarning from there isn't displayed).
1 parent05de5c0 commit04eb09c

File tree

1 file changed

+15
-18
lines changed

1 file changed

+15
-18
lines changed

‎git/cmd.py

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
TYPE_CHECKING,
5656
TextIO,
5757
Tuple,
58-
Type,
5958
Union,
6059
cast,
6160
overload,
@@ -336,15 +335,15 @@ class _GitMeta(type):
336335
This helps issue :class:`DeprecationWarning` if :attr:`Git.USE_SHELL` is used.
337336
"""
338337

339-
@property
340-
defUSE_SHELL(cls:Type[Git])->bool:
341-
_warn_use_shell(False)
342-
returncls._USE_SHELL
338+
def__getattribute__(cls,name:str)->Any:
339+
ifname=="USE_SHELL":
340+
_warn_use_shell(False)
341+
returnsuper().__getattribute__(name)
343342

344-
@USE_SHELL.setter
345-
defUSE_SHELL(cls:Type[Git],value:bool)->None:
346-
_warn_use_shell(value)
347-
cls._USE_SHELL=value
343+
def__setattr__(cls,name:str,value:Any)->Any:
344+
ifname=="USE_SHELL":
345+
_warn_use_shell(value)
346+
super().__setattr__(name,value)
348347

349348

350349
classGit(metaclass=_GitMeta):
@@ -397,9 +396,7 @@ def __setstate__(self, d: Dict[str, Any]) -> None:
397396
GIT_PYTHON_TRACE=os.environ.get("GIT_PYTHON_TRACE",False)
398397
"""Enables debugging of GitPython's git commands."""
399398

400-
_USE_SHELL:bool=False
401-
402-
USE_SHELL:bool
399+
USE_SHELL:bool=False
403400
"""Deprecated. If set to ``True``, a shell will be used to execute git commands.
404401
405402
Prior to GitPython 2.0.8, this had a narrow purpose in suppressing console windows
@@ -909,6 +906,11 @@ def __init__(self, working_dir: Union[None, PathLike] = None) -> None:
909906
self.cat_file_header:Union[None,TBD]=None
910907
self.cat_file_all:Union[None,TBD]=None
911908

909+
def__getattribute__(self,name:str)->Any:
910+
ifname=="USE_SHELL":
911+
_warn_use_shell(False)
912+
returnsuper().__getattribute__(name)
913+
912914
def__getattr__(self,name:str)->Any:
913915
"""A convenience method as it allows to call the command as if it was an object.
914916
@@ -918,11 +920,6 @@ def __getattr__(self, name: str) -> Any:
918920
"""
919921
ifname.startswith("_"):
920922
returnsuper().__getattribute__(name)
921-
922-
ifname=="USE_SHELL":
923-
_warn_use_shell(False)
924-
returnself._USE_SHELL
925-
926923
returnlambda*args,**kwargs:self._call_process(name,*args,**kwargs)
927924

928925
defset_persistent_git_options(self,**kwargs:Any)->None:
@@ -1184,7 +1181,7 @@ def execute(
11841181

11851182
stdout_sink=PIPEifwith_stdoutelsegetattr(subprocess,"DEVNULL",None)oropen(os.devnull,"wb")
11861183
ifshellisNone:
1187-
shell=self._USE_SHELL
1184+
shell=self.USE_SHELL
11881185
_logger.debug(
11891186
"Popen(%s, cwd=%s, stdin=%s, shell=%s, universal_newlines=%s)",
11901187
redacted_command,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp