scmrepo 3.3.2__tar.gz → 3.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of scmrepo might be problematic. Click here for more details.

Files changed (73) hide show
  1. {scmrepo-3.3.2 → scmrepo-3.3.4}/.pre-commit-config.yaml +2 -2
  2. {scmrepo-3.3.2/src/scmrepo.egg-info → scmrepo-3.3.4}/PKG-INFO +2 -2
  3. {scmrepo-3.3.2 → scmrepo-3.3.4}/noxfile.py +1 -1
  4. {scmrepo-3.3.2 → scmrepo-3.3.4}/pyproject.toml +1 -1
  5. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/backend/dulwich/__init__.py +5 -5
  6. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/backend/pygit2/__init__.py +14 -11
  7. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/lfs/fetch.py +23 -1
  8. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/lfs/storage.py +1 -1
  9. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/stash.py +1 -1
  10. {scmrepo-3.3.2 → scmrepo-3.3.4/src/scmrepo.egg-info}/PKG-INFO +2 -2
  11. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo.egg-info/requires.txt +1 -1
  12. {scmrepo-3.3.2 → scmrepo-3.3.4}/.coveragerc +0 -0
  13. {scmrepo-3.3.2 → scmrepo-3.3.4}/.cruft.json +0 -0
  14. {scmrepo-3.3.2 → scmrepo-3.3.4}/.gitattributes +0 -0
  15. {scmrepo-3.3.2 → scmrepo-3.3.4}/.github/dependabot.yml +0 -0
  16. {scmrepo-3.3.2 → scmrepo-3.3.4}/.github/workflows/release.yaml +0 -0
  17. {scmrepo-3.3.2 → scmrepo-3.3.4}/.github/workflows/tests.yaml +0 -0
  18. {scmrepo-3.3.2 → scmrepo-3.3.4}/.github/workflows/update-template.yaml +0 -0
  19. {scmrepo-3.3.2 → scmrepo-3.3.4}/.gitignore +0 -0
  20. {scmrepo-3.3.2 → scmrepo-3.3.4}/CODE_OF_CONDUCT.rst +0 -0
  21. {scmrepo-3.3.2 → scmrepo-3.3.4}/CONTRIBUTING.rst +0 -0
  22. {scmrepo-3.3.2 → scmrepo-3.3.4}/LICENSE +0 -0
  23. {scmrepo-3.3.2 → scmrepo-3.3.4}/README.rst +0 -0
  24. {scmrepo-3.3.2 → scmrepo-3.3.4}/setup.cfg +0 -0
  25. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/__init__.py +0 -0
  26. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/asyn.py +0 -0
  27. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/base.py +0 -0
  28. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/exceptions.py +0 -0
  29. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/fs.py +0 -0
  30. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/__init__.py +0 -0
  31. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/backend/__init__.py +0 -0
  32. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/backend/base.py +0 -0
  33. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/backend/dulwich/asyncssh_vendor.py +0 -0
  34. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/backend/dulwich/client.py +0 -0
  35. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/backend/gitpython.py +0 -0
  36. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/backend/pygit2/callbacks.py +0 -0
  37. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/backend/pygit2/filter.py +0 -0
  38. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/config.py +0 -0
  39. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/credentials.py +0 -0
  40. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/lfs/__init__.py +0 -0
  41. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/lfs/client.py +0 -0
  42. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/lfs/exceptions.py +0 -0
  43. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/lfs/object.py +0 -0
  44. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/lfs/pointer.py +0 -0
  45. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/lfs/progress.py +0 -0
  46. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/lfs/smudge.py +0 -0
  47. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/git/objects.py +0 -0
  48. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/noscm.py +0 -0
  49. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/progress.py +0 -0
  50. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/py.typed +0 -0
  51. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/urls.py +0 -0
  52. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo/utils.py +0 -0
  53. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo.egg-info/SOURCES.txt +0 -0
  54. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo.egg-info/dependency_links.txt +0 -0
  55. {scmrepo-3.3.2 → scmrepo-3.3.4}/src/scmrepo.egg-info/top_level.txt +0 -0
  56. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/__init__.py +0 -0
  57. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/conftest.py +0 -0
  58. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/docker-compose.yml +0 -0
  59. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/git-init/git.sh +0 -0
  60. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/test_credentials.py +0 -0
  61. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/test_dulwich.py +0 -0
  62. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/test_fs.py +0 -0
  63. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/test_git.py +0 -0
  64. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/test_lfs.py +0 -0
  65. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/test_noscm.py +0 -0
  66. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/test_pygit2.py +0 -0
  67. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/test_scmrepo.py +0 -0
  68. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/test_stash.py +0 -0
  69. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/test_urls.py +0 -0
  70. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/user.key +0 -0
  71. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/user.key.pub +0 -0
  72. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/vendor/__init__.py +0 -0
  73. {scmrepo-3.3.2 → scmrepo-3.3.4}/tests/vendor/test_paramiko_vendor.py +0 -0
