Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5aaaa02

Browse filesBrowse files
authored
Merge pull request #1780 from EliahKagan/iteritems
Better document IterableObj.iter_items and improve some subclasses
2 parents d986a59 + dfee31f commit 5aaaa02
Copy full SHA for 5aaaa02

File tree

4 files changed

+66
-36
lines changed
Filter options

4 files changed

+66
-36
lines changed

‎git/objects/submodule/base.py

Copy file name to clipboardExpand all lines: git/objects/submodule/base.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1401,7 +1401,7 @@ def iter_items(
14011401
pc = repo.commit(parent_commit) # Parent commit instance
14021402
parser = cls._config_parser(repo, pc, read_only=True)
14031403
except (IOError, BadName):
1404-
return iter([])
1404+
return
14051405
# END handle empty iterator
14061406

14071407
for sms in parser.sections():

‎git/remote.py

Copy file name to clipboardExpand all lines: git/remote.py
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def to_progress_instance(
130130
return progress
131131

132132

133-
class PushInfo(IterableObj, object):
133+
class PushInfo(IterableObj):
134134
"""
135135
Carries information about the result of a push operation of a single head::
136136
@@ -300,7 +300,7 @@ def raise_if_error(self) -> None:
300300
raise self.error
301301

302302

303-
class FetchInfo(IterableObj, object):
303+
class FetchInfo(IterableObj):
304304
"""
305305
Carries information about the results of a fetch operation of a single head::
306306

‎git/util.py

Copy file name to clipboardExpand all lines: git/util.py
+51-33Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,8 @@ def __delitem__(self, index: Union[SupportsIndex, int, slice, str]) -> None:
11831183

11841184

11851185
class IterableClassWatcher(type):
1186-
"""Metaclass that watches."""
1186+
"""Metaclass that issues :class:`DeprecationWarning` when :class:`git.util.Iterable`
1187+
is subclassed."""
11871188

11881189
def __init__(cls, name: str, bases: Tuple, clsdict: Dict) -> None:
11891190
for base in bases:
@@ -1199,39 +1200,49 @@ def __init__(cls, name: str, bases: Tuple, clsdict: Dict) -> None:
11991200

12001201

12011202
class Iterable(metaclass=IterableClassWatcher):
1202-
"""Defines an interface for iterable items, so there is a uniform way to retrieve
1203-
and iterate items within the git repository."""
1203+
"""Deprecated, use :class:`IterableObj` instead.
1204+
1205+
Defines an interface for iterable items, so there is a uniform way to retrieve
1206+
and iterate items within the git repository.
1207+
"""
12041208

12051209
__slots__ = ()
12061210

12071211
_id_attribute_ = "attribute that most suitably identifies your instance"
12081212

12091213
@classmethod
1210-
def list_items(cls, repo: "Repo", *args: Any, **kwargs: Any) -> Any:
1214+
def iter_items(cls, repo: "Repo", *args: Any, **kwargs: Any) -> Any:
1215+
# return typed to be compatible with subtypes e.g. Remote
1216+
"""Deprecated, use :class:`IterableObj` instead.
1217+
1218+
Find (all) items of this type.
1219+
1220+
Subclasses can specify ``args`` and ``kwargs`` differently, and may use them for
1221+
filtering. However, when the method is called with no additional positional or
1222+
keyword arguments, subclasses are obliged to to yield all items.
1223+
1224+
:return: Iterator yielding Items
12111225
"""
1212-
Deprecated, use IterableObj instead.
1226+
raise NotImplementedError("To be implemented by Subclass")
1227+
1228+
@classmethod
1229+
def list_items(cls, repo: "Repo", *args: Any, **kwargs: Any) -> Any:
1230+
"""Deprecated, use :class:`IterableObj` instead.
1231+
1232+
Find (all) items of this type and collect them into a list.
12131233
1214-
Find all items of this type - subclasses can specify args and kwargs differently.
1215-
If no args are given, subclasses are obliged to return all items if no additional
1216-
arguments arg given.
1234+
For more information about the arguments, see :meth:`list_items`.
12171235
1218-
:note: Favor the iter_items method as it will
1236+
:note: Favor the :meth:`iter_items` method as it will avoid eagerly collecting
1237+
all items. When there are many items, that can slow performance and increase
1238+
memory usage.
12191239
12201240
:return: list(Item,...) list of item instances
12211241
"""
12221242
out_list: Any = IterableList(cls._id_attribute_)
12231243
out_list.extend(cls.iter_items(repo, *args, **kwargs))
12241244
return out_list
12251245

1226-
@classmethod
1227-
def iter_items(cls, repo: "Repo", *args: Any, **kwargs: Any) -> Any:
1228-
# return typed to be compatible with subtypes e.g. Remote
1229-
"""For more information about the arguments, see list_items.
1230-
1231-
:return: Iterator yielding Items
1232-
"""
1233-
raise NotImplementedError("To be implemented by Subclass")
1234-
12351246

12361247
@runtime_checkable
12371248
class IterableObj(Protocol):
@@ -1246,30 +1257,37 @@ class IterableObj(Protocol):
12461257
_id_attribute_: str
12471258

12481259
@classmethod
1249-
def list_items(cls, repo: "Repo", *args: Any, **kwargs: Any) -> IterableList[T_IterableObj]:
1260+
@abstractmethod
1261+
def iter_items(cls, repo: "Repo", *args: Any, **kwargs: Any) -> Iterator[T_IterableObj]:
1262+
# Return-typed to be compatible with subtypes e.g. Remote.
1263+
"""Find (all) items of this type.
1264+
1265+
Subclasses can specify ``args`` and ``kwargs`` differently, and may use them for
1266+
filtering. However, when the method is called with no additional positional or
1267+
keyword arguments, subclasses are obliged to to yield all items.
1268+
1269+
For more information about the arguments, see list_items.
1270+
1271+
:return: Iterator yielding Items
12501272
"""
1251-
Find all items of this type - subclasses can specify args and kwargs differently.
1252-
If no args are given, subclasses are obliged to return all items if no additional
1253-
arguments arg given.
1273+
raise NotImplementedError("To be implemented by Subclass")
1274+
1275+
@classmethod
1276+
def list_items(cls, repo: "Repo", *args: Any, **kwargs: Any) -> IterableList[T_IterableObj]:
1277+
"""Find (all) items of this type and collect them into a list.
1278+
1279+
For more information about the arguments, see :meth:`list_items`.
12541280
1255-
:note: Favor the iter_items method as it will
1281+
:note: Favor the :meth:`iter_items` method as it will avoid eagerly collecting
1282+
all items. When there are many items, that can slow performance and increase
1283+
memory usage.
12561284
12571285
:return: list(Item,...) list of item instances
12581286
"""
12591287
out_list: IterableList = IterableList(cls._id_attribute_)
12601288
out_list.extend(cls.iter_items(repo, *args, **kwargs))
12611289
return out_list
12621290

1263-
@classmethod
1264-
@abstractmethod
1265-
def iter_items(cls, repo: "Repo", *args: Any, **kwargs: Any) -> Iterator[T_IterableObj]: # Iterator[T_IterableObj]:
1266-
# Return-typed to be compatible with subtypes e.g. Remote.
1267-
"""For more information about the arguments, see list_items.
1268-
1269-
:return: Iterator yielding Items
1270-
"""
1271-
raise NotImplementedError("To be implemented by Subclass")
1272-
12731291

12741292
# } END classes
12751293

‎test/test_submodule.py

Copy file name to clipboardExpand all lines: test/test_submodule.py
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,18 @@ def test_root_module(self, rwrepo):
688688
# gitdb: has either 1 or 2 submodules depending on the version.
689689
assert len(nsm.children()) >= 1 and nsmc.module_exists()
690690

691+
def test_iter_items_from_nonexistent_hash(self):
692+
it = Submodule.iter_items(self.rorepo, "b4ecbfaa90c8be6ed6d9fb4e57cc824663ae15b4")
693+
with self.assertRaisesRegex(ValueError, r"\bcould not be resolved\b"):
694+
next(it)
695+
696+
def test_iter_items_from_invalid_hash(self):
697+
"""Check legacy behavaior on BadName (also applies to IOError, i.e. OSError)."""
698+
it = Submodule.iter_items(self.rorepo, "xyz")
699+
with self.assertRaises(StopIteration) as ctx:
700+
next(it)
701+
self.assertIsNone(ctx.exception.value)
702+
691703
@with_rw_repo(k_no_subm_tag, bare=False)
692704
def test_first_submodule(self, rwrepo):
693705
assert len(list(rwrepo.iter_submodules())) == 0

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.