Skip to content

Commit

Permalink
Merge pull request #1298 from Yobmod/main
Browse files Browse the repository at this point in the history
Revert use of Typeguard and therefore typing-extensions==3.10.0.0
  • Loading branch information
Byron authored Jul 25, 2021
2 parents 0c1446d + be7bb86 commit c5e6ae2
Show file tree
Hide file tree
Showing 15 changed files with 140 additions and 149 deletions.
2 changes: 1 addition & 1 deletion .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ignore = E265,E266,E731,E704,
W293, W504,
ANN0 ANN1 ANN2,
TC002,
# TC0, TC1, TC2
TC0, TC1, TC2
# B,
A,
D,
Expand Down
69 changes: 36 additions & 33 deletions git/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""Module containing module parser implementation able to properly read and write
configuration files"""

import sys
import abc
from functools import wraps
import inspect
Expand All @@ -14,12 +15,10 @@
import os
import re
import fnmatch
from collections import OrderedDict

from git.compat import (
defenc,
force_text,
with_metaclass,
is_win,
)

Expand All @@ -31,15 +30,24 @@

# typing-------------------------------------------------------

from typing import (Any, Callable, IO, List, Dict, Sequence,
TYPE_CHECKING, Tuple, Union, cast, overload)
from typing import (Any, Callable, Generic, IO, List, Dict, Sequence,
TYPE_CHECKING, Tuple, TypeVar, Union, cast, overload)

from git.types import Lit_config_levels, ConfigLevels_Tup, PathLike, TBD, assert_never, is_config_level
from git.types import Lit_config_levels, ConfigLevels_Tup, PathLike, TBD, assert_never, _T

if TYPE_CHECKING:
from git.repo.base import Repo
from io import BytesIO

T_ConfigParser = TypeVar('T_ConfigParser', bound='GitConfigParser')

if sys.version_info[:2] < (3, 7):
from collections import OrderedDict
OrderedDict_OMD = OrderedDict
else:
from typing import OrderedDict
OrderedDict_OMD = OrderedDict[str, List[_T]]

# -------------------------------------------------------------

__all__ = ('GitConfigParser', 'SectionConstraint')
Expand All @@ -61,7 +69,6 @@


class MetaParserBuilder(abc.ABCMeta):

"""Utlity class wrapping base-class methods into decorators that assure read-only properties"""
def __new__(cls, name: str, bases: TBD, clsdict: Dict[str, Any]) -> TBD:
"""
Expand Down Expand Up @@ -115,7 +122,7 @@ def flush_changes(self, *args: Any, **kwargs: Any) -> Any:
return flush_changes


class SectionConstraint(object):
class SectionConstraint(Generic[T_ConfigParser]):

