Skip to content

Commit 8a1f87d

Browse files
authored
Merge branch 'gitpython-developers:main' into main
2 parents c062de2 + 0a6d9d6 commit 8a1f87d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+972
-445
lines changed

.appveyor.yml

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,12 @@ environment:
66
CYGWIN64_GIT_PATH: "C:\\cygwin64\\bin;%GIT_DAEMON_PATH%"
77

88
matrix:
9-
- PYTHON: "C:\\Python34-x64"
10-
PYTHON_VERSION: "3.4"
11-
GIT_PATH: "%GIT_DAEMON_PATH%"
12-
- PYTHON: "C:\\Python35-x64"
13-
PYTHON_VERSION: "3.5"
14-
GIT_PATH: "%GIT_DAEMON_PATH%"
159
- PYTHON: "C:\\Python36-x64"
1610
PYTHON_VERSION: "3.6"
1711
GIT_PATH: "%GIT_DAEMON_PATH%"
1812
- PYTHON: "C:\\Python37-x64"
1913
PYTHON_VERSION: "3.7"
2014
GIT_PATH: "%GIT_DAEMON_PATH%"
21-
- PYTHON: "C:\\Miniconda35-x64"
22-
PYTHON_VERSION: "3.5"
23-
IS_CONDA: "yes"
24-
MAYFAIL: "yes"
25-
GIT_PATH: "%GIT_DAEMON_PATH%"
26-
## Cygwin
27-
- PYTHON: "C:\\Python35-x64"
28-
PYTHON_VERSION: "3.5"
29-
IS_CYGWIN: "yes"
30-
MAYFAIL: "yes"
31-
GIT_PATH: "%CYGWIN64_GIT_PATH%"
3215

3316
matrix:
3417
allow_failures:
@@ -76,18 +59,10 @@ install:
7659
build: false
7760

7861
test_script:
79-
- IF "%IS_CYGWIN%" == "yes" (
80-
nosetests -v
81-
) ELSE (
82-
IF "%PYTHON_VERSION%" == "3.5" (
83-
nosetests -v --with-coverage
84-
) ELSE (
85-
nosetests -v
86-
)
87-
)
62+
- nosetests -v
8863

8964
on_success:
90-
- IF "%PYTHON_VERSION%" == "3.5" IF NOT "%IS_CYGWIN%" == "yes" (codecov)
65+
- IF "%PYTHON_VERSION%" == "3.6" IF NOT "%IS_CYGWIN%" == "yes" (codecov)
9166

9267
# Enable this to be able to login to the build worker. You can use the
9368
# `remmina` program in Ubuntu, use the login information that the line below

.github/workflows/pythonpackage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
strategy:
1717
matrix:
18-
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
18+
python-version: [3.6, 3.7, 3.8, 3.9]
1919

2020
steps:
2121
- uses: actions/checkout@v2

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ nbproject
2121
.mypy_cache/
2222
.pytest_cache/
2323
monkeytype.sqlite3
24+
output.txt

.travis.yml

Lines changed: 0 additions & 44 deletions
This file was deleted.

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ Contributors are:
4343
-Liam Beguin <liambeguin _at_ gmail.com>
4444
-Ram Rachum <ram _at_ rachum.com>
4545
-Alba Mendez <me _at_ alba.sh>
46+
-Robert Westman <robert _at_ byteflux.io>
4647
Portions derived from other open source works and are clearly marked.

CHANGES

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
Please see the online documentation for the latest changelog:
2-
https://github.com/gitpython-developers/GitPython/blob/master/doc/source/changes.rst
2+
https://github.com/gitpython-developers/GitPython/blob/main/doc/source/changes.rst

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ include README.md
66
include VERSION
77
include requirements.txt
88
include test-requirements.txt
9+
include git/py.typed
910

1011
recursive-include doc *
1112
recursive-exclude test *

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ If it is not in your `PATH`, you can help GitPython find it by setting
3434
the `GIT_PYTHON_GIT_EXECUTABLE=<path/to/git>` environment variable.
3535

3636
* Git (1.7.x or newer)
37-
* Python >= 3.5
37+
* Python >= 3.6
3838

3939
The list of dependencies are listed in `./requirements.txt` and `./test-requirements.txt`.
4040
The installer takes care of installing them for you.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.1.17
1+
3.1.18

doc/source/changes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
Changelog
33
=========
44

5+
3.1.18
6+
======
7+
8+
* drop support for python 3.5 to reduce maintenance burden on typing. Lower patch levels of python 3.5 would break, too.
9+
10+
See the following for details:
11+
https://github.com/gitpython-developers/gitpython/milestone/50?closed=1
12+
513
3.1.17
614
======
715

doc/source/intro.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The object database implementation is optimized for handling large quantities of
1313
Requirements
1414
============
1515

16-
* `Python`_ >= 3.5
16+
* `Python`_ >= 3.6
1717
* `Git`_ 1.7.0 or newer
1818
It should also work with older versions, but it may be that some operations
1919
involving remotes will not work as expected.

doc/source/tutorial.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ GitPython Tutorial
1010

