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

Commiteba6fce

Browse files
authored
Merge pull request#1838 from EliahKagan/refresh-version
Fix version_info cache invalidation, typing, parsing, and serialization
2 parentsafa5754 +629fd87 commiteba6fce

File tree

3 files changed

+244
-33
lines changed

3 files changed

+244
-33
lines changed

‎git/cmd.py

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
importre
99
importcontextlib
1010
importio
11+
importitertools
1112
importlogging
1213
importos
1314
importsignal
@@ -25,7 +26,6 @@
2526
UnsafeProtocolError,
2627
)
2728
fromgit.utilimport (
28-
LazyMixin,
2929
cygpath,
3030
expand_path,
3131
is_cygwin_git,
@@ -287,7 +287,7 @@ def dict_to_slots_and__excluded_are_none(self: object, d: Mapping[str, Any], exc
287287
## -- End Utilities -- @}
288288

289289

290-
classGit(LazyMixin):
290+
classGit:
291291
"""The Git class manages communication with the Git binary.
292292
293293
It provides a convenient interface to calling the Git binary, such as in::
@@ -307,12 +307,18 @@ class Git(LazyMixin):
307307
"cat_file_all",
308308
"cat_file_header",
309309
"_version_info",
310+
"_version_info_token",
310311
"_git_options",
311312
"_persistent_git_options",
312313
"_environment",
313314
)
314315

315-
_excluded_= ("cat_file_all","cat_file_header","_version_info")
316+
_excluded_= (
317+
"cat_file_all",
318+
"cat_file_header",
319+
"_version_info",
320+
"_version_info_token",
321+
)
316322

317323
re_unsafe_protocol=re.compile(r"(.+)::.+")
318324

@@ -359,6 +365,8 @@ def __setstate__(self, d: Dict[str, Any]) -> None:
359365
the top level ``__init__``.
360366
"""
361367

368+
_refresh_token=object()# Since None would match an initial _version_info_token.
369+
362370
@classmethod
363371
defrefresh(cls,path:Union[None,PathLike]=None)->bool:
364372
"""This gets called by the refresh function (see the top level __init__)."""
@@ -371,7 +379,9 @@ def refresh(cls, path: Union[None, PathLike] = None) -> bool:
371379

372380
# Keep track of the old and new git executable path.
373381
old_git=cls.GIT_PYTHON_GIT_EXECUTABLE
382+
old_refresh_token=cls._refresh_token
374383
cls.GIT_PYTHON_GIT_EXECUTABLE=new_git
384+
cls._refresh_token=object()
375385

376386
# Test if the new git executable path is valid. A GitCommandNotFound error is
377387
# spawned by us. A PermissionError is spawned if the git executable cannot be
@@ -400,6 +410,7 @@ def refresh(cls, path: Union[None, PathLike] = None) -> bool:
400410

401411
# Revert to whatever the old_git was.
402412
cls.GIT_PYTHON_GIT_EXECUTABLE=old_git
413+
cls._refresh_token=old_refresh_token
403414

404415
ifold_gitisNone:
405416
# On the first refresh (when GIT_PYTHON_GIT_EXECUTABLE is None) we only
@@ -783,6 +794,10 @@ def __init__(self, working_dir: Union[None, PathLike] = None):
783794
# Extra environment variables to pass to git commands
784795
self._environment:Dict[str,str]= {}
785796

797+
# Cached version slots
798+
self._version_info:Union[Tuple[int, ...],None]=None
799+
self._version_info_token:object=None
800+
786801
# Cached command slots
787802
self.cat_file_header:Union[None,TBD]=None
788803
self.cat_file_all:Union[None,TBD]=None
@@ -795,8 +810,8 @@ def __getattr__(self, name: str) -> Any:
795810
Callable object that will execute call :meth:`_call_process` with
796811
your arguments.
797812
"""
798-
ifname[0]=="_":
799-
returnLazyMixin.__getattr__(self,name)
813+
ifname.startswith("_"):
814+
returnsuper().__getattribute__(name)
800815
returnlambda*args,**kwargs:self._call_process(name,*args,**kwargs)
801816

802817
defset_persistent_git_options(self,**kwargs:Any)->None:
@@ -811,33 +826,36 @@ def set_persistent_git_options(self, **kwargs: Any) -> None:
811826

812827
self._persistent_git_options=self.transform_kwargs(split_single_char_options=True,**kwargs)
813828

814-
def_set_cache_(self,attr:str)->None:
815-
ifattr=="_version_info":
816-
# We only use the first 4 numbers, as everything else could be strings in fact (on Windows).
817-
process_version=self._call_process("version")# Should be as default *args and **kwargs used.
818-
version_numbers=process_version.split(" ")[2]
819-
820-
self._version_info=cast(
821-
Tuple[int,int,int,int],
822-
tuple(int(n)forninversion_numbers.split(".")[:4]ifn.isdigit()),
823-
)
824-
else:
825-
super()._set_cache_(attr)
826-
# END handle version info
827-
828829
@property
829830
defworking_dir(self)->Union[None,PathLike]:
830831
""":return: Git directory we are working on"""
831832
returnself._working_dir
832833

833834
@property
834-
defversion_info(self)->Tuple[int,int,int,int]:
835+
defversion_info(self)->Tuple[int,...]:
835836
"""
836-
:return:tuple(int, int, int, int)tuple with integers representing the major, minor
837-
and additionalversion numbers as parsed from git version.
837+
:return:tuple with integers representing the major, minor and additional
838+
version numbers as parsed from git version. Up to four fields are used.
838839
839840
This value is generated on demand and is cached.
840841
"""
842+
# Refreshing is global, but version_info caching is per-instance.
843+
refresh_token=self._refresh_token# Copy token in case of concurrent refresh.
844+
845+
# Use the cached version if obtained after the most recent refresh.
846+
ifself._version_info_tokenisrefresh_token:
847+
assertself._version_infoisnotNone,"Bug: corrupted token-check state"
848+
returnself._version_info
849+
850+
# Run "git version" and parse it.
851+
process_version=self._call_process("version")
852+
version_string=process_version.split(" ")[2]
853+
version_fields=version_string.split(".")[:4]
854+
leading_numeric_fields=itertools.takewhile(str.isdigit,version_fields)
855+
self._version_info=tuple(map(int,leading_numeric_fields))
856+
857+
# This value will be considered valid until the next refresh.
858+
self._version_info_token=refresh_token
841859
returnself._version_info
842860

843861
@overload

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp