summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Turner <9087854+AA-Turner@users.noreply.github.com>2023-04-27 01:27:07 +0100
committerGitHub <noreply@github.com>2023-04-27 01:27:07 +0100
commit973e8fb5cf2664ef70666dfb1c98b8ac67c2224d (patch)
treecd8c8faf1512c48bd6355d7c593f9cf92c9e04a8
parent2a9e805206be7859dea0d222ca9b20a8875d3726 (diff)
downloadsphinx-git-973e8fb5cf2664ef70666dfb1c98b8ac67c2224d.tar.gz
Remove the deprecated ``sphinx.ext.napoleon.iterators`` module (#11364)
-rw-r--r--CHANGES1
-rw-r--r--sphinx/ext/napoleon/iterators.py235
-rw-r--r--tests/test_ext_napoleon_iterators.py358
3 files changed, 1 insertions, 593 deletions
diff --git a/CHANGES b/CHANGES
index 049019b33..81d5adfd7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -13,6 +13,7 @@ Incompatible changes
description classes.
* #11363: Remove the Setuptools integration (``build_sphinx`` hook in
``setup.py``).
+* #11364: Remove deprecated ``sphinx.ext.napoleon.iterators`` module.
Deprecated
----------
diff --git a/sphinx/ext/napoleon/iterators.py b/sphinx/ext/napoleon/iterators.py
deleted file mode 100644
index 2861caa7d..000000000
--- a/sphinx/ext/napoleon/iterators.py
+++ /dev/null
@@ -1,235 +0,0 @@
-"""A collection of helpful iterators."""
-
-from __future__ import annotations
-
-import collections
-import warnings
-from typing import Any, Iterable
-
-from sphinx.deprecation import RemovedInSphinx70Warning
-
-warnings.warn('sphinx.ext.napoleon.iterators is deprecated.',
- RemovedInSphinx70Warning)
-
-
-class peek_iter:
- """An iterator object that supports peeking ahead.
-
- Parameters
- ----------
- o : iterable or callable
- `o` is interpreted very differently depending on the presence of
- `sentinel`.
-
- If `sentinel` is not given, then `o` must be a collection object
- which supports either the iteration protocol or the sequence protocol.
-
- If `sentinel` is given, then `o` must be a callable object.
-
- sentinel : any value, optional
- If given, the iterator will call `o` with no arguments for each
- call to its `next` method; if the value returned is equal to
- `sentinel`, :exc:`StopIteration` will be raised, otherwise the
- value will be returned.
-
- See Also
- --------
- `peek_iter` can operate as a drop in replacement for the built-in
- `iter <https://docs.python.org/3/library/functions.html#iter>`_ function.
-
- Attributes
- ----------
- sentinel
- The value used to indicate the iterator is exhausted. If `sentinel`
- was not given when the `peek_iter` was instantiated, then it will
- be set to a new object instance: ``object()``.
-
- """
- def __init__(self, *args: Any) -> None:
- """__init__(o, sentinel=None)"""
- self._iterable: Iterable = iter(*args)
- self._cache: collections.deque = collections.deque()
- if len(args) == 2:
- self.sentinel = args[1]
- else:
- self.sentinel = object()
-
- def __iter__(self) -> peek_iter:
- return self
-
- def __next__(self, n: int | None = None) -> Any:
- return self.next(n)
-
- def _fillcache(self, n: int | None) -> None:
- """Cache `n` items. If `n` is 0 or None, then 1 item is cached."""
- if not n:
- n = 1
- try:
- while len(self._cache) < n:
- self._cache.append(next(self._iterable)) # type: ignore
- except StopIteration:
- while len(self._cache) < n:
- self._cache.append(self.sentinel)
-
- def has_next(self) -> bool:
- """Determine if iterator is exhausted.
-
- Returns
- -------
- bool
- True if iterator has more items, False otherwise.
-
- Note
- ----
- Will never raise :exc:`StopIteration`.
-
- """
- return self.peek() != self.sentinel
-
- def next(self, n: int | None = None) -> Any:
- """Get the next item or `n` items of the iterator.
-
- Parameters
- ----------
- n : int or None
- The number of items to retrieve. Defaults to None.
-
- Returns
- -------
- item or list of items
- The next item or `n` items of the iterator. If `n` is None, the
- item itself is returned. If `n` is an int, the items will be
- returned in a list. If `n` is 0, an empty list is returned.
-
- Raises
- ------
- StopIteration
- Raised if the iterator is exhausted, even if `n` is 0.
-
- """
- self._fillcache(n)
- if not n:
- if self._cache[0] == self.sentinel:
- raise StopIteration
- if n is None:
- result = self._cache.popleft()
- else:
- result = []
- else:
- if self._cache[n - 1] == self.sentinel:
- raise StopIteration
- result = [self._cache.popleft() for i in range(n)]
- return result
-
- def peek(self, n: int | None = None) -> Any:
- """Preview the next item or `n` items of the iterator.
-
- The iterator is not advanced when peek is called.
-
- Returns
- -------
- item or list of items
- The next item or `n` items of the iterator. If `n` is None, the
- item itself is returned. If `n` is an int, the items will be
- returned in a list. If `n` is 0, an empty list is returned.
-
- If the iterator is exhausted, `peek_iter.sentinel` is returned,
- or placed as the last item in the returned list.
-
- Note
- ----
- Will never raise :exc:`StopIteration`.
-
- """
- self._fillcache(n)
- if n is None:
- result = self._cache[0]
- else:
- result = [self._cache[i] for i in range(n)]
- return result
-
-
-class modify_iter(peek_iter):
- """An iterator object that supports modifying items as they are returned.
-
- Parameters
- ----------
- o : iterable or callable
- `o` is interpreted very differently depending on the presence of
- `sentinel`.
-
- If `sentinel` is not given, then `o` must be a collection object
- which supports either the iteration protocol or the sequence protocol.
-
- If `sentinel` is given, then `o` must be a callable object.
-
- sentinel : any value, optional
- If given, the iterator will call `o` with no arguments for each
- call to its `next` method; if the value returned is equal to
- `sentinel`, :exc:`StopIteration` will be raised, otherwise the
- value will be returned.
-
- modifier : callable, optional
- The function that will be used to modify each item returned by the
- iterator. `modifier` should take a single argument and return a
- single value. Defaults to ``lambda x: x``.
-
- If `sentinel` is not given, `modifier` must be passed as a keyword
- argument.
-
- Attributes
- ----------
- modifier : callable
- `modifier` is called with each item in `o` as it is iterated. The
- return value of `modifier` is returned in lieu of the item.
-
- Values returned by `peek` as well as `next` are affected by
- `modifier`. However, `modify_iter.sentinel` is never passed through
- `modifier`; it will always be returned from `peek` unmodified.
-
- Example
- -------
- >>> a = [" A list ",
- ... " of strings ",
- ... " with ",
- ... " extra ",
- ... " whitespace. "]
- >>> modifier = lambda s: s.strip().replace('with', 'without')
- >>> for s in modify_iter(a, modifier=modifier):
- ... print('"%s"' % s)
- "A list"
- "of strings"
- "without"
- "extra"
- "whitespace."
-
- """
- def __init__(self, *args: Any, **kwargs: Any) -> None:
- """__init__(o, sentinel=None, modifier=lambda x: x)"""
- if 'modifier' in kwargs:
- self.modifier = kwargs['modifier']
- elif len(args) > 2:
- self.modifier = args[2]
- args = args[:2]
- else:
- self.modifier = lambda x: x
- if not callable(self.modifier):
- raise TypeError('modify_iter(o, modifier): '
- 'modifier must be callable')
- super().__init__(*args)
-
- def _fillcache(self, n: int | None) -> None:
- """Cache `n` modified items. If `n` is 0 or None, 1 item is cached.
-
- Each item returned by the iterator is passed through the
- `modify_iter.modified` function before being cached.
-
- """
- if not n:
- n = 1
- try:
- while len(self._cache) < n:
- self._cache.append(self.modifier(next(self._iterable))) # type: ignore
- except StopIteration:
- while len(self._cache) < n:
- self._cache.append(self.sentinel)
diff --git a/tests/test_ext_napoleon_iterators.py b/tests/test_ext_napoleon_iterators.py
deleted file mode 100644
index e7e976ee5..000000000
--- a/tests/test_ext_napoleon_iterators.py
+++ /dev/null
@@ -1,358 +0,0 @@
-"""Tests for :mod:`sphinx.ext.napoleon.iterators` module."""
-
-import sys
-
-import pytest
-
-from sphinx.deprecation import RemovedInSphinx70Warning
-
-with pytest.warns(DeprecationWarning,
- match="sphinx.ext.napoleon.iterators is deprecated."):
- from sphinx.ext.napoleon.iterators import modify_iter, peek_iter
-
-
-class TestModuleIsDeprecated:
- def test_module_is_deprecated(self):
- sys.modules.pop("sphinx.ext.napoleon.iterators")
- with pytest.warns(RemovedInSphinx70Warning,
- match="sphinx.ext.napoleon.iterators is deprecated."):
- import sphinx.ext.napoleon.iterators # noqa: F401
-
-
-def _assert_equal_twice(expected, func, *args):
- assert expected == func(*args)
- assert expected == func(*args)
-
-
-def _assert_false_twice(func, *args):
- assert not func(*args)
- assert not func(*args)
-
-
-def _assert_next(it, expected, is_last):
- _assert_true_twice(it.has_next)
- _assert_equal_twice(expected, it.peek)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(expected, it.peek)
- _assert_true_twice(it.has_next)
- assert expected == next(it)
- if is_last:
- _assert_false_twice(it.has_next)
- _assert_raises_twice(StopIteration, it.next)
- else:
- _assert_true_twice(it.has_next)
-
-
-def _assert_raises_twice(exc, func, *args):
- with pytest.raises(exc):
- func(*args)
- with pytest.raises(exc):
- func(*args)
-
-
-def _assert_true_twice(func, *args):
- assert func(*args)
- assert func(*args)
-
-
-class TestPeekIter:
- def test_init_with_sentinel(self):
- a = iter(['1', '2', 'DONE'])
- sentinel = 'DONE'
- with pytest.raises(TypeError):
- peek_iter(a, sentinel)
-
- def get_next():
- return next(a)
- it = peek_iter(get_next, sentinel)
- assert it.sentinel == sentinel
- _assert_next(it, '1', is_last=False)
- _assert_next(it, '2', is_last=True)
-
- def test_iter(self):
- a = ['1', '2', '3']
- it = peek_iter(a)
- assert it is it.__iter__()
-
- a = []
- b = list(peek_iter(a))
- assert [] == b
-
- a = ['1']
- b = list(peek_iter(a))
- assert ["1"] == b
-
- a = ['1', '2']
- b = list(peek_iter(a))
- assert ["1", "2"] == b
-
- a = ['1', '2', '3']
- b = list(peek_iter(a))
- assert ["1", "2", "3"] == b
-
- def test_next_with_multi(self):
- a = []
- it = peek_iter(a)
- _assert_false_twice(it.has_next)
- _assert_raises_twice(StopIteration, it.next, 2)
-
- a = ['1']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_raises_twice(StopIteration, it.next, 2)
- _assert_true_twice(it.has_next)
-
- a = ['1', '2']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- assert ["1", "2"] == it.next(2)
- _assert_false_twice(it.has_next)
-
- a = ['1', '2', '3']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- assert ["1", "2"] == it.next(2)
- _assert_true_twice(it.has_next)
- _assert_raises_twice(StopIteration, it.next, 2)
- _assert_true_twice(it.has_next)
-
- a = ['1', '2', '3', '4']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- assert ["1", "2"] == it.next(2)
- _assert_true_twice(it.has_next)
- assert ["3", "4"] == it.next(2)
- _assert_false_twice(it.has_next)
- _assert_raises_twice(StopIteration, it.next, 2)
- _assert_false_twice(it.has_next)
-
- def test_next_with_none(self):
- a = []
- it = peek_iter(a)
- _assert_false_twice(it.has_next)
- _assert_raises_twice(StopIteration, it.next)
- _assert_false_twice(it.has_next)
-
- a = ['1']
- it = peek_iter(a)
- assert it.__next__() == "1"
-
- a = ['1']
- it = peek_iter(a)
- _assert_next(it, '1', is_last=True)
-
- a = ['1', '2']
- it = peek_iter(a)
- _assert_next(it, '1', is_last=False)
- _assert_next(it, '2', is_last=True)
-
- a = ['1', '2', '3']
- it = peek_iter(a)
- _assert_next(it, '1', is_last=False)
- _assert_next(it, '2', is_last=False)
- _assert_next(it, '3', is_last=True)
-
- def test_next_with_one(self):
- a = []
- it = peek_iter(a)
- _assert_false_twice(it.has_next)
- _assert_raises_twice(StopIteration, it.next, 1)
-
- a = ['1']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- assert ["1"] == it.next(1)
- _assert_false_twice(it.has_next)
- _assert_raises_twice(StopIteration, it.next, 1)
-
- a = ['1', '2']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- assert ["1"] == it.next(1)
- _assert_true_twice(it.has_next)
- assert ["2"] == it.next(1)
- _assert_false_twice(it.has_next)
- _assert_raises_twice(StopIteration, it.next, 1)
-
- def test_next_with_zero(self):
- a = []
- it = peek_iter(a)
- _assert_false_twice(it.has_next)
- _assert_raises_twice(StopIteration, it.next, 0)
-
- a = ['1']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_equal_twice([], it.next, 0)
- _assert_true_twice(it.has_next)
- _assert_equal_twice([], it.next, 0)
-
- a = ['1', '2']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_equal_twice([], it.next, 0)
- _assert_true_twice(it.has_next)
- _assert_equal_twice([], it.next, 0)
-
- def test_peek_with_multi(self):
- a = []
- it = peek_iter(a)
- _assert_false_twice(it.has_next)
- _assert_equal_twice([it.sentinel, it.sentinel], it.peek, 2)
- _assert_false_twice(it.has_next)
-
- a = ['1']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['1', it.sentinel], it.peek, 2)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['1', it.sentinel, it.sentinel], it.peek, 3)
- _assert_true_twice(it.has_next)
-
- a = ['1', '2']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['1', '2'], it.peek, 2)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['1', '2', it.sentinel], it.peek, 3)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['1', '2', it.sentinel, it.sentinel], it.peek, 4)
- _assert_true_twice(it.has_next)
-
- a = ['1', '2', '3']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['1', '2'], it.peek, 2)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['1', '2', '3'], it.peek, 3)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['1', '2', '3', it.sentinel], it.peek, 4)
- _assert_true_twice(it.has_next)
- assert next(it) == "1"
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['2', '3'], it.peek, 2)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['2', '3', it.sentinel], it.peek, 3)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['2', '3', it.sentinel, it.sentinel], it.peek, 4)
- _assert_true_twice(it.has_next)
-
- def test_peek_with_none(self):
- a = []
- it = peek_iter(a)
- _assert_false_twice(it.has_next)
- _assert_equal_twice(it.sentinel, it.peek)
- _assert_false_twice(it.has_next)
-
- a = ['1']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_equal_twice('1', it.peek)
- assert next(it) == "1"
- _assert_false_twice(it.has_next)
- _assert_equal_twice(it.sentinel, it.peek)
- _assert_false_twice(it.has_next)
-
- a = ['1', '2']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_equal_twice('1', it.peek)
- assert next(it) == "1"
- _assert_true_twice(it.has_next)
- _assert_equal_twice('2', it.peek)
- assert next(it) == "2"
- _assert_false_twice(it.has_next)
- _assert_equal_twice(it.sentinel, it.peek)
- _assert_false_twice(it.has_next)
-
- def test_peek_with_one(self):
- a = []
- it = peek_iter(a)
- _assert_false_twice(it.has_next)
- _assert_equal_twice([it.sentinel], it.peek, 1)
- _assert_false_twice(it.has_next)
-
- a = ['1']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['1'], it.peek, 1)
- assert next(it) == "1"
- _assert_false_twice(it.has_next)
- _assert_equal_twice([it.sentinel], it.peek, 1)
- _assert_false_twice(it.has_next)
-
- a = ['1', '2']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['1'], it.peek, 1)
- assert next(it) == "1"
- _assert_true_twice(it.has_next)
- _assert_equal_twice(['2'], it.peek, 1)
- assert next(it) == "2"
- _assert_false_twice(it.has_next)
- _assert_equal_twice([it.sentinel], it.peek, 1)
- _assert_false_twice(it.has_next)
-
- def test_peek_with_zero(self):
- a = []
- it = peek_iter(a)
- _assert_false_twice(it.has_next)
- _assert_equal_twice([], it.peek, 0)
-
- a = ['1']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_equal_twice([], it.peek, 0)
- _assert_true_twice(it.has_next)
- _assert_equal_twice([], it.peek, 0)
-
- a = ['1', '2']
- it = peek_iter(a)
- _assert_true_twice(it.has_next)
- _assert_equal_twice([], it.peek, 0)
- _assert_true_twice(it.has_next)
- _assert_equal_twice([], it.peek, 0)
-
-
-class TestModifyIter:
- def test_init_with_sentinel_args(self):
- a = iter(['1', '2', '3', 'DONE'])
- sentinel = 'DONE'
-
- def get_next():
- return next(a)
- it = modify_iter(get_next, sentinel, int)
- expected = [1, 2, 3]
- assert expected == list(it)
-
- def test_init_with_sentinel_kwargs(self):
- a = iter([1, 2, 3, 4])
- sentinel = 4
-
- def get_next():
- return next(a)
- it = modify_iter(get_next, sentinel, modifier=str)
- expected = ['1', '2', '3']
- assert expected == list(it)
-
- def test_modifier_default(self):
- a = ['', ' ', ' a ', 'b ', ' c', ' ', '']
- it = modify_iter(a)
- expected = ['', ' ', ' a ', 'b ', ' c', ' ', '']
- assert expected == list(it)
-
- def test_modifier_not_callable(self):
- with pytest.raises(TypeError):
- modify_iter([1], modifier='not_callable')
-
- def test_modifier_rstrip(self):
- a = ['', ' ', ' a ', 'b ', ' c', ' ', '']
- it = modify_iter(a, modifier=lambda s: s.rstrip())
- expected = ['', '', ' a', 'b', ' c', '', '']
- assert expected == list(it)
-
- def test_modifier_rstrip_unicode(self):
- a = ['', ' ', ' a ', 'b ', ' c', ' ', '']
- it = modify_iter(a, modifier=lambda s: s.rstrip())
- expected = ['', '', ' a', 'b', ' c', '', '']
- assert expected == list(it)