Skip to content

Commit

Permalink
feat: support python 3.13 (#539)
Browse files Browse the repository at this point in the history
* feat: support python 3.13

* revert linters to 3.12, satisfy mypy

* Add CHANGELOG entry

---------

Co-authored-by: Scott Bailey <[email protected]>
  • Loading branch information
branchvincent and rscottbailey authored Oct 17, 2024
1 parent a6d44bc commit 8092d1e
Show file tree
Hide file tree
Showing 8 changed files with 666 additions and 522 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: [3.8, 3.9, "3.10", 3.11, 3.12]
python-version: [3.8, 3.9, "3.10", 3.11, 3.12, 3.13]
include:
- os: ubuntu-latest
path: ~/.cache/pypoetry
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@f095bcc56b7c2baf48f3ac70d6d6782f4f553222
- name: Set up Python 3.12
- name: Set up Python 3.13
uses: actions/setup-python@db9987b4c1f10f0404fa60ee629f675fafbd6763
with:
python-version: 3.12
python-version: 3.13
- name: Install dependencies
run: |
pip install --upgrade pip
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
v5.0.2 - Mmmm DD 2024
---------------------

* [#539](https://github.com/godaddy/tartufo/pull/539) - Add support for python
3.13, and update dependencies to latest versions.

v5.0.1 - July 25 2024
---------------------

Expand Down
1,128 changes: 628 additions & 500 deletions poetry.lock

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Security",
Expand All @@ -39,10 +40,13 @@ tartufo = "tartufo.cli:main"

[tool.poetry.dependencies]
GitPython = "^3.1.43"
pygit2 = "^1.11.0"
pygit2 = [
{version = "^1.11.0", python = "<3.10"},
{version = "^1.16.0", python = ">=3.10"}
]
click = "^8.1.7"
colorama = {version = "*", markers = "sys_platform == 'win32'"}
python = ">=3.8, <3.13"
python = ">=3.8, <3.14"
tomlkit = "^0.13.0"
cached-property = "^1.5.2"

Expand Down
33 changes: 19 additions & 14 deletions tartufo/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ def __init__(self, global_options: types.GlobalOptions, repo_path: str) -> None:
# Disable ownership sanity checks to maintain compatibility with
# behavior of libgit2 1.4.2 and earlier; later versions (i.e. with
# pygit2 1.9.2 and later) fail in docker context otherwise.
pygit2.option(pygit2.GIT_OPT_SET_OWNER_VALIDATION, 0)
pygit2.option(pygit2.GIT_OPT_SET_OWNER_VALIDATION, 0) # type: ignore[attr-defined]

# Load any configuration file in the target repository. This comes
# *BEFORE* load_repo() because that method may rely on configuration data
Expand Down Expand Up @@ -735,13 +735,13 @@ def _iter_diff_index(
file_path = (
delta.new_file.path if delta.new_file.path else delta.old_file.path
)
if delta.status == pygit2.GIT_DELTA_DELETED:
if delta.status == pygit2.GIT_DELTA_DELETED: # type: ignore[attr-defined]
self.logger.debug("Skipping as the file was a git delete operation")
continue
if delta.is_binary:
self.logger.debug("Binary file skipped: %s", file_path)
continue
printable_diff: str = patch.text
printable_diff: str = patch.text or ""
if not self.global_options.scan_filenames:
# The `printable_diff` contains diff header,
# so we need to strip that before analyzing it
Expand Down Expand Up @@ -773,7 +773,7 @@ def filter_submodules(self, repo: pygit2.Repository) -> None:
self.logger.info("Excluding submodules paths from scan.")
try:
for module in repo.listall_submodules():
submodule = repo.lookup_submodule(module)
submodule = repo.lookup_submodule(module) # type: ignore[attr-defined]
patterns.append(re.compile(f"^{submodule.path}"))
except AttributeError as exc:
raise TartufoException(
Expand Down Expand Up @@ -825,11 +825,14 @@ def load_repo(self, repo_path: str) -> pygit2.Repository:
raise types.GitLocalException(str(exc)) from exc

def _get_chunks(
self, commits: Iterable, already_searched: Set[bytes], branch_name: str
self,
commits: Iterable[pygit2.Commit],
already_searched: Set[bytes],
branch_name: str,
) -> Generator[types.Chunk, None, None]:
diff_hash: bytes
curr_commit: pygit2.Commit = None
prev_commit: pygit2.Commit = None
curr_commit: Optional[pygit2.Commit] = None
prev_commit: Optional[pygit2.Commit] = None
for curr_commit in commits:
try:
prev_commit = curr_commit.parents[0]
Expand All @@ -847,7 +850,7 @@ def _get_chunks(
).digest()
if diff_hash in already_searched:
continue
diff: pygit2.Diff = self._repo.diff(prev_commit, curr_commit)
diff: pygit2.Diff = self._repo.diff(prev_commit, curr_commit) # type: ignore[attr-defined]
already_searched.add(diff_hash)
diff.find_similar()
for blob, file_path in self._iter_diff_index(diff):
Expand All @@ -860,7 +863,7 @@ def _get_chunks(

# Finally, yield the first commit to the branch
if curr_commit:
tree: pygit2.Tree = self._repo.revparse_single(str(curr_commit.id)).tree
tree: pygit2.Tree = self._repo.revparse_single(str(curr_commit.id)).tree # type: ignore[attr-defined]
tree_diff: pygit2.Diff = tree.diff_to_tree(swap=True)
iter_diff = self._iter_diff_index(tree_diff)
for blob, file_path in iter_diff:
Expand All @@ -882,7 +885,7 @@ def chunks(self) -> Generator[types.Chunk, None, None]:
try:
if self.git_options.branch:
# Single branch only
branch = self._repo.branches.get(self.git_options.branch)
branch = self._repo.branches.get(self.git_options.branch) # type: ignore[attr-defined]
if not branch:
raise BranchNotFoundException(
f"Branch {self.git_options.branch} was not found."
Expand All @@ -899,7 +902,7 @@ def chunks(self) -> Generator[types.Chunk, None, None]:
# scan not only the locally checked out branches (as provided
# by self._repo.listall_branches()), but to also scan all
# available remote refs
branches = list(self._repo.branches)
branches = list(self._repo.branches) # type: ignore[attr-defined]
except pygit2.GitError as exc:
raise types.GitRemoteException(str(exc)) from exc

Expand All @@ -911,13 +914,15 @@ def chunks(self) -> Generator[types.Chunk, None, None]:
branch_len = len(branches)
for branch_name in branches:
self.logger.info("Scanning branch: %s", branch_name)
commits: Iterable[pygit2.Commit]
if branch_name == "HEAD":
commits = [self._repo.get(self._repo.head.target)]
commits = [self._repo.get(self._repo.head.target)] # type: ignore[attr-defined]
else:
branch = self._repo.branches.get(branch_name)
branch = self._repo.branches.get(branch_name) # type: ignore[attr-defined]
try:
commits = self._repo.walk(
branch.resolve().target, pygit2.GIT_SORT_TOPOLOGICAL
branch.resolve().target,
pygit2.GIT_SORT_TOPOLOGICAL, # type: ignore[attr-defined]
)

except AttributeError:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_git_repo_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ def test_excluded_files_are_not_scanned(self, mock_should: mock.MagicMock):
test_scanner = scanner.GitRepoScanner(
self.global_options, self.git_options, "."
)
diffs = list(test_scanner._iter_diff_index([mock_diff]))
diffs = list(test_scanner._iter_diff_index([mock_diff])) # type: ignore[arg-type]
self.assertEqual(diffs, [])
mock_should.assert_called_once()

Expand Down Expand Up @@ -502,7 +502,7 @@ def test_all_files_are_yielded(self, mock_should: mock.MagicMock):
test_scanner = scanner.GitRepoScanner(
self.global_options, self.git_options, "."
)
diffs = list(test_scanner._iter_diff_index([mock_diff_1, mock_diff_2]))
diffs = list(test_scanner._iter_diff_index([mock_diff_1, mock_diff_2])) # type: ignore[arg-type]
self.assertEqual(
diffs,
[
Expand Down
3 changes: 2 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
minversion = 3.8.0
toxworkdir = {env:TOX_WORK_DIR:.tox}
skip_missing_interpreters = True
envlist = py{38,39,pypy3,310,311,312},black,mypy,pylint,vulture,docs
envlist = py{38,39,pypy3,310,311,312,313},black,mypy,pylint,vulture,docs
parallel_show_output = True
isolated_build = True

Expand All @@ -13,6 +13,7 @@ python =
3.10: py310
3.11: py311
3.12: py312
3.13: py313
pypy3: pypy3

[testenv]
Expand Down

0 comments on commit 8092d1e

Please sign in to comment.