1111
GitPython provides object model access to your git repository. This tutorial is composed of multiple sections, most of which explains a real-life usecase.
1212

13-
All code presented here originated from `test_docs.py <https://github.com/gitpython-developers/GitPython/blob/master/test/test_docs.py>`_ to assure correctness. Knowing this should also allow you to more easily run the code for your own testing purposes, all you need is a developer installation of git-python.
13+
All code presented here originated from `test_docs.py <https://github.com/gitpython-developers/GitPython/blob/main/test/test_docs.py>`_ to assure correctness. Knowing this should also allow you to more easily run the code for your own testing purposes, all you need is a developer installation of git-python.
1414

1515
Meet the Repo type
1616
******************

git/cmd.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
import subprocess
1818
import sys
1919
import threading
20-
from collections import OrderedDict
2120
from textwrap import dedent
22-
import warnings
2321

2422
from git.compat import (
2523
defenc,
@@ -150,7 +148,6 @@ def dashify(string: str) -> str:
150148

151149

152150
def slots_to_dict(self, exclude: Sequence[str] = ()) -> Dict[str, Any]:
153-
# annotate self.__slots__ as Tuple[str, ...] once 3.5 dropped
154151
return {s: getattr(self, s) for s in self.__slots__ if s not in exclude}
155152

156153

@@ -345,11 +342,11 @@ def polish_url(cls, url: str, is_cygwin: Literal[False] = ...) -> str:
345342

346343
@overload
347344
@classmethod
348-
def polish_url(cls, url: PathLike, is_cygwin: Union[None, bool] = None) -> str:
345+
def polish_url(cls, url: str, is_cygwin: Union[None, bool] = None) -> str:
349346
...
350347

351348
@classmethod
352-
def polish_url(cls, url: PathLike, is_cygwin: Union[None, bool] = None) -> PathLike:
349+
def polish_url(cls, url: str, is_cygwin: Union[None, bool] = None) -> PathLike:
353350
if is_cygwin is None:
354351
is_cygwin = cls.is_cygwin()
355352

@@ -462,7 +459,7 @@ class CatFileContentStream(object):
462459
If not all data is read to the end of the objects's lifetime, we read the
463460
rest to assure the underlying stream continues to work"""
464461

465-
__slots__ = ('_stream', '_nbr', '_size')
462+
__slots__: Tuple[str, ...] = ('_stream', '_nbr', '_size')
466463

467464
def __init__(self, size: int, stream: IO[bytes]) -> None:
468465
self._stream = stream
@@ -1005,13 +1002,6 @@ def transform_kwarg(self, name: str, value: Any, split_single_char_options: bool
10051002

10061003
def transform_kwargs(self, split_single_char_options: bool = True, **kwargs: Any) -> List[str]:
10071004
"""Transforms Python style kwargs into git command line options."""
1008-
# Python 3.6 preserves the order of kwargs and thus has a stable
1009-
# order. For older versions sort the kwargs by the key to get a stable
1010-
# order.
1011-
if sys.version_info[:2] < (3, 6):
1012-
kwargs = OrderedDict(sorted(kwargs.items(), key=lambda x: x[0]))
1013-
warnings.warn("Python 3.5 support is deprecated and will be removed 2021-09-05.\n" +
1014-
"It does not preserve the order for key-word arguments and enforce lexical sorting instead.")
10151005
args = []
10161006
for k, v in kwargs.items():
10171007
if isinstance(v, (list, tuple)):

git/config.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929

3030
import configparser as cp
3131

32-
from pathlib import Path
33-
3432
# typing-------------------------------------------------------
3533

3634
from typing import Any, Callable, IO, List, Dict, Sequence, TYPE_CHECKING, Tuple, Union, cast, overload
@@ -330,7 +328,7 @@ def _acquire_lock(self) -> None:
330328
"Write-ConfigParsers can operate on a single file only, multiple files have been passed")
331329
# END single file check
332330

333-
if isinstance(self._file_or_files, (str, Path)): # cannot narrow by os._pathlike until 3.5 dropped
331+
if isinstance(self._file_or_files, (str, os.PathLike)):
334332
file_or_files = self._file_or_files
335333
else:
336334
file_or_files = cast(IO, self._file_or_files).name
@@ -696,6 +694,16 @@ def read_only(self) -> bool:
696694
""":return: True if this instance may change the configuration file"""
697695
return self._read_only
698696

697+
@overload
698+
def get_value(self, section: str, option: str, default: str
699+
) -> str:
700+
...
701+
702+
@overload
703+
def get_value(self, section: str, option: str, default: float
704+
) -> float:
705+
...
706+
699707
def get_value(self, section: str, option: str, default: Union[int, float, str, bool, None] = None
700708
) -> Union[int, float, str, bool]:
701709
# can default or return type include bool?

git/diff.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# typing ------------------------------------------------------------------
1717

1818
from typing import Any, Iterator, List, Match, Optional, Tuple, Type, Union, TYPE_CHECKING
19-
from git.types import PathLike, TBD, Final, Literal
19+
from git.types import PathLike, TBD, Literal
2020

2121
if TYPE_CHECKING:
2222
from .objects.tree import Tree
@@ -31,7 +31,7 @@
3131
__all__ = ('Diffable', 'DiffIndex', 'Diff', 'NULL_TREE')
3232

3333
# Special object to compare against the empty tree in diffs
34-
NULL_TREE = object() # type: Final[object]
34+
NULL_TREE = object()
3535

3636
_octal_byte_re = re.compile(b'\\\\([0-9]{3})')
3737

git/index/base.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#
44
# This module is part of GitPython and is released under
55
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
6-
from git.refs.reference import Reference
6+
77
import glob
88
from io import BytesIO
99
import os
@@ -74,6 +74,8 @@
7474
if TYPE_CHECKING:
7575
from subprocess import Popen
7676
from git.repo import Repo
77+
from git.refs.reference import Reference
78+
from git.util import Actor
7779

7880

7981
StageType = int
@@ -568,7 +570,7 @@ def write_tree(self) -> Tree:
568570
# note: additional deserialization could be saved if write_tree_from_cache
569571
# would return sorted tree entries
570572
root_tree = Tree(self.repo, binsha, path='')
571-
root_tree._cache = tree_items
573+
root_tree._cache = tree_items # type: ignore
572574
return root_tree
573575

574576
def _process_diff_args(self, args: List[Union[str, diff.Diffable, object]]
@@ -966,8 +968,8 @@ def move(self, items: Sequence[Union[PathLike, Blob, BaseIndexEntry, Submodule]]
966968

967969
return out
968970

969-
def commit(self, message: str, parent_commits=None, head: bool = True, author: str = None,
970-
committer: str = None, author_date: str = None, commit_date: str = None,
971+
def commit(self, message: str, parent_commits=None, head: bool = True, author: Union[None, 'Actor'] = None,
972+
committer: Union[None, 'Actor'] = None, author_date: str = None, commit_date: str = None,
971973
skip_hooks: bool = False) -> Commit:
972974
"""Commit the current default index file, creating a commit object.
973975
For more information on the arguments, see tree.commit.
@@ -1191,7 +1193,7 @@ def handle_stderr(proc: 'Popen[bytes]', iter_checked_out_files: Iterable[PathLik
11911193
assert "Should not reach this point"
11921194

11931195
@default_index
1194-
def reset(self, commit: Union[Commit, Reference, str] = 'HEAD', working_tree: bool = False,
1196+
def reset(self, commit: Union[Commit, 'Reference', str] = 'HEAD', working_tree: bool = False,
11951197
paths: Union[None, Iterable[PathLike]] = None,
11961198
head: bool = False, **kwargs: Any) -> 'IndexFile':
11971199
"""Reset the index to reflect the tree at the given commit. This will not

git/index/fun.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353

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

56-
from git.types import PathLike
56+
from git.types import PathLike, TypeGuard
5757

5858
if TYPE_CHECKING:
5959
from .base import IndexFile
@@ -109,7 +109,7 @@ def run_commit_hook(name: str, index: 'IndexFile', *args: str) -> None:
109109
# end handle return code
110110

111111

112-
def stat_mode_to_index_mode(mode):
112+
def stat_mode_to_index_mode(mode: int) -> int:
113113
"""Convert the given mode from a stat call to the corresponding index mode
114114
and return it"""
115115
if S_ISLNK(mode): # symlinks
@@ -185,11 +185,17 @@ def read_header(stream: IO[bytes]) -> Tuple[int, int]:
185185
def entry_key(*entry: Union[BaseIndexEntry, PathLike, int]) -> Tuple[PathLike, int]:
186186
""":return: Key suitable to be used for the index.entries dictionary
187187
:param entry: One instance of type BaseIndexEntry or the path and the stage"""
188+
189+
def is_entry_tuple(entry: Tuple) -> TypeGuard[Tuple[PathLike, int]]:
190+
return isinstance(entry, tuple) and len(entry) == 2
191+
188192
if len(entry) == 1:
189-
entry_first = cast(BaseIndexEntry, entry[0]) # type: BaseIndexEntry
193+
entry_first = entry[0]
194+
assert isinstance(entry_first, BaseIndexEntry)
190195
return (entry_first.path, entry_first.stage)
191196
else:
192-
entry = cast(Tuple[PathLike, int], tuple(entry))
197+
# entry = tuple(entry)
198+
assert is_entry_tuple(entry)
193199
return entry
194200
# END handle entry
195201

@@ -293,7 +299,7 @@ def write_tree_from_cache(entries: List[IndexEntry], odb, sl: slice, si: int = 0
293299
# finally create the tree
294300
sio = BytesIO()
295301
tree_to_stream(tree_items, sio.write) # converts bytes of each item[0] to str
296-
tree_items_stringified = cast(List[Tuple[str, int, str]], tree_items) # type: List[Tuple[str, int, str]]
302+
tree_items_stringified = cast(List[Tuple[str, int, str]], tree_items)
297303
sio.seek(0)
298304

299305
istream = odb.store(IStream(str_tree_type, len(sio.getvalue()), sio))

0 commit comments

Comments
 (0)