@@ -2,7 +2,7 @@ default_language_version:
2
2
  python: python3
3
3
  repos:
4
4
  - repo: https://github.com/pre-commit/pre-commit-hooks
5
- rev: v4.5.0
5
+ rev: v4.6.0
6
6
  hooks:
7
7
  - id: check-added-large-files
8
8
  - id: check-case-conflict
@@ -20,7 +20,7 @@ repos:
20
20
  - id: sort-simple-yaml
21
21
  - id: trailing-whitespace
22
22
  - repo: https://github.com/astral-sh/ruff-pre-commit
23
- rev: 'v0.3.5'
23
+ rev: 'v0.4.3'
24
24
  hooks:
25
25
  - id: ruff
26
26
  args: [--fix, --exit-non-zero-on-fix]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scmrepo
3
- Version: 3.3.2
3
+ Version: 3.3.4
4
4
  Summary: scmrepo
5
5
  Author-email: Iterative <support@dvc.org>
6
6
  License: Apache-2.0
@@ -36,7 +36,7 @@ Requires-Dist: pytest-mock; extra == "tests"
36
36
  Requires-Dist: pytest-sugar; extra == "tests"
37
37
  Requires-Dist: pytest-test-utils<0.2,>=0.1.0; extra == "tests"
38
38
  Provides-Extra: dev
39
- Requires-Dist: mypy==1.9.0; extra == "dev"
39
+ Requires-Dist: mypy==1.10.0; extra == "dev"
40
40
  Requires-Dist: scmrepo[tests]; extra == "dev"
41
41
  Requires-Dist: types-certifi; extra == "dev"
42
42
  Requires-Dist: types-mock; extra == "dev"
@@ -37,7 +37,7 @@ def safety(session: nox.Session) -> None:
37
37
  """Scan dependencies for insecure packages."""
38
38
  session.install(".[dev]")
39
39
  session.install("safety")
40
- session.run("safety", "check", "--full-report")
40
+ session.run("safety", "check", "--full-report", "--ignore=67599")
41
41
 
42
42
 
43
43
  @nox.session
@@ -50,7 +50,7 @@ tests = [
50
50
  "pytest-test-utils>=0.1.0,<0.2",
51
51
  ]
