From f8e223263c73a7516e2b216a546079e9a144b3a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Wed, 21 Apr 2021 10:03:11 +0200 Subject: Use typing-extensions only on Python < 3.8 All necessary attributes are available in the built-in typing module since Python 3.8. Use typing-extensions only for older versions of Python, and avoid the unnecessary dep in 3.8+. --- git/compat.py | 107 ------------------------------------------------- git/compat/__init__.py | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ git/compat/typing.py | 13 ++++++ git/config.py | 3 +- git/diff.py | 2 +- git/repo/base.py | 2 +- 6 files changed, 123 insertions(+), 111 deletions(-) delete mode 100644 git/compat.py create mode 100644 git/compat/__init__.py create mode 100644 git/compat/typing.py (limited to 'git') diff --git a/git/compat.py b/git/compat.py deleted file mode 100644 index c4bd2aa3..00000000 --- a/git/compat.py +++ /dev/null @@ -1,107 +0,0 @@ -# -*- coding: utf-8 -*- -# config.py -# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors -# -# This module is part of GitPython and is released under -# the BSD License: http://www.opensource.org/licenses/bsd-license.php -"""utilities to help provide compatibility with python 3""" -# flake8: noqa - -import locale -import os -import sys - -from gitdb.utils.encoding import ( - force_bytes, # @UnusedImport - force_text # @UnusedImport -) - -# typing -------------------------------------------------------------------- - -from typing import ( - Any, - AnyStr, - Dict, - IO, - Optional, - Type, - Union, - overload, -) -from git.types import TBD - -# --------------------------------------------------------------------------- - - -is_win = (os.name == 'nt') # type: bool -is_posix = (os.name == 'posix') -is_darwin = (os.name == 'darwin') -defenc = sys.getfilesystemencoding() - - -@overload -def safe_decode(s: None) -> None: ... - -@overload -def safe_decode(s: Union[IO[str], AnyStr]) -> str: ... - -def safe_decode(s: Union[IO[str], AnyStr, None]) -> Optional[str]: - """Safely decodes a binary string to unicode""" - if isinstance(s, str): - return s - elif isinstance(s, bytes): - return s.decode(defenc, 'surrogateescape') - elif s is None: - return None - else: - raise TypeError('Expected bytes or text, but got %r' % (s,)) - - -@overload -def safe_encode(s: None) -> None: ... - -@overload -def safe_encode(s: AnyStr) -> bytes: ... - -def safe_encode(s: Optional[AnyStr]) -> Optional[bytes]: - """Safely encodes a binary string to unicode""" - if isinstance(s, str): - return s.encode(defenc) - elif isinstance(s, bytes): - return s - elif s is None: - return None - else: - raise TypeError('Expected bytes or text, but got %r' % (s,)) - - -@overload -def win_encode(s: None) -> None: ... - -@overload -def win_encode(s: AnyStr) -> bytes: ... - -def win_encode(s: Optional[AnyStr]) -> Optional[bytes]: - """Encode unicodes for process arguments on Windows.""" - if isinstance(s, str): - return s.encode(locale.getpreferredencoding(False)) - elif isinstance(s, bytes): - return s - elif s is not None: - raise TypeError('Expected bytes or text, but got %r' % (s,)) - return None - - -def with_metaclass(meta: Type[Any], *bases: Any) -> 'metaclass': # type: ignore ## mypy cannot understand dynamic class creation - """copied from https://github.com/Byron/bcore/blob/master/src/python/butility/future.py#L15""" - - class metaclass(meta): # type: ignore - __call__ = type.__call__ - __init__ = type.__init__ # type: ignore - - def __new__(cls, name: str, nbases: Optional[int], d: Dict[str, Any]) -> TBD: - if nbases is None: - return type.__new__(cls, name, (), d) - return meta(name, bases, d) - - return metaclass(meta.__name__ + 'Helper', None, {}) diff --git a/git/compat/__init__.py b/git/compat/__init__.py new file mode 100644 index 00000000..c4bd2aa3 --- /dev/null +++ b/git/compat/__init__.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# config.py +# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors +# +# This module is part of GitPython and is released under +# the BSD License: http://www.opensource.org/licenses/bsd-license.php +"""utilities to help provide compatibility with python 3""" +# flake8: noqa + +import locale +import os +import sys + +from gitdb.utils.encoding import ( + force_bytes, # @UnusedImport + force_text # @UnusedImport +) + +# typing -------------------------------------------------------------------- + +from typing import ( + Any, + AnyStr, + Dict, + IO, + Optional, + Type, + Union, + overload, +) +from git.types import TBD + +# --------------------------------------------------------------------------- + + +is_win = (os.name == 'nt') # type: bool +is_posix = (os.name == 'posix') +is_darwin = (os.name == 'darwin') +defenc = sys.getfilesystemencoding() + + +@overload +def safe_decode(s: None) -> None: ... + +@overload +def safe_decode(s: Union[IO[str], AnyStr]) -> str: ... + +def safe_decode(s: Union[IO[str], AnyStr, None]) -> Optional[str]: + """Safely decodes a binary string to unicode""" + if isinstance(s, str): + return s + elif isinstance(s, bytes): + return s.decode(defenc, 'surrogateescape') + elif s is None: + return None + else: + raise TypeError('Expected bytes or text, but got %r' % (s,)) + + +@overload +def safe_encode(s: None) -> None: ... + +@overload +def safe_encode(s: AnyStr) -> bytes: ... + +def safe_encode(s: Optional[AnyStr]) -> Optional[bytes]: + """Safely encodes a binary string to unicode""" + if isinstance(s, str): + return s.encode(defenc) + elif isinstance(s, bytes): + return s + elif s is None: + return None + else: + raise TypeError('Expected bytes or text, but got %r' % (s,)) + + +@overload +def win_encode(s: None) -> None: ... + +@overload +def win_encode(s: AnyStr) -> bytes: ... + +def win_encode(s: Optional[AnyStr]) -> Optional[bytes]: + """Encode unicodes for process arguments on Windows.""" + if isinstance(s, str): + return s.encode(locale.getpreferredencoding(False)) + elif isinstance(s, bytes): + return s + elif s is not None: + raise TypeError('Expected bytes or text, but got %r' % (s,)) + return None + + +def with_metaclass(meta: Type[Any], *bases: Any) -> 'metaclass': # type: ignore ## mypy cannot understand dynamic class creation + """copied from https://github.com/Byron/bcore/blob/master/src/python/butility/future.py#L15""" + + class metaclass(meta): # type: ignore + __call__ = type.__call__ + __init__ = type.__init__ # type: ignore + + def __new__(cls, name: str, nbases: Optional[int], d: Dict[str, Any]) -> TBD: + if nbases is None: + return type.__new__(cls, name, (), d) + return meta(name, bases, d) + + return metaclass(meta.__name__ + 'Helper', None, {}) diff --git a/git/compat/typing.py b/git/compat/typing.py new file mode 100644 index 00000000..4bab4cdd --- /dev/null +++ b/git/compat/typing.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# config.py +# Copyright (C) 2021 Michael Trier (mtrier@gmail.com) and contributors +# +# This module is part of GitPython and is released under +# the BSD License: http://www.opensource.org/licenses/bsd-license.php + +import sys + +if sys.version_info[:2] >= (3, 8): + from typing import Final, Literal +else: + from typing_extensions import Final, Literal diff --git a/git/config.py b/git/config.py index 1cb80475..0c8d975d 100644 --- a/git/config.py +++ b/git/config.py @@ -16,14 +16,13 @@ import re import fnmatch from collections import OrderedDict -from typing_extensions import Literal - from git.compat import ( defenc, force_text, with_metaclass, is_win, ) +from git.compat.typing import Literal from git.util import LockFile import os.path as osp diff --git a/git/diff.py b/git/diff.py index deedb635..943916ea 100644 --- a/git/diff.py +++ b/git/diff.py @@ -16,7 +16,7 @@ from .objects.util import mode_str_to_int # typing ------------------------------------------------------------------ from typing import Any, Iterator, List, Match, Optional, Tuple, Type, Union, TYPE_CHECKING -from typing_extensions import Final, Literal +from git.compat.typing import Final, Literal from git.types import TBD if TYPE_CHECKING: diff --git a/git/repo/base.py b/git/repo/base.py index b1d0cdbc..ed0a810e 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -34,8 +34,8 @@ import gitdb # typing ------------------------------------------------------ +from git.compat.typing import Literal from git.types import TBD, PathLike -from typing_extensions import Literal from typing import (Any, BinaryIO, Callable, Dict, Iterator, List, Mapping, Optional, TextIO, Tuple, Type, Union, -- cgit v1.2.1 From 9448c082b158dcab960d33982e8189f2d2da4729 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 24 Apr 2021 09:49:45 +0800 Subject: Fix flake8 --- git/compat/typing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git') diff --git a/git/compat/typing.py b/git/compat/typing.py index 4bab4cdd..925c5ba2 100644 --- a/git/compat/typing.py +++ b/git/compat/typing.py @@ -8,6 +8,6 @@ import sys if sys.version_info[:2] >= (3, 8): - from typing import Final, Literal + from typing import Final, Literal # noqa: F401 else: - from typing_extensions import Final, Literal + from typing_extensions import Final, Literal # noqa: F401 -- cgit v1.2.1