"""Constrains a ConfigParser to only option commands which are constrained to
always use the section we have been initialized with.
Expand All @@ -128,7 +135,7 @@ class SectionConstraint(object):
_valid_attrs_ = ("get_value", "set_value", "get", "set", "getint", "getfloat", "getboolean", "has_option",
"remove_section", "remove_option", "options")

def __init__(self, config: 'GitConfigParser', section: str) -> None:
def __init__(self, config: T_ConfigParser, section: str) -> None:
self._config = config
self._section_name = section

Expand All @@ -149,26 +156,26 @@ def _call_config(self, method: str, *args: Any, **kwargs: Any) -> Any:
return getattr(self._config, method)(self._section_name, *args, **kwargs)

@property
def config(self) -> 'GitConfigParser':
def config(self) -> T_ConfigParser:
"""return: Configparser instance we constrain"""
return self._config

def release(self) -> None:
"""Equivalent to GitConfigParser.release(), which is called on our underlying parser instance"""
return self._config.release()

def __enter__(self) -> 'SectionConstraint':
def __enter__(self) -> 'SectionConstraint[T_ConfigParser]':
self._config.__enter__()
return self

def __exit__(self, exception_type: str, exception_value: str, traceback: str) -> None:
self._config.__exit__(exception_type, exception_value, traceback)


class _OMD(OrderedDict):
class _OMD(OrderedDict_OMD):
"""Ordered multi-dict."""

def __setitem__(self, key: str, value: Any) -> None:
def __setitem__(self, key: str, value: _T) -> None: # type: ignore[override]
super(_OMD, self).__setitem__(key, [value])

def add(self, key: str, value: Any) -> None:
Expand All @@ -177,7 +184,7 @@ def add(self, key: str, value: Any) -> None:
return None
super(_OMD, self).__getitem__(key).append(value)

def setall(self, key: str, values: Any) -> None:
def setall(self, key: str, values: List[_T]) -> None:
super(_OMD, self).__setitem__(key, values)

def __getitem__(self, key: str) -> Any:
Expand All @@ -194,25 +201,17 @@ def setlast(self, key: str, value: Any) -> None:
prior = super(_OMD, self).__getitem__(key)
prior[-1] = value

@overload
def get(self, key: str, default: None = ...) -> None:
...

@overload
def get(self, key: str, default: Any = ...) -> Any:
...

def get(self, key: str, default: Union[Any, None] = None) -> Union[Any, None]:
return super(_OMD, self).get(key, [default])[-1]
def get(self, key: str, default: Union[_T, None] = None) -> Union[_T, None]: # type: ignore
return super(_OMD, self).get(key, [default])[-1] # type: ignore

def getall(self, key: str) -> Any:
def getall(self, key: str) -> List[_T]:
return super(_OMD, self).__getitem__(key)

def items(self) -> List[Tuple[str, Any]]: # type: ignore[override]
def items(self) -> List[Tuple[str, _T]]: # type: ignore[override]
"""List of (key, last value for key)."""
return [(k, self[k]) for k in self]

def items_all(self) -> List[Tuple[str, List[Any]]]:
def items_all(self) -> List[Tuple[str, List[_T]]]:
"""List of (key, list of values for key)."""
return [(k, self.getall(k)) for k in self]

Expand All @@ -238,7 +237,7 @@ def get_config_path(config_level: Lit_config_levels) -> str:
assert_never(config_level, ValueError(f"Invalid configuration level: {config_level!r}"))


class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser)): # type: ignore ## mypy does not understand dynamic class creation # noqa: E501
class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):

"""Implements specifics required to read git style configuration files.
Expand Down Expand Up @@ -298,7 +297,10 @@ def __init__(self, file_or_files: Union[None, PathLike, 'BytesIO', Sequence[Unio
:param repo: Reference to repository to use if [includeIf] sections are found in configuration files.
"""
cp.RawConfigParser.__init__(self, dict_type=_OMD)
cp.RawConfigParser.__init__(self, dict_type=_OMD) # type: ignore[arg-type]
self._dict: Callable[..., _OMD] # type: ignore[assignment] # mypy/typeshed bug
self._defaults: _OMD # type: ignore[assignment] # mypy/typeshed bug
self._sections: _OMD # type: ignore[assignment] # mypy/typeshed bug

# Used in python 3, needs to stay in sync with sections for underlying implementation to work
if not hasattr(self, '_proxies'):
Expand All @@ -309,9 +311,9 @@ def __init__(self, file_or_files: Union[None, PathLike, 'BytesIO', Sequence[Unio
else:
if config_level is None:
if read_only:
self._file_or_files = [get_config_path(f)
self._file_or_files = [get_config_path(cast(Lit_config_levels, f))
for f in CONFIG_LEVELS
if is_config_level(f) and f != 'repository']
if f != 'repository']
else:
raise ValueError("No configuration level or configuration files specified")
else:
Expand Down Expand Up @@ -424,7 +426,7 @@ def string_decode(v: str) -> str:
# is it a section header?
mo = self.SECTCRE.match(line.strip())
if not is_multi_line and mo:
sectname = mo.group('header').strip()
sectname: str = mo.group('header').strip()
if sectname in self._sections:
cursect = self._sections[sectname]
elif sectname == cp.DEFAULTSECT:
Expand Down Expand Up @@ -535,7 +537,7 @@ def _included_paths(self) -> List[Tuple[str, str]]:

return paths

def read(self) -> None:
def read(self) -> None: # type: ignore[override]
"""Reads the data stored in the files we have been initialized with. It will
ignore files that cannot be read, possibly leaving an empty configuration
Expand Down Expand Up @@ -623,10 +625,11 @@ def write_section(name, section_dict):

if self._defaults:
write_section(cp.DEFAULTSECT, self._defaults)
value: TBD
for name, value in self._sections.items():
write_section(name, value)

def items(self, section_name: str) -> List[Tuple[str, str]]:
def items(self, section_name: str) -> List[Tuple[str, str]]: # type: ignore[override]
""":return: list((option, value), ...) pairs of all items in the given section"""
return [(k, v) for k, v in super(GitConfigParser, self).items(section_name) if k != '__name__']

Expand Down
14 changes: 7 additions & 7 deletions git/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

# typing ------------------------------------------------------------------

from typing import Any, Iterator, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING
from git.types import PathLike, TBD, Literal, TypeGuard
from typing import Any, Iterator, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING, cast
from git.types import PathLike, TBD, Literal

if TYPE_CHECKING:
from .objects.tree import Tree
Expand All @@ -28,9 +28,9 @@
Lit_change_type = Literal['A', 'D', 'C', 'M', 'R', 'T', 'U']


def is_change_type(inp: str) -> TypeGuard[Lit_change_type]:
# return True
return inp in ['A', 'D', 'C', 'M', 'R', 'T', 'U']
# def is_change_type(inp: str) -> TypeGuard[Lit_change_type]:
# # return True
# return inp in ['A', 'D', 'C', 'M', 'R', 'T', 'U']

# ------------------------------------------------------------------------

Expand Down Expand Up @@ -517,8 +517,8 @@ def _handle_diff_line(lines_bytes: bytes, repo: 'Repo', index: DiffIndex) -> Non
# Change type can be R100
# R: status letter
# 100: score (in case of copy and rename)
assert is_change_type(_change_type[0]), f"Unexpected value for change_type received: {_change_type[0]}"
change_type: Lit_change_type = _change_type[0]
# assert is_change_type(_change_type[0]), f"Unexpected value for change_type received: {_change_type[0]}"
change_type: Lit_change_type = cast(Lit_change_type, _change_type[0])
score_str = ''.join(_change_type[1:])
score = int(score_str) if score_str.isdigit() else None
path = path.strip()
Expand Down
28 changes: 15 additions & 13 deletions git/index/fun.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@

from typing import (Dict, IO, List, Sequence, TYPE_CHECKING, Tuple, Type, Union, cast)

from git.types import PathLike, TypeGuard
from git.types import PathLike

if TYPE_CHECKING:
from .base import IndexFile
from git.db import GitCmdObjectDB
from git.objects.tree import TreeCacheTup
# from git.objects.fun import EntryTupOrNone

Expand Down Expand Up @@ -149,15 +150,15 @@ def write_cache(entries: Sequence[Union[BaseIndexEntry, 'IndexEntry']], stream:
# body
for entry in entries:
beginoffset = tell()
write(entry[4]) # ctime
write(entry[5]) # mtime
path_str: str = entry[3]
write(entry.ctime_bytes) # ctime
write(entry.mtime_bytes) # mtime
path_str = str(entry.path)
path: bytes = force_bytes(path_str, encoding=defenc)
plen = len(path) & CE_NAMEMASK # path length
assert plen == len(path), "Path %s too long to fit into index" % entry[3]
flags = plen | (entry[2] & CE_NAMEMASK_INV) # clear possible previous values
write(pack(">LLLLLL20sH", entry[6], entry[7], entry[0],
entry[8], entry[9], entry[10], entry[1], flags))
assert plen == len(path), "Path %s too long to fit into index" % entry.path
flags = plen | (entry.flags & CE_NAMEMASK_INV) # clear possible previous values
write(pack(">LLLLLL20sH", entry.dev, entry.inode, entry.mode,
entry.uid, entry.gid, entry.size, entry.binsha, flags))
write(path)
real_size = ((tell() - beginoffset + 8) & ~7)
write(b"\0" * ((beginoffset + real_size) - tell()))
Expand Down Expand Up @@ -188,15 +189,16 @@ def entry_key(*entry: Union[BaseIndexEntry, PathLike, int]) -> Tuple[PathLike, i
""":return: Key suitable to be used for the index.entries dictionary
:param entry: One instance of type BaseIndexEntry or the path and the stage"""

def is_entry_key_tup(entry_key: Tuple) -> TypeGuard[Tuple[PathLike, int]]:
return isinstance(entry_key, tuple) and len(entry_key) == 2
# def is_entry_key_tup(entry_key: Tuple) -> TypeGuard[Tuple[PathLike, int]]:
# return isinstance(entry_key, tuple) and len(entry_key) == 2

if len(entry) == 1:
entry_first = entry[0]
assert isinstance(entry_first, BaseIndexEntry)
return (entry_first.path, entry_first.stage)
else:
assert is_entry_key_tup(entry)
# assert is_entry_key_tup(entry)
entry = cast(Tuple[PathLike, int], entry)
return entry
# END handle entry

Expand Down Expand Up @@ -244,7 +246,7 @@ def read_cache(stream: IO[bytes]) -> Tuple[int, Dict[Tuple[PathLike, int], 'Inde
content_sha = extension_data[-20:]

# truncate the sha in the end as we will dynamically create it anyway
extension_data = extension_data[:-20]
extension_data = extension_data[: -20]

return (version, entries, extension_data, content_sha)

Expand Down Expand Up @@ -310,7 +312,7 @@ def _tree_entry_to_baseindexentry(tree_entry: 'TreeCacheTup', stage: int) -> Bas
return BaseIndexEntry((tree_entry[1], tree_entry[0], stage << CE_STAGESHIFT, tree_entry[2]))


def aggressive_tree_merge(odb, tree_shas: Sequence[bytes]) -> List[BaseIndexEntry]:
def aggressive_tree_merge(odb: 'GitCmdObjectDB', tree_shas: Sequence[bytes]) -> List[BaseIndexEntry]:
"""
:return: list of BaseIndexEntries representing the aggressive merge of the given
trees. All valid entries are on stage 0, whereas the conflicting ones are left
Expand Down
Loading

0 comments on commit c5e6ae2

Please sign in to comment.