52
52
  dev = [
53
- "mypy==1.9.0",
53
+ "mypy==1.10.0",
54
54
  "scmrepo[tests]",
55
55
  "types-certifi",
56
56
  "types-mock",
@@ -264,7 +264,7 @@ class DulwichBackend(BaseGitBackend): # pylint:disable=abstract-method
264
264
  cls._set_mirror(repo, progress=progress)
265
265
  else:
266
266
  cls._set_default_tracking_branch(repo)
267
- except Exception as exc: # noqa: BLE001
267
+ except Exception as exc:
268
268
  raise CloneError(url, os.fsdecode(to_path)) from exc
269
269
 
270
270
  @staticmethod
@@ -580,7 +580,7 @@ class DulwichBackend(BaseGitBackend): # pylint:disable=abstract-method
580
580
  try:
581
581
  _remote, location = get_remote_repo(self.repo, url)
582
582
  client, path = get_transport_and_path(location, **kwargs)
583
- except Exception as exc: # noqa: BLE001
583
+ except Exception as exc:
584
584
  raise InvalidRemote(url) from exc
585
585
 
586
586
  try:
@@ -617,7 +617,7 @@ class DulwichBackend(BaseGitBackend): # pylint:disable=abstract-method
617
617
  try:
618
618
  _remote, location = get_remote_repo(self.repo, url)
619
619
  client, path = get_transport_and_path(location, **kwargs)
620
- except Exception as exc: # noqa: BLE001
620
+ except Exception as exc:
621
621
  raise SCMError(f"'{url}' is not a valid Git remote or URL") from exc
622
622
 
623
623
  change_result = {}
@@ -910,7 +910,7 @@ class DulwichBackend(BaseGitBackend): # pylint:disable=abstract-method
910
910
  try:
911
911
  _, location = get_remote_repo(self.repo, url)
912
912
  client, path = get_transport_and_path(location, **kwargs)
913
- except Exception as exc: # noqa: BLE001
913
+ except Exception as exc:
914
914
  raise InvalidRemote(url) from exc
915
915
  if isinstance(client, LocalGitClient) and not os.path.exists(
916
916
  os.path.join("", path)
@@ -989,5 +989,5 @@ def ls_remote(url: str) -> dict[str, str]:
989
989
  return {os.fsdecode(ref): sha.decode("ascii") for ref, sha in refs.items()}
990
990
  except HTTPUnauthorized as exc:
991
991
  raise AuthError(url) from exc
992
- except Exception as exc: # noqa: BLE001
992
+ except Exception as exc:
993
993
  raise InvalidRemote(url) from exc
@@ -72,7 +72,7 @@ class Pygit2Object(GitObject):
72
72
  path = "/".join(key)
73
73
  blob_kwargs = {
74
74
  "as_path": path,
75
- "commit_id": commit.oid,
75
+ "commit_id": commit.id,
76
76
  }
77
77
  blobio = BlobIO(self.obj, **blob_kwargs)
78
78
  if mode == "rb":
@@ -108,7 +108,7 @@ class Pygit2Object(GitObject):
108
108
 
109
109
  @property
110
110
  def sha(self) -> str:
111
- return self.obj.hex
111
+ return str(self.obj.id)
112
112
 
113
113
  def scandir(self) -> Iterable["Pygit2Object"]:
114
114
  for entry in self.obj:
@@ -190,12 +190,13 @@ class Pygit2Backend(BaseGitBackend): # pylint:disable=abstract-method
190
190
  return RefdbFsBackend(self.repo)
191
191
 
192
192
  def _resolve_refish(self, refish: str):
193
- from pygit2 import GIT_OBJ_COMMIT, Tag
193
+ from pygit2 import Tag
194
+ from pygit2.enums import ObjectType
194
195
 
195
196
  commit, ref = self.repo.resolve_refish(refish)
196
197
  if isinstance(commit, Tag):
197
198
  ref = commit
198
- commit = commit.peel(GIT_OBJ_COMMIT)
199
+ commit = commit.peel(ObjectType.COMMIT)
199
200
  return commit, ref
200
201
 
201
202
  @property
@@ -395,7 +396,8 @@ class Pygit2Backend(BaseGitBackend): # pylint:disable=abstract-method
395
396
  annotated: bool = False,
396
397
  message: Optional[str] = None,
397
398
  ):
398
- from pygit2 import GIT_OBJ_COMMIT, GitError
399
+ from pygit2 import GitError
400
+ from pygit2.enums import ObjectType
399
401
 
400
402
  if annotated and not message:
401
403
  raise SCMError("message is required for annotated tag")
@@ -404,7 +406,7 @@ class Pygit2Backend(BaseGitBackend): # pylint:disable=abstract-method
404
406
  self.repo.create_tag(
405
407
  tag,
406
408
  target_obj.id,
407
- GIT_OBJ_COMMIT,
409
+ ObjectType.COMMIT,
408
410
  self.committer,
409
411
  message or "",
410
412
  )
@@ -526,7 +528,8 @@ class Pygit2Backend(BaseGitBackend): # pylint:disable=abstract-method
526
528
  self.repo.create_reference_direct(name, new_ref, True, message=message)
527
529
 
528
530
  def get_ref(self, name, follow: bool = True) -> Optional[str]:
529
- from pygit2 import GIT_OBJ_COMMIT, GIT_REF_SYMBOLIC, InvalidSpecError, Tag
531
+ from pygit2 import InvalidSpecError, Tag
532
+ from pygit2.enums import ObjectType, ReferenceType
530
533
 
531
534
  try:
532
535
  ref = self.repo.references.get(name)
@@ -534,12 +537,12 @@ class Pygit2Backend(BaseGitBackend): # pylint:disable=abstract-method
534
537
  return None
535
538
  if not ref:
536
539
  return None
537
- if follow and ref.type == GIT_REF_SYMBOLIC:
540
+ if follow and ref.type == ReferenceType.SYMBOLIC:
538
541
  ref = ref.resolve()
539
542
  try:
540
543
  obj = self.repo[ref.target]
541
544
  if isinstance(obj, Tag):
542
- return str(obj.peel(GIT_OBJ_COMMIT).id)
545
+ return str(obj.peel(ObjectType.COMMIT).id)
543
546
  except ValueError:
544
547
  pass
545
548
 
@@ -841,7 +844,7 @@ class Pygit2Backend(BaseGitBackend): # pylint:disable=abstract-method
841
844
  if os.name == "nt":
842
845
  rel = rel.replace("\\", "/")
843
846
  obj = tree[rel]
844
- self.repo.index.add(IndexEntry(rel, obj.oid, obj.filemode))
847
+ self.repo.index.add(IndexEntry(rel, obj.id, obj.filemode))
845
848
  self.repo.index.write()
846
849
  elif hard:
847
850
  self.repo.reset(self.repo.head.target, GIT_RESET_HARD)
@@ -1077,7 +1080,7 @@ class Pygit2Backend(BaseGitBackend): # pylint:disable=abstract-method
1077
1080
  if isinstance(tag, Tag):
1078
1081
  return GitTag(
1079
1082
  tag.name,
1080
- str(tag.oid),
1083
+ str(tag.id),
1081
1084
  str(tag.target),
1082
1085
  tag.tagger.name,
1083
1086
  tag.tagger.email,
@@ -1,6 +1,7 @@
1
1
  import fnmatch
2
2
  import io
3
3
  import os
4
+ import re
4
5
  from collections.abc import Iterable, Iterator
5
6
  from typing import TYPE_CHECKING, Callable, Optional
6
7
 
@@ -98,6 +99,9 @@ def get_fetch_url(scm: "Git", remote: Optional[str] = None): # noqa: C901,PLR09
98
99
  return scm.get_remote_url(remote)
99
100
 
100
101
 
102
+ _ROOT_PATH_PREFIX_REGEX = re.compile(r"^(?P<prefix>[^*?\[]*(?:/|$))")
103
+
104
+
101
105
  def _collect_objects(
102
106
  scm: "Git",
103
107
  rev: str,
@@ -105,7 +109,25 @@ def _collect_objects(
105
109
  exclude: Optional[list[str]],
106
110
  ) -> Iterator[Pointer]:
107
111
  fs = scm.get_fs(rev)
108
- for path in _filter_paths(fs.find("/"), include, exclude):
112
+ # Optimize path filtering if the `include` list contains exactly one path.
113
+ # First, determine the root directory wherein to initiate the file search.
114
+ # If the `include` path is a Unix filename pattern, determine the static
115
+ # path prefix and set it as the root directory. Second, if the path and the
116
+ # root are identical or the Unix filename pattern matches *any* (i.e., `**`)
117
+ # file under the root directory, unset `include` to avoid unnecessary
118
+ # filtering work.
119
+ if (
120
+ include
121
+ and len(include) == 1
122
+ and (result := _ROOT_PATH_PREFIX_REGEX.match(path := include[0]))
123
+ ):
124
+ root = result.group("prefix")
125
+ if path in {root, f'{root.rstrip("/")}/**'}:
126
+ include = []
127
+ else:
128
+ root = "/"
129
+
130
+ for path in _filter_paths(fs.find(root), include, exclude):
109
131
  check_path = path.lstrip("/")
110
132
  if scm.check_attr(check_path, "filter", source=rev) == "lfs":
111
133
  try:
@@ -53,7 +53,7 @@ class LFSStorage:
53
53
  raise
54
54
  try:
55
55
  self.fetch(fetch_url, [obj], batch_size=batch_size)
56
- except BaseException as exc: # noqa: BLE001
56
+ except BaseException as exc:
57
57
  raise FileNotFoundError(
58
58
  errno.ENOENT, os.strerror(errno.ENOENT), path
59
59
  ) from exc
@@ -53,7 +53,7 @@ class Stash:
53
53
  rev = self.scm.resolve_rev(ref)
54
54
  try:
55
55
  self.apply(rev, **kwargs)
56
- except Exception as exc: # noqa: BLE001
56
+ except Exception as exc:
57
57
  raise SCMError("Could not apply stash commit") from exc
58
58
  self.drop()
59
59
  return rev
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scmrepo
3
- Version: 3.3.2
3
+ Version: 3.3.4
4
4
  Summary: scmrepo
5
5
  Author-email: Iterative <support@dvc.org>
6
6
  License: Apache-2.0
@@ -36,7 +36,7 @@ Requires-Dist: pytest-mock; extra == "tests"
36
36
  Requires-Dist: pytest-sugar; extra == "tests"
37
37
  Requires-Dist: pytest-test-utils<0.2,>=0.1.0; extra == "tests"
38
38
  Provides-Extra: dev
39
- Requires-Dist: mypy==1.9.0; extra == "dev"
39
+ Requires-Dist: mypy==1.10.0; extra == "dev"
40
40
  Requires-Dist: scmrepo[tests]; extra == "dev"
41
41
  Requires-Dist: types-certifi; extra == "dev"
42
42
  Requires-Dist: types-mock; extra == "dev"
@@ -10,7 +10,7 @@ aiohttp-retry>=2.5.0
10
10
  tqdm
11
11
 
12
12
  [dev]
13
- mypy==1.9.0
13
+ mypy==1.10.0
14
14
  scmrepo[tests]
15
15
  types-certifi
16
16
  types-mock
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes