Repository: more-itertools/more-itertools

Issue:
Incomplete annotation for _sample_weighted()
```
diff --git a/more_itertools/more.pyi b/more_itertools/more.pyi
index 66e6938..64166c2 100644
--- a/more_itertools/more.pyi
+++ b/more_itertools/more.pyi
@@ -587,7 +587,7 @@ def _sample_counted(
     population: Iterator[_T], k: int, counts: Iterable[int], strict: bool
 ) -> list[_T]: ...
 def _sample_weighted(
-    iterator: Iterator[_T], k: int, weights, strict
+    iterator: Iterator[_T], k: int, weights: Iterator[float], strict: bool
 ) -> list[_T]: ...
 def sample(
     iterable: Iterable[_T],

```

Hints from issue comments:

Solution patch:
diff --git a/docs/api.rst b/docs/api.rst
index 056ebe7..98188c6 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -328,3 +328,4 @@ Others
 .. autofunction:: tabulate
 .. autofunction:: repeatfunc
 .. autofunction:: reshape
+.. autofunction:: loops
diff --git a/more_itertools/more.pyi b/more_itertools/more.pyi
index 823e386..f8543b4 100644
--- a/more_itertools/more.pyi
+++ b/more_itertools/more.pyi
@@ -587,7 +587,7 @@ def _sample_counted(
     population: Iterator[_T], k: int, counts: Iterable[int], strict: bool
 ) -> list[_T]: ...
 def _sample_weighted(
-    iterator: Iterator[_T], k: int, weights, strict
+    iterator: Iterator[_T], k: int, weights: Iterator[float], strict: bool
 ) -> list[_T]: ...
 def sample(
     iterable: Iterable[_T],
diff --git a/more_itertools/recipes.py b/more_itertools/recipes.py
index 6153414..cf61fc6 100644
--- a/more_itertools/recipes.py
+++ b/more_itertools/recipes.py
@@ -45,6 +45,7 @@ __all__ = [
     'is_prime',
     'iter_except',
     'iter_index',
+    'loops',
     'matmul',
     'ncycles',
     'nth',
@@ -1146,3 +1147,17 @@ def is_prime(n):
     else:
         bases = [randrange(2, n - 1) for i in range(32)]
     return all(_strong_probable_prime(n, base) for base in bases)
+
+
+def loops(n):
+    """Returns an iterable with *n* elements for efficient looping.
+    Like ``range(n)`` but doesn't create integers.
+
+    >>> i = 0
+    >>> for _ in loops(5):
+    ...     i += 1
+    >>> i
+    5
+
+    """
+    return repeat(None, n)
diff --git a/more_itertools/recipes.pyi b/more_itertools/recipes.pyi
index f07ea46..1f73af9 100644
--- a/more_itertools/recipes.pyi
+++ b/more_itertools/recipes.pyi
@@ -137,3 +137,4 @@ def totient(n: int) -> int: ...
 def _shift_to_odd(n: int) -> tuple[int, int]: ...
 def _strong_probable_prime(n: int, base: int) -> bool: ...
 def is_prime(n: int) -> bool: ...
+def loops(n: int) -> Iterator[None]: ...


Test patch:
diff --git a/tests/test_recipes.py b/tests/test_recipes.py
index 0aad5f5..6f8bfaf 100644
--- a/tests/test_recipes.py
+++ b/tests/test_recipes.py
@@ -1370,3 +1370,10 @@ class PrimeFunctionTests(TestCase):
         ):
             with self.subTest(n=n):
                 self.assertTrue(mi.is_prime(n))
+
+
+class LoopsTests(TestCase):
+    def test_basic(self):
+        self.assertTrue(
+            all(list(mi.loops(n)) == [None] * n for n in range(-10, 10))
+        )