Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-tenacity for openSUSE:Factory 
checked in at 2023-06-01 17:19:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-tenacity (Old)
 and      /work/SRC/openSUSE:Factory/.python-tenacity.new.2531 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-tenacity"

Thu Jun  1 17:19:29 2023 rev:19 rq:1090091 version:8.2.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-tenacity/python-tenacity.changes  
2023-05-16 14:27:17.379695052 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-tenacity.new.2531/python-tenacity.changes    
    2023-06-01 17:19:37.590198127 +0200
@@ -1,0 +2,11 @@
+Wed May 31 19:54:37 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 8.2.2:
+  * feat: accept datetime.timedelta instances as argument to `stop_after..
+  * fix: docstring for wait_exponential_jitter 
+  * fix: remove __iter__ from AsyncRetring 
+  * Add retry_if_exception_cause_type and wait_exponential_jitter
+  * better wait.WaitBaseT annotation
+  * CI conversion to GitHub actions 
+
+-------------------------------------------------------------------

Old:
----
  tenacity-8.1.0.tar.gz

New:
----
  tenacity-8.2.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-tenacity.spec ++++++
--- /var/tmp/diff_new_pack.Giz9JJ/_old  2023-06-01 17:19:38.074200996 +0200
+++ /var/tmp/diff_new_pack.Giz9JJ/_new  2023-06-01 17:19:38.078201020 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-tenacity
-Version:        8.1.0
+Version:        8.2.2
 Release:        0
 Summary:        Python module for retrying code until it succeeeds
 License:        Apache-2.0

++++++ tenacity-8.1.0.tar.gz -> tenacity-8.2.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/.circleci/config.yml 
new/tenacity-8.2.2/.circleci/config.yml
--- old/tenacity-8.1.0/.circleci/config.yml     2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/.circleci/config.yml     1970-01-01 01:00:00.000000000 
+0100
@@ -1,98 +0,0 @@
-version: 2
-
-jobs:
-  pep8:
-    docker:
-      - image: circleci/python:3.9
-    steps:
-      - checkout
-      - run:
-          command: |
-            sudo pip install tox
-            tox -e pep8
-  black:
-    docker:
-      - image: circleci/python:3.9
-    steps:
-      - checkout
-      - run:
-          command: |
-            sudo pip install tox
-            tox -e black-ci
-  py36:
-    docker:
-      - image: circleci/python:3.6
-    steps:
-      - checkout
-      - run:
-          command: |
-            sudo pip install tox
-            tox -e py36
-  py37:
-    docker:
-      - image: circleci/python:3.7
-    steps:
-      - checkout
-      - run:
-          command: |
-            sudo pip install tox
-            tox -e py37
-  py38:
-    docker:
-      - image: circleci/python:3.8
-    steps:
-      - checkout
-      - run:
-          command: |
-            sudo pip install tox
-            tox -e py38
-  py39:
-    docker:
-      - image: circleci/python:3.9
-    steps:
-      - checkout
-      - run:
-          command: |
-            sudo pip install tox
-            tox -e py39
-  deploy:
-    docker:
-      - image: circleci/python:3.9
-    steps:
-      - checkout
-      - run: |
-          python -m venv venv
-      - run: |
-          venv/bin/pip install twine wheel
-      - run:
-          name: init .pypirc
-          command: |
-            echo -e "[pypi]" >> ~/.pypirc
-            echo -e "username = __token__" >> ~/.pypirc
-            echo -e "password = $PYPI_TOKEN" >> ~/.pypirc
-      - run:
-          name: create packages
-          command: |
-            venv/bin/python setup.py sdist bdist_wheel
-      - run:
-          name: upload to PyPI
-          command: |
-            venv/bin/twine upload dist/*
-
-workflows:
-  version: 2
-
-  test:
-    jobs:
-      - pep8
-      - black
-      - py36
-      - py37
-      - py38
-      - py39
-      - deploy:
-          filters:
-            tags:
-              only: /[0-9]+(\.[0-9]+)*/
-            branches:
-              ignore: /.*/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/.github/workflows/ci.yaml 
new/tenacity-8.2.2/.github/workflows/ci.yaml
--- old/tenacity-8.1.0/.github/workflows/ci.yaml        1970-01-01 
01:00:00.000000000 +0100
+++ new/tenacity-8.2.2/.github/workflows/ci.yaml        2023-02-28 
15:21:48.000000000 +0100
@@ -0,0 +1,53 @@
+name: Continuous Integration
+permissions: read-all
+
+on:
+  pull_request:
+    branches:
+      - main
+
+concurrency:
+  # yamllint disable-line rule:line-length
+  group: "${{ github.workflow }}-${{ github.head_ref || github.run_id }}"
+  cancel-in-progress: true
+
+jobs:
+  test:
+    timeout-minutes: 20
+    runs-on: ubuntu-20.04
+    strategy:
+      matrix:
+        include:
+          - python: "3.6"
+            tox: py36
+          - python: "3.7"
+            tox: py37
+          - python: "3.8"
+            tox: py38
+          - python: "3.9"
+            tox: py39
+          - python: "3.10"
+            tox: py310
+          - python: "3.11"
+            tox: py311
+          - python: "3.11"
+            tox: pep8
+          - python: "3.11"
+            tox: black-ci
+          - python: "3.11"
+            tox: mypy
+    steps:
+      - name: Checkout 🛎️
+        uses: actions/checkout@v3.3.0
+        with:
+          fetch-depth: 0
+
+      - name: Setup Python 🔧
+        uses: actions/setup-python@v4.5.0
+        with:
+          python-version: ${{ matrix.python }}
+
+      - name: Build 🔧 & Test 🔍
+        run: |
+          pip install tox
+          tox -e ${{ matrix.tox }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/.github/workflows/deploy.yaml 
new/tenacity-8.2.2/.github/workflows/deploy.yaml
--- old/tenacity-8.1.0/.github/workflows/deploy.yaml    1970-01-01 
01:00:00.000000000 +0100
+++ new/tenacity-8.2.2/.github/workflows/deploy.yaml    2023-02-28 
15:21:48.000000000 +0100
@@ -0,0 +1,33 @@
+name: Release deploy
+
+on:
+  push:
+    tags:
+
+jobs:
+  test:
+    timeout-minutes: 20
+    runs-on: ubuntu-20.04
+    steps:
+      - name: Checkout 🛎️
+        uses: actions/checkout@v3.3.0
+        with:
+          fetch-depth: 0
+
+      - name: Setup Python 🔧
+        uses: actions/setup-python@v4.5.0
+        with:
+          python-version: 3.11
+
+      - name: Build 🔧 & Deploy 🚀
+        env:
+          PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
+        run: |
+          pip install tox twine wheel
+
+          echo -e "[pypi]" >> ~/.pypirc
+          echo -e "username = __token__" >> ~/.pypirc
+          echo -e "password = $PYPI_TOKEN" >> ~/.pypirc
+
+          python setup.py sdist bdist_wheel
+          twine upload dist/*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/.mergify.yml 
new/tenacity-8.2.2/.mergify.yml
--- old/tenacity-8.1.0/.mergify.yml     2022-09-21 14:23:59.000000000 +0200
+++ new/tenacity-8.2.2/.mergify.yml     2023-02-28 15:21:48.000000000 +0100
@@ -1,12 +1,15 @@
 queue_rules:
   - name: default
-    conditions:
-      - "status-success=ci/circleci: pep8"
-      - "status-success=ci/circleci: black"
-      - "status-success=ci/circleci: py36"
-      - "status-success=ci/circleci: py37"
-      - "status-success=ci/circleci: py38"
-      - "status-success=ci/circleci: py39"
+    conditions: &CheckRuns
+      - "check-success=test (3.6, py36)"
+      - "check-success=test (3.7, py37)"
+      - "check-success=test (3.8, py38)"
+      - "check-success=test (3.9, py39)"
+      - "check-success=test (3.10, py310)"
+      - "check-success=test (3.11, py311)"
+      - "check-success=test (3.11, black-ci)"
+      - "check-success=test (3.11, pep8)"
+      - "check-success=test (3.11, mypy)"
 
 pull_request_rules:
   - name: warn on no changelog
@@ -22,12 +25,7 @@
           a changelog entry.
   - name: automatic merge without changelog
     conditions:
-      - "status-success=ci/circleci: pep8"
-      - "status-success=ci/circleci: black"
-      - "status-success=ci/circleci: py36"
-      - "status-success=ci/circleci: py37"
-      - "status-success=ci/circleci: py38"
-      - "status-success=ci/circleci: py39"
+      - and: *CheckRuns
       - "#approved-reviews-by>=1"
       - label=no-changelog
     actions:
@@ -36,12 +34,7 @@
         method: squash
   - name: automatic merge with changelog
     conditions:
-      - "status-success=ci/circleci: pep8"
-      - "status-success=ci/circleci: black"
-      - "status-success=ci/circleci: py36"
-      - "status-success=ci/circleci: py37"
-      - "status-success=ci/circleci: py38"
-      - "status-success=ci/circleci: py39"
+      - and: *CheckRuns
       - "#approved-reviews-by>=1"
       - files~=^releasenotes/notes/
     actions:
@@ -51,12 +44,7 @@
   - name: automatic merge for jd without changelog
     conditions:
       - author=jd
-      - "status-success=ci/circleci: pep8"
-      - "status-success=ci/circleci: black"
-      - "status-success=ci/circleci: py36"
-      - "status-success=ci/circleci: py37"
-      - "status-success=ci/circleci: py38"
-      - "status-success=ci/circleci: py39"
+      - and: *CheckRuns
       - label=no-changelog
     actions:
       queue:
@@ -65,12 +53,7 @@
   - name: automatic merge for jd with changelog
     conditions:
       - author=jd
-      - "status-success=ci/circleci: pep8"
-      - "status-success=ci/circleci: black"
-      - "status-success=ci/circleci: py36"
-      - "status-success=ci/circleci: py37"
-      - "status-success=ci/circleci: py38"
-      - "status-success=ci/circleci: py39"
+      - and: *CheckRuns
       - files~=^releasenotes/notes/
     actions:
       queue:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/PKG-INFO new/tenacity-8.2.2/PKG-INFO
--- old/tenacity-8.1.0/PKG-INFO 2022-09-21 14:24:11.075567200 +0200
+++ new/tenacity-8.2.2/PKG-INFO 2023-02-28 15:22:05.633156000 +0100
@@ -1,12 +1,11 @@
 Metadata-Version: 2.1
 Name: tenacity
-Version: 8.1.0
+Version: 8.2.2
 Summary: Retry code until it succeeds
 Home-page: https://github.com/jd/tenacity
 Author: Julien Danjou
 Author-email: jul...@danjou.info
 License: Apache 2.0
-Platform: UNKNOWN
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: Apache Software License
 Classifier: Programming Language :: Python
@@ -17,10 +16,10 @@
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
 Classifier: Topic :: Utilities
 Requires-Python: >=3.6
 Provides-Extra: doc
 License-File: LICENSE
 
 Tenacity is a general-purpose retrying library to simplify the task of adding 
retry behavior to just about anything.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/README.rst 
new/tenacity-8.2.2/README.rst
--- old/tenacity-8.1.0/README.rst       2022-09-21 14:23:59.000000000 +0200
+++ new/tenacity-8.2.2/README.rst       2023-02-28 15:21:48.000000000 +0100
@@ -6,7 +6,7 @@
 .. image:: https://circleci.com/gh/jd/tenacity.svg?style=svg
     :target: https://circleci.com/gh/jd/tenacity
 
-.. image:: 
https://img.shields.io/endpoint.svg?url=https://dashboard.mergify.io/badges/jd/tenacity&style=flat
+.. image:: 
https://img.shields.io/endpoint.svg?url=https://api.mergify.com/badges/jd/tenacity&style=flat
    :target: https://mergify.io
    :alt: Mergify Status
 
@@ -274,8 +274,12 @@
 Error Handling
 ~~~~~~~~~~~~~~
 
-While callables that "timeout" retrying raise a `RetryError` by default,
-we can reraise the last attempt's exception if needed:
+Normally when your function fails its final time (and will not be retried 
again based on your settings),
+a `RetryError` is raised. The exception your code encountered will be shown 
somewhere in the *middle*
+of the stack trace.
+
+If you would rather see the exception your code encountered at the *end* of 
the stack trace (where it
+is most visible), you can set `reraise=True`.
 
 .. testcode::
 
@@ -298,6 +302,7 @@
 .. testcode::
 
     import logging
+    import sys
 
     logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
 
@@ -312,6 +317,7 @@
 .. testcode::
 
     import logging
+    import sys
 
     logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
 
@@ -328,6 +334,7 @@
 .. testcode::
 
     import logging
+    import sys
 
     logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
 
@@ -566,6 +573,22 @@
       except RetryError:
           pass
 
+In both cases, you may want to set the result to the attempt so it's available
+in retry strategies like ``retry_if_result``. This can be done accessing the
+``retry_state`` property:
+
+.. testcode::
+
+    from tenacity import AsyncRetrying, retry_if_result
+
+    async def function():
+       async for attempt in AsyncRetrying(retry=retry_if_result(lambda x: x < 
3)):
+           with attempt:
+               result = 1  # Some complex calculation, function call, etc.
+           if not attempt.retry_state.outcome.failed:
+               attempt.retry_state.set_result(result)
+       return result
+
 Async and retry
 ~~~~~~~~~~~~~~~
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/doc/source/index.rst 
new/tenacity-8.2.2/doc/source/index.rst
--- old/tenacity-8.1.0/doc/source/index.rst     2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/doc/source/index.rst     2023-02-28 15:21:48.000000000 
+0100
@@ -6,7 +6,7 @@
 .. image:: https://circleci.com/gh/jd/tenacity.svg?style=svg
     :target: https://circleci.com/gh/jd/tenacity
 
-.. image:: 
https://img.shields.io/endpoint.svg?url=https://dashboard.mergify.io/badges/jd/tenacity&style=flat
+.. image:: 
https://img.shields.io/endpoint.svg?url=https://api.mergify.com/badges/jd/tenacity&style=flat
    :target: https://mergify.io
    :alt: Mergify Status
 
@@ -274,8 +274,12 @@
 Error Handling
 ~~~~~~~~~~~~~~
 
-While callables that "timeout" retrying raise a `RetryError` by default,
-we can reraise the last attempt's exception if needed:
+Normally when your function fails its final time (and will not be retried 
again based on your settings),
+a `RetryError` is raised. The exception your code encountered will be shown 
somewhere in the *middle*
+of the stack trace.
+
+If you would rather see the exception your code encountered at the *end* of 
the stack trace (where it
+is most visible), you can set `reraise=True`.
 
 .. testcode::
 
@@ -298,6 +302,7 @@
 .. testcode::
 
     import logging
+    import sys
 
     logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
 
@@ -312,6 +317,7 @@
 .. testcode::
 
     import logging
+    import sys
 
     logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
 
@@ -328,6 +334,7 @@
 .. testcode::
 
     import logging
+    import sys
 
     logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
 
@@ -566,6 +573,22 @@
       except RetryError:
           pass
 
+In both cases, you may want to set the result to the attempt so it's available
+in retry strategies like ``retry_if_result``. This can be done accessing the
+``retry_state`` property:
+
+.. testcode::
+
+    from tenacity import AsyncRetrying, retry_if_result
+
+    async def function():
+       async for attempt in AsyncRetrying(retry=retry_if_result(lambda x: x < 
3)):
+           with attempt:
+               result = 1  # Some complex calculation, function call, etc.
+           if not attempt.retry_state.outcome.failed:
+               attempt.retry_state.set_result(result)
+       return result
+
 Async and retry
 ~~~~~~~~~~~~~~~
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/pyproject.toml 
new/tenacity-8.2.2/pyproject.toml
--- old/tenacity-8.1.0/pyproject.toml   2022-09-21 14:23:59.000000000 +0200
+++ new/tenacity-8.2.2/pyproject.toml   2023-02-28 15:21:48.000000000 +0100
@@ -11,6 +11,15 @@
 [tool.black]
 line-length = 120
 safe = true
-target-version = ["py36", "py37", "py38", "py39"]
+target-version = ["py36", "py37", "py38", "py39", "py310", "py311"]
+
+[tool.mypy]
+strict = true
+files = ["tenacity"]
+show_error_codes = true
+
+[[tool.mypy.overrides]]
+module = "tornado.*"
+ignore_missing_imports = true
 
 [tool.setuptools_scm]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tenacity-8.1.0/releasenotes/notes/add_omitted_modules_to_import_all-2ab282f20a2c22f7.yaml
 
new/tenacity-8.2.2/releasenotes/notes/add_omitted_modules_to_import_all-2ab282f20a2c22f7.yaml
--- 
old/tenacity-8.1.0/releasenotes/notes/add_omitted_modules_to_import_all-2ab282f20a2c22f7.yaml
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/tenacity-8.2.2/releasenotes/notes/add_omitted_modules_to_import_all-2ab282f20a2c22f7.yaml
       2023-02-28 15:21:48.000000000 +0100
@@ -0,0 +1,3 @@
+---
+other:
+  - Add `retry_if_exception_cause_type`and `wait_exponential_jitter` to 
__all__ of init.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tenacity-8.1.0/releasenotes/notes/clarify-reraise-option-6829667eacf4f599.yaml
 
new/tenacity-8.2.2/releasenotes/notes/clarify-reraise-option-6829667eacf4f599.yaml
--- 
old/tenacity-8.1.0/releasenotes/notes/clarify-reraise-option-6829667eacf4f599.yaml
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/tenacity-8.2.2/releasenotes/notes/clarify-reraise-option-6829667eacf4f599.yaml
  2023-02-28 15:21:48.000000000 +0100
@@ -0,0 +1,3 @@
+---
+prelude: >
+    Clarify usage of `reraise` keyword argument
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tenacity-8.1.0/releasenotes/notes/export-convenience-symbols-981d9611c8b754f3.yaml
 
new/tenacity-8.2.2/releasenotes/notes/export-convenience-symbols-981d9611c8b754f3.yaml
--- 
old/tenacity-8.1.0/releasenotes/notes/export-convenience-symbols-981d9611c8b754f3.yaml
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/tenacity-8.2.2/releasenotes/notes/export-convenience-symbols-981d9611c8b754f3.yaml
      2023-02-28 15:21:48.000000000 +0100
@@ -0,0 +1,3 @@
+---
+features:
+  - Explicitly export convenience symbols from tenacity root module
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tenacity-8.1.0/releasenotes/notes/fix-async-loop-with-result-f68e913ccb425aca.yaml
 
new/tenacity-8.2.2/releasenotes/notes/fix-async-loop-with-result-f68e913ccb425aca.yaml
--- 
old/tenacity-8.1.0/releasenotes/notes/fix-async-loop-with-result-f68e913ccb425aca.yaml
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/tenacity-8.2.2/releasenotes/notes/fix-async-loop-with-result-f68e913ccb425aca.yaml
      2023-02-28 15:21:48.000000000 +0100
@@ -0,0 +1,4 @@
+---
+fixes:
+  - |
+    Fix async loop with retrying code block when result is available.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tenacity-8.1.0/releasenotes/notes/fix-wait-typing-b26eecdb6cc0a1de.yaml 
new/tenacity-8.2.2/releasenotes/notes/fix-wait-typing-b26eecdb6cc0a1de.yaml
--- old/tenacity-8.1.0/releasenotes/notes/fix-wait-typing-b26eecdb6cc0a1de.yaml 
1970-01-01 01:00:00.000000000 +0100
+++ new/tenacity-8.2.2/releasenotes/notes/fix-wait-typing-b26eecdb6cc0a1de.yaml 
2023-02-28 15:21:48.000000000 +0100
@@ -0,0 +1,5 @@
+---
+fixes:
+  - |
+    Argument `wait` was improperly annotated, making mypy checks fail.
+    Now it's annotated as `typing.Union[wait_base, 
typing.Callable[["RetryCallState"], typing.Union[float, int]]]`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tenacity-8.1.0/releasenotes/notes/no-async-iter-6132a42e52348a75.yaml 
new/tenacity-8.2.2/releasenotes/notes/no-async-iter-6132a42e52348a75.yaml
--- old/tenacity-8.1.0/releasenotes/notes/no-async-iter-6132a42e52348a75.yaml   
1970-01-01 01:00:00.000000000 +0100
+++ new/tenacity-8.2.2/releasenotes/notes/no-async-iter-6132a42e52348a75.yaml   
2023-02-28 15:21:48.000000000 +0100
@@ -0,0 +1,7 @@
+---
+fixes:
+  - |
+    `AsyncRetrying` was erroneously implementing `__iter__()`, making tenacity
+    retrying mechanism working but in a synchronous fashion and not waiting as
+    expected. This interface has been removed, `__aiter__()` should be used
+    instead.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tenacity-8.1.0/releasenotes/notes/timedelta-for-stop-ef6bf71b88ce9988.yaml 
new/tenacity-8.2.2/releasenotes/notes/timedelta-for-stop-ef6bf71b88ce9988.yaml
--- 
old/tenacity-8.1.0/releasenotes/notes/timedelta-for-stop-ef6bf71b88ce9988.yaml  
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/tenacity-8.2.2/releasenotes/notes/timedelta-for-stop-ef6bf71b88ce9988.yaml  
    2023-02-28 15:21:48.000000000 +0100
@@ -0,0 +1,4 @@
+---
+features:
+  - |
+    - accept ``datetime.timedelta`` instances as argument to 
``tenacity.stop.stop_after_delay``
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/setup.cfg new/tenacity-8.2.2/setup.cfg
--- old/tenacity-8.1.0/setup.cfg        2022-09-21 14:24:11.075567200 +0200
+++ new/tenacity-8.2.2/setup.cfg        2023-02-28 15:22:05.637156000 +0100
@@ -18,6 +18,7 @@
        Programming Language :: Python :: 3.8
        Programming Language :: Python :: 3.9
        Programming Language :: Python :: 3.10
+       Programming Language :: Python :: 3.11
        Topic :: Utilities
 
 [options]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity/__init__.py 
new/tenacity-8.2.2/tenacity/__init__.py
--- old/tenacity-8.1.0/tenacity/__init__.py     2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/tenacity/__init__.py     2023-02-28 15:21:48.000000000 
+0100
@@ -16,6 +16,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+
 import functools
 import sys
 import threading
@@ -79,58 +80,20 @@
 from .before_sleep import before_sleep_nothing  # noqa
 
 try:
-    import tornado  # type: ignore
+    import tornado
 except ImportError:
-    tornado = None  # type: ignore
+    tornado = None
 
 if t.TYPE_CHECKING:
     import types
 
-    from .wait import wait_base
-    from .stop import stop_base
-
-
-WrappedFn = t.TypeVar("WrappedFn", bound=t.Callable)
-_RetValT = t.TypeVar("_RetValT")
-
-
-@t.overload
-def retry(fn: WrappedFn) -> WrappedFn:
-    pass
-
-
-@t.overload
-def retry(*dargs: t.Any, **dkw: t.Any) -> t.Callable[[WrappedFn], WrappedFn]:  
# noqa
-    pass
+    from .retry import RetryBaseT
+    from .stop import StopBaseT
+    from .wait import WaitBaseT
 
 
-def retry(*dargs: t.Any, **dkw: t.Any) -> t.Union[WrappedFn, 
t.Callable[[WrappedFn], WrappedFn]]:  # noqa
-    """Wrap a function with a new `Retrying` object.
-
-    :param dargs: positional arguments passed to Retrying object
-    :param dkw: keyword arguments passed to the Retrying object
-    """
-    # support both @retry and @retry() as valid syntax
-    if len(dargs) == 1 and callable(dargs[0]):
-        return retry()(dargs[0])
-    else:
-
-        def wrap(f: WrappedFn) -> WrappedFn:
-            if isinstance(f, retry_base):
-                warnings.warn(
-                    f"Got retry_base instance ({f.__class__.__name__}) as 
callable argument, "
-                    f"this will probably hang indefinitely (did you mean 
retry={f.__class__.__name__}(...)?)"
-                )
-            if iscoroutinefunction(f):
-                r: "BaseRetrying" = AsyncRetrying(*dargs, **dkw)
-            elif tornado and hasattr(tornado.gen, "is_coroutine_function") and 
tornado.gen.is_coroutine_function(f):
-                r = TornadoRetrying(*dargs, **dkw)
-            else:
-                r = Retrying(*dargs, **dkw)
-
-            return r.wraps(f)
-
-        return wrap
+WrappedFnReturnT = t.TypeVar("WrappedFnReturnT")
+WrappedFn = t.TypeVar("WrappedFn", bound=t.Callable[..., t.Any])
 
 
 class TryAgain(Exception):
@@ -214,7 +177,7 @@
         exc_value: t.Optional[BaseException],
         traceback: t.Optional["types.TracebackType"],
     ) -> t.Optional[bool]:
-        if isinstance(exc_value, BaseException):
+        if exc_type is not None and exc_value is not None:
             self.retry_state.set_exception((exc_type, exc_value, traceback))
             return True  # Swallow exception.
         else:
@@ -227,9 +190,9 @@
     def __init__(
         self,
         sleep: t.Callable[[t.Union[int, float]], None] = sleep,
-        stop: "stop_base" = stop_never,
-        wait: "wait_base" = wait_none(),
-        retry: retry_base = retry_if_exception_type(),
+        stop: "StopBaseT" = stop_never,
+        wait: "WaitBaseT" = wait_none(),
+        retry: "RetryBaseT" = retry_if_exception_type(),
         before: t.Callable[["RetryCallState"], None] = before_nothing,
         after: t.Callable[["RetryCallState"], None] = after_nothing,
         before_sleep: t.Optional[t.Callable[["RetryCallState"], None]] = None,
@@ -252,8 +215,8 @@
     def copy(
         self,
         sleep: t.Union[t.Callable[[t.Union[int, float]], None], object] = 
_unset,
-        stop: t.Union["stop_base", object] = _unset,
-        wait: t.Union["wait_base", object] = _unset,
+        stop: t.Union["StopBaseT", object] = _unset,
+        wait: t.Union["WaitBaseT", object] = _unset,
         retry: t.Union[retry_base, object] = _unset,
         before: t.Union[t.Callable[["RetryCallState"], None], object] = _unset,
         after: t.Union[t.Callable[["RetryCallState"], None], object] = _unset,
@@ -310,9 +273,9 @@
                   statistics from each thread).
         """
         try:
-            return self._local.statistics
+            return self._local.statistics  # type: ignore[no-any-return]
         except AttributeError:
-            self._local.statistics = {}
+            self._local.statistics = t.cast(t.Dict[str, t.Any], {})
             return self._local.statistics
 
     def wraps(self, f: WrappedFn) -> WrappedFn:
@@ -328,10 +291,10 @@
         def retry_with(*args: t.Any, **kwargs: t.Any) -> WrappedFn:
             return self.copy(*args, **kwargs).wraps(f)
 
-        wrapped_f.retry = self
-        wrapped_f.retry_with = retry_with
+        wrapped_f.retry = self  # type: ignore[attr-defined]
+        wrapped_f.retry_with = retry_with  # type: ignore[attr-defined]
 
-        return wrapped_f
+        return wrapped_f  # type: ignore[return-value]
 
     def begin(self) -> None:
         self.statistics.clear()
@@ -346,15 +309,15 @@
                 self.before(retry_state)
             return DoAttempt()
 
-        is_explicit_retry = retry_state.outcome.failed and 
isinstance(retry_state.outcome.exception(), TryAgain)
-        if not (is_explicit_retry or self.retry(retry_state=retry_state)):
+        is_explicit_retry = fut.failed and isinstance(fut.exception(), 
TryAgain)
+        if not (is_explicit_retry or self.retry(retry_state)):
             return fut.result()
 
         if self.after is not None:
             self.after(retry_state)
 
         self.statistics["delay_since_first_attempt"] = 
retry_state.seconds_since_start
-        if self.stop(retry_state=retry_state):
+        if self.stop(retry_state):
             if self.retry_error_callback:
                 return self.retry_error_callback(retry_state)
             retry_exc = self.retry_error_cls(fut)
@@ -363,7 +326,7 @@
             raise retry_exc from fut.exception()
 
         if self.wait:
-            sleep = self.wait(retry_state=retry_state)
+            sleep = self.wait(retry_state)
         else:
             sleep = 0.0
         retry_state.next_action = RetryAction(sleep)
@@ -391,14 +354,24 @@
                 break
 
     @abstractmethod
-    def __call__(self, fn: t.Callable[..., _RetValT], *args: t.Any, **kwargs: 
t.Any) -> _RetValT:
+    def __call__(
+        self,
+        fn: t.Callable[..., WrappedFnReturnT],
+        *args: t.Any,
+        **kwargs: t.Any,
+    ) -> WrappedFnReturnT:
         pass
 
 
 class Retrying(BaseRetrying):
     """Retrying controller."""
 
-    def __call__(self, fn: t.Callable[..., _RetValT], *args: t.Any, **kwargs: 
t.Any) -> _RetValT:
+    def __call__(
+        self,
+        fn: t.Callable[..., WrappedFnReturnT],
+        *args: t.Any,
+        **kwargs: t.Any,
+    ) -> WrappedFnReturnT:
         self.begin()
 
         retry_state = RetryCallState(retry_object=self, fn=fn, args=args, 
kwargs=kwargs)
@@ -408,17 +381,23 @@
                 try:
                     result = fn(*args, **kwargs)
                 except BaseException:  # noqa: B902
-                    retry_state.set_exception(sys.exc_info())
+                    retry_state.set_exception(sys.exc_info())  # type: 
ignore[arg-type]
                 else:
                     retry_state.set_result(result)
             elif isinstance(do, DoSleep):
                 retry_state.prepare_for_next_attempt()
                 self.sleep(do)
             else:
-                return do
+                return do  # type: ignore[no-any-return]
 
 
-class Future(futures.Future):
+if sys.version_info[1] >= 9:
+    FutureGenericT = futures.Future[t.Any]
+else:
+    FutureGenericT = futures.Future
+
+
+class Future(FutureGenericT):
     """Encapsulates a (future or past) attempted call to a target function."""
 
     def __init__(self, attempt_number: int) -> None:
@@ -491,13 +470,15 @@
         fut.set_result(val)
         self.outcome, self.outcome_timestamp = fut, ts
 
-    def set_exception(self, exc_info: t.Tuple[t.Type[BaseException], 
BaseException, "types.TracebackType"]) -> None:
+    def set_exception(
+        self, exc_info: t.Tuple[t.Type[BaseException], BaseException, 
"types.TracebackType| None"]
+    ) -> None:
         ts = time.monotonic()
         fut = Future(self.attempt_number)
         fut.set_exception(exc_info[1])
         self.outcome, self.outcome_timestamp = fut, ts
 
-    def __repr__(self):
+    def __repr__(self) -> str:
         if self.outcome is None:
             result = "none yet"
         elif self.outcome.failed:
@@ -511,7 +492,115 @@
         return f"<{clsname} {id(self)}: attempt #{self.attempt_number}; slept 
for {slept}; last result: {result}>"
 
 
+@t.overload
+def retry(func: WrappedFn) -> WrappedFn:
+    ...
+
+
+@t.overload
+def retry(
+    sleep: t.Callable[[t.Union[int, float]], None] = sleep,
+    stop: "StopBaseT" = stop_never,
+    wait: "WaitBaseT" = wait_none(),
+    retry: "RetryBaseT" = retry_if_exception_type(),
+    before: t.Callable[["RetryCallState"], None] = before_nothing,
+    after: t.Callable[["RetryCallState"], None] = after_nothing,
+    before_sleep: t.Optional[t.Callable[["RetryCallState"], None]] = None,
+    reraise: bool = False,
+    retry_error_cls: t.Type["RetryError"] = RetryError,
+    retry_error_callback: t.Optional[t.Callable[["RetryCallState"], t.Any]] = 
None,
+) -> t.Callable[[WrappedFn], WrappedFn]:
+    ...
+
+
+def retry(*dargs: t.Any, **dkw: t.Any) -> t.Any:
+    """Wrap a function with a new `Retrying` object.
+
+    :param dargs: positional arguments passed to Retrying object
+    :param dkw: keyword arguments passed to the Retrying object
+    """
+    # support both @retry and @retry() as valid syntax
+    if len(dargs) == 1 and callable(dargs[0]):
+        return retry()(dargs[0])
+    else:
+
+        def wrap(f: WrappedFn) -> WrappedFn:
+            if isinstance(f, retry_base):
+                warnings.warn(
+                    f"Got retry_base instance ({f.__class__.__name__}) as 
callable argument, "
+                    f"this will probably hang indefinitely (did you mean 
retry={f.__class__.__name__}(...)?)"
+                )
+            r: "BaseRetrying"
+            if iscoroutinefunction(f):
+                r = AsyncRetrying(*dargs, **dkw)
+            elif tornado and hasattr(tornado.gen, "is_coroutine_function") and 
tornado.gen.is_coroutine_function(f):
+                r = TornadoRetrying(*dargs, **dkw)
+            else:
+                r = Retrying(*dargs, **dkw)
+
+            return r.wraps(f)
+
+        return wrap
+
+
 from tenacity._asyncio import AsyncRetrying  # noqa:E402,I100
 
 if tornado:
     from tenacity.tornadoweb import TornadoRetrying
+
+
+__all__ = [
+    "retry_base",
+    "retry_all",
+    "retry_always",
+    "retry_any",
+    "retry_if_exception",
+    "retry_if_exception_type",
+    "retry_if_exception_cause_type",
+    "retry_if_not_exception_type",
+    "retry_if_not_result",
+    "retry_if_result",
+    "retry_never",
+    "retry_unless_exception_type",
+    "retry_if_exception_message",
+    "retry_if_not_exception_message",
+    "sleep",
+    "sleep_using_event",
+    "stop_after_attempt",
+    "stop_after_delay",
+    "stop_all",
+    "stop_any",
+    "stop_never",
+    "stop_when_event_set",
+    "wait_chain",
+    "wait_combine",
+    "wait_exponential",
+    "wait_fixed",
+    "wait_incrementing",
+    "wait_none",
+    "wait_random",
+    "wait_random_exponential",
+    "wait_full_jitter",
+    "wait_exponential_jitter",
+    "before_log",
+    "before_nothing",
+    "after_log",
+    "after_nothing",
+    "before_sleep_log",
+    "before_sleep_nothing",
+    "retry",
+    "WrappedFn",
+    "TryAgain",
+    "NO_RESULT",
+    "DoAttempt",
+    "DoSleep",
+    "BaseAction",
+    "RetryAction",
+    "RetryError",
+    "AttemptManager",
+    "BaseRetrying",
+    "Retrying",
+    "Future",
+    "RetryCallState",
+    "AsyncRetrying",
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity/_asyncio.py 
new/tenacity-8.2.2/tenacity/_asyncio.py
--- old/tenacity-8.1.0/tenacity/_asyncio.py     2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/tenacity/_asyncio.py     2023-02-28 15:21:48.000000000 
+0100
@@ -17,7 +17,7 @@
 
 import functools
 import sys
-import typing
+import typing as t
 from asyncio import sleep
 
 from tenacity import AttemptManager
@@ -26,21 +26,20 @@
 from tenacity import DoSleep
 from tenacity import RetryCallState
 
-WrappedFn = typing.TypeVar("WrappedFn", bound=typing.Callable)
-_RetValT = typing.TypeVar("_RetValT")
+WrappedFnReturnT = t.TypeVar("WrappedFnReturnT")
+WrappedFn = t.TypeVar("WrappedFn", bound=t.Callable[..., t.Awaitable[t.Any]])
 
 
 class AsyncRetrying(BaseRetrying):
-    def __init__(self, sleep: typing.Callable[[float], typing.Awaitable] = 
sleep, **kwargs: typing.Any) -> None:
+    sleep: t.Callable[[float], t.Awaitable[t.Any]]
+
+    def __init__(self, sleep: t.Callable[[float], t.Awaitable[t.Any]] = sleep, 
**kwargs: t.Any) -> None:
         super().__init__(**kwargs)
         self.sleep = sleep
 
-    async def __call__(  # type: ignore  # Change signature from supertype
-        self,
-        fn: typing.Callable[..., typing.Awaitable[_RetValT]],
-        *args: typing.Any,
-        **kwargs: typing.Any,
-    ) -> _RetValT:
+    async def __call__(  # type: ignore[override]
+        self, fn: WrappedFn, *args: t.Any, **kwargs: t.Any
+    ) -> WrappedFnReturnT:
         self.begin()
 
         retry_state = RetryCallState(retry_object=self, fn=fn, args=args, 
kwargs=kwargs)
@@ -50,21 +49,24 @@
                 try:
                     result = await fn(*args, **kwargs)
                 except BaseException:  # noqa: B902
-                    retry_state.set_exception(sys.exc_info())
+                    retry_state.set_exception(sys.exc_info())  # type: 
ignore[arg-type]
                 else:
                     retry_state.set_result(result)
             elif isinstance(do, DoSleep):
                 retry_state.prepare_for_next_attempt()
                 await self.sleep(do)
             else:
-                return do
+                return do  # type: ignore[no-any-return]
+
+    def __iter__(self) -> t.Generator[AttemptManager, None, None]:
+        raise TypeError("AsyncRetrying object is not iterable")
 
     def __aiter__(self) -> "AsyncRetrying":
         self.begin()
         self._retry_state = RetryCallState(self, fn=None, args=(), kwargs={})
         return self
 
-    async def __anext__(self) -> typing.Union[AttemptManager, typing.Any]:
+    async def __anext__(self) -> AttemptManager:
         while True:
             do = self.iter(retry_state=self._retry_state)
             if do is None:
@@ -75,18 +77,18 @@
                 self._retry_state.prepare_for_next_attempt()
                 await self.sleep(do)
             else:
-                return do
+                raise StopAsyncIteration
 
     def wraps(self, fn: WrappedFn) -> WrappedFn:
         fn = super().wraps(fn)
         # Ensure wrapper is recognized as a coroutine function.
 
         @functools.wraps(fn)
-        async def async_wrapped(*args: typing.Any, **kwargs: typing.Any) -> 
typing.Any:
+        async def async_wrapped(*args: t.Any, **kwargs: t.Any) -> t.Any:
             return await fn(*args, **kwargs)
 
         # Preserve attributes
-        async_wrapped.retry = fn.retry
-        async_wrapped.retry_with = fn.retry_with
+        async_wrapped.retry = fn.retry  # type: ignore[attr-defined]
+        async_wrapped.retry_with = fn.retry_with  # type: ignore[attr-defined]
 
-        return async_wrapped
+        return async_wrapped  # type: ignore[return-value]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity/_utils.py 
new/tenacity-8.2.2/tenacity/_utils.py
--- old/tenacity-8.1.0/tenacity/_utils.py       2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/tenacity/_utils.py       2023-02-28 15:21:48.000000000 
+0100
@@ -16,6 +16,7 @@
 
 import sys
 import typing
+from datetime import timedelta
 
 
 # sys.maxsize:
@@ -66,3 +67,10 @@
         except AttributeError:
             pass
         return ".".join(segments)
+
+
+time_unit_type = typing.Union[int, float, timedelta]
+
+
+def to_seconds(time_unit: time_unit_type) -> float:
+    return float(time_unit.total_seconds() if isinstance(time_unit, timedelta) 
else time_unit)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity/after.py 
new/tenacity-8.2.2/tenacity/after.py
--- old/tenacity-8.1.0/tenacity/after.py        2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/tenacity/after.py        2023-02-28 15:21:48.000000000 
+0100
@@ -36,9 +36,14 @@
     """After call strategy that logs to some logger the finished attempt."""
 
     def log_it(retry_state: "RetryCallState") -> None:
+        if retry_state.fn is None:
+            # NOTE(sileht): can't really happen, but we must please mypy
+            fn_name = "<unknown>"
+        else:
+            fn_name = _utils.get_callback_name(retry_state.fn)
         logger.log(
             log_level,
-            f"Finished call to '{_utils.get_callback_name(retry_state.fn)}' "
+            f"Finished call to '{fn_name}' "
             f"after {sec_format % retry_state.seconds_since_start}(s), "
             f"this was the {_utils.to_ordinal(retry_state.attempt_number)} 
time calling it.",
         )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity/before.py 
new/tenacity-8.2.2/tenacity/before.py
--- old/tenacity-8.1.0/tenacity/before.py       2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/tenacity/before.py       2023-02-28 15:21:48.000000000 
+0100
@@ -32,9 +32,14 @@
     """Before call strategy that logs to some logger the attempt."""
 
     def log_it(retry_state: "RetryCallState") -> None:
+        if retry_state.fn is None:
+            # NOTE(sileht): can't really happen, but we must please mypy
+            fn_name = "<unknown>"
+        else:
+            fn_name = _utils.get_callback_name(retry_state.fn)
         logger.log(
             log_level,
-            f"Starting call to '{_utils.get_callback_name(retry_state.fn)}', "
+            f"Starting call to '{fn_name}', "
             f"this is the {_utils.to_ordinal(retry_state.attempt_number)} time 
calling it.",
         )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity/before_sleep.py 
new/tenacity-8.2.2/tenacity/before_sleep.py
--- old/tenacity-8.1.0/tenacity/before_sleep.py 2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/tenacity/before_sleep.py 2023-02-28 15:21:48.000000000 
+0100
@@ -36,6 +36,14 @@
     """Before call strategy that logs to some logger the attempt."""
 
     def log_it(retry_state: "RetryCallState") -> None:
+        local_exc_info: BaseException | bool | None
+
+        if retry_state.outcome is None:
+            raise RuntimeError("log_it() called before outcome was set")
+
+        if retry_state.next_action is None:
+            raise RuntimeError("log_it() called before next_action was set")
+
         if retry_state.outcome.failed:
             ex = retry_state.outcome.exception()
             verb, value = "raised", f"{ex.__class__.__name__}: {ex}"
@@ -48,10 +56,15 @@
             verb, value = "returned", retry_state.outcome.result()
             local_exc_info = False  # exc_info does not apply when no exception
 
+        if retry_state.fn is None:
+            # NOTE(sileht): can't really happen, but we must please mypy
+            fn_name = "<unknown>"
+        else:
+            fn_name = _utils.get_callback_name(retry_state.fn)
+
         logger.log(
             log_level,
-            f"Retrying {_utils.get_callback_name(retry_state.fn)} "
-            f"in {retry_state.next_action.sleep} seconds as it {verb} 
{value}.",
+            f"Retrying {fn_name} " f"in {retry_state.next_action.sleep} 
seconds as it {verb} {value}.",
             exc_info=local_exc_info,
         )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity/retry.py 
new/tenacity-8.2.2/tenacity/retry.py
--- old/tenacity-8.1.0/tenacity/retry.py        2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/tenacity/retry.py        2023-02-28 15:21:48.000000000 
+0100
@@ -36,6 +36,9 @@
         return retry_any(self, other)
 
 
+RetryBaseT = typing.Union[retry_base, typing.Callable[["RetryCallState"], 
bool]]
+
+
 class _retry_never(retry_base):
     """Retry strategy that never rejects any result."""
 
@@ -63,8 +66,14 @@
         self.predicate = predicate
 
     def __call__(self, retry_state: "RetryCallState") -> bool:
+        if retry_state.outcome is None:
+            raise RuntimeError("__call__() called before outcome was set")
+
         if retry_state.outcome.failed:
-            return self.predicate(retry_state.outcome.exception())
+            exception = retry_state.outcome.exception()
+            if exception is None:
+                raise RuntimeError("outcome failed but the exception is None")
+            return self.predicate(exception)
         else:
             return False
 
@@ -111,10 +120,17 @@
         super().__init__(lambda e: not isinstance(e, exception_types))
 
     def __call__(self, retry_state: "RetryCallState") -> bool:
+        if retry_state.outcome is None:
+            raise RuntimeError("__call__() called before outcome was set")
+
         # always retry if no exception was raised
         if not retry_state.outcome.failed:
             return True
-        return self.predicate(retry_state.outcome.exception())
+
+        exception = retry_state.outcome.exception()
+        if exception is None:
+            raise RuntimeError("outcome failed but the exception is None")
+        return self.predicate(exception)
 
 
 class retry_if_exception_cause_type(retry_base):
@@ -134,6 +150,9 @@
         self.exception_cause_types = exception_types
 
     def __call__(self, retry_state: "RetryCallState") -> bool:
+        if retry_state.outcome is None:
+            raise RuntimeError("__call__ called before outcome was set")
+
         if retry_state.outcome.failed:
             exc = retry_state.outcome.exception()
             while exc is not None:
@@ -151,6 +170,9 @@
         self.predicate = predicate
 
     def __call__(self, retry_state: "RetryCallState") -> bool:
+        if retry_state.outcome is None:
+            raise RuntimeError("__call__() called before outcome was set")
+
         if not retry_state.outcome.failed:
             return self.predicate(retry_state.outcome.result())
         else:
@@ -164,6 +186,9 @@
         self.predicate = predicate
 
     def __call__(self, retry_state: "RetryCallState") -> bool:
+        if retry_state.outcome is None:
+            raise RuntimeError("__call__() called before outcome was set")
+
         if not retry_state.outcome.failed:
             return not self.predicate(retry_state.outcome.result())
         else:
@@ -215,9 +240,16 @@
         self.predicate = lambda *args_, **kwargs_: not if_predicate(*args_, 
**kwargs_)
 
     def __call__(self, retry_state: "RetryCallState") -> bool:
+        if retry_state.outcome is None:
+            raise RuntimeError("__call__() called before outcome was set")
+
         if not retry_state.outcome.failed:
             return True
-        return self.predicate(retry_state.outcome.exception())
+
+        exception = retry_state.outcome.exception()
+        if exception is None:
+            raise RuntimeError("outcome failed but the exception is None")
+        return self.predicate(exception)
 
 
 class retry_any(retry_base):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity/stop.py 
new/tenacity-8.2.2/tenacity/stop.py
--- old/tenacity-8.1.0/tenacity/stop.py 2022-09-21 14:23:59.000000000 +0200
+++ new/tenacity-8.2.2/tenacity/stop.py 2023-02-28 15:21:48.000000000 +0100
@@ -16,6 +16,8 @@
 import abc
 import typing
 
+from tenacity import _utils
+
 if typing.TYPE_CHECKING:
     import threading
 
@@ -36,6 +38,9 @@
         return stop_any(self, other)
 
 
+StopBaseT = typing.Union[stop_base, typing.Callable[["RetryCallState"], bool]]
+
+
 class stop_any(stop_base):
     """Stop if any of the stop condition is valid."""
 
@@ -89,8 +94,10 @@
 class stop_after_delay(stop_base):
     """Stop when the time from the first attempt >= limit."""
 
-    def __init__(self, max_delay: float) -> None:
-        self.max_delay = max_delay
+    def __init__(self, max_delay: _utils.time_unit_type) -> None:
+        self.max_delay = _utils.to_seconds(max_delay)
 
     def __call__(self, retry_state: "RetryCallState") -> bool:
+        if retry_state.seconds_since_start is None:
+            raise RuntimeError("__call__() called but seconds_since_start is 
not set")
         return retry_state.seconds_since_start >= self.max_delay
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity/tornadoweb.py 
new/tenacity-8.2.2/tenacity/tornadoweb.py
--- old/tenacity-8.1.0/tenacity/tornadoweb.py   2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/tenacity/tornadoweb.py   2023-02-28 15:21:48.000000000 
+0100
@@ -33,8 +33,8 @@
         super().__init__(**kwargs)
         self.sleep = sleep
 
-    @gen.coroutine
-    def __call__(  # type: ignore  # Change signature from supertype
+    @gen.coroutine  # type: ignore[misc]
+    def __call__(
         self,
         fn: "typing.Callable[..., typing.Union[typing.Generator[typing.Any, 
typing.Any, _RetValT], Future[_RetValT]]]",
         *args: typing.Any,
@@ -49,7 +49,7 @@
                 try:
                     result = yield fn(*args, **kwargs)
                 except BaseException:  # noqa: B902
-                    retry_state.set_exception(sys.exc_info())
+                    retry_state.set_exception(sys.exc_info())  # type: 
ignore[arg-type]
                 else:
                     retry_state.set_result(result)
             elif isinstance(do, DoSleep):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity/wait.py 
new/tenacity-8.2.2/tenacity/wait.py
--- old/tenacity-8.1.0/tenacity/wait.py 2022-09-21 14:23:59.000000000 +0200
+++ new/tenacity-8.2.2/tenacity/wait.py 2023-02-28 15:21:48.000000000 +0100
@@ -17,19 +17,12 @@
 import abc
 import random
 import typing
-from datetime import timedelta
 
 from tenacity import _utils
 
 if typing.TYPE_CHECKING:
     from tenacity import RetryCallState
 
-wait_unit_type = typing.Union[int, float, timedelta]
-
-
-def to_seconds(wait_unit: wait_unit_type) -> float:
-    return float(wait_unit.total_seconds() if isinstance(wait_unit, timedelta) 
else wait_unit)
-
 
 class wait_base(abc.ABC):
     """Abstract base class for wait strategies."""
@@ -43,16 +36,19 @@
 
     def __radd__(self, other: "wait_base") -> typing.Union["wait_combine", 
"wait_base"]:
         # make it possible to use multiple waits with the built-in sum function
-        if other == 0:
+        if other == 0:  # type: ignore[comparison-overlap]
             return self
         return self.__add__(other)
 
 
+WaitBaseT = typing.Union[wait_base, typing.Callable[["RetryCallState"], 
typing.Union[float, int]]]
+
+
 class wait_fixed(wait_base):
     """Wait strategy that waits a fixed amount of time between each retry."""
 
-    def __init__(self, wait: wait_unit_type) -> None:
-        self.wait_fixed = to_seconds(wait)
+    def __init__(self, wait: _utils.time_unit_type) -> None:
+        self.wait_fixed = _utils.to_seconds(wait)
 
     def __call__(self, retry_state: "RetryCallState") -> float:
         return self.wait_fixed
@@ -68,9 +64,9 @@
 class wait_random(wait_base):
     """Wait strategy that waits a random amount of time between min/max."""
 
-    def __init__(self, min: wait_unit_type = 0, max: wait_unit_type = 1) -> 
None:  # noqa
-        self.wait_random_min = to_seconds(min)
-        self.wait_random_max = to_seconds(max)
+    def __init__(self, min: _utils.time_unit_type = 0, max: 
_utils.time_unit_type = 1) -> None:  # noqa
+        self.wait_random_min = _utils.to_seconds(min)
+        self.wait_random_max = _utils.to_seconds(max)
 
     def __call__(self, retry_state: "RetryCallState") -> float:
         return self.wait_random_min + (random.random() * (self.wait_random_max 
- self.wait_random_min))
@@ -120,13 +116,13 @@
 
     def __init__(
         self,
-        start: wait_unit_type = 0,
-        increment: wait_unit_type = 100,
-        max: wait_unit_type = _utils.MAX_WAIT,  # noqa
+        start: _utils.time_unit_type = 0,
+        increment: _utils.time_unit_type = 100,
+        max: _utils.time_unit_type = _utils.MAX_WAIT,  # noqa
     ) -> None:
-        self.start = to_seconds(start)
-        self.increment = to_seconds(increment)
-        self.max = to_seconds(max)
+        self.start = _utils.to_seconds(start)
+        self.increment = _utils.to_seconds(increment)
+        self.max = _utils.to_seconds(max)
 
     def __call__(self, retry_state: "RetryCallState") -> float:
         result = self.start + (self.increment * (retry_state.attempt_number - 
1))
@@ -149,13 +145,13 @@
     def __init__(
         self,
         multiplier: typing.Union[int, float] = 1,
-        max: wait_unit_type = _utils.MAX_WAIT,  # noqa
+        max: _utils.time_unit_type = _utils.MAX_WAIT,  # noqa
         exp_base: typing.Union[int, float] = 2,
-        min: wait_unit_type = 0,  # noqa
+        min: _utils.time_unit_type = 0,  # noqa
     ) -> None:
         self.multiplier = multiplier
-        self.min = to_seconds(min)
-        self.max = to_seconds(max)
+        self.min = _utils.to_seconds(min)
+        self.max = _utils.to_seconds(max)
         self.exp_base = exp_base
 
     def __call__(self, retry_state: "RetryCallState") -> float:
@@ -206,7 +202,7 @@
     This implements the strategy described here:
     https://cloud.google.com/storage/docs/retry-strategy
 
-    The wait time is min(initial * (2**n + random.uniform(0, jitter)), maximum)
+    The wait time is min(initial * 2**n + random.uniform(0, jitter), maximum)
     where n is the retry count.
     """
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity.egg-info/PKG-INFO 
new/tenacity-8.2.2/tenacity.egg-info/PKG-INFO
--- old/tenacity-8.1.0/tenacity.egg-info/PKG-INFO       2022-09-21 
14:24:11.000000000 +0200
+++ new/tenacity-8.2.2/tenacity.egg-info/PKG-INFO       2023-02-28 
15:22:05.000000000 +0100
@@ -1,12 +1,11 @@
 Metadata-Version: 2.1
 Name: tenacity
-Version: 8.1.0
+Version: 8.2.2
 Summary: Retry code until it succeeds
 Home-page: https://github.com/jd/tenacity
 Author: Julien Danjou
 Author-email: jul...@danjou.info
 License: Apache 2.0
-Platform: UNKNOWN
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: Apache Software License
 Classifier: Programming Language :: Python
@@ -17,10 +16,10 @@
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
 Classifier: Topic :: Utilities
 Requires-Python: >=3.6
 Provides-Extra: doc
 License-File: LICENSE
 
 Tenacity is a general-purpose retrying library to simplify the task of adding 
retry behavior to just about anything.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tenacity.egg-info/SOURCES.txt 
new/tenacity-8.2.2/tenacity.egg-info/SOURCES.txt
--- old/tenacity-8.1.0/tenacity.egg-info/SOURCES.txt    2022-09-21 
14:24:11.000000000 +0200
+++ new/tenacity-8.2.2/tenacity.egg-info/SOURCES.txt    2023-02-28 
15:22:05.000000000 +0100
@@ -9,7 +9,8 @@
 setup.cfg
 setup.py
 tox.ini
-.circleci/config.yml
+.github/workflows/ci.yaml
+.github/workflows/deploy.yaml
 doc/source/api.rst
 doc/source/changelog.rst
 doc/source/conf.py
@@ -17,21 +18,28 @@
 
releasenotes/notes/Use--for-formatting-and-validate-using-black-39ec9d57d4691778.yaml
 releasenotes/notes/add-reno-d1ab5710f272650a.yaml
 releasenotes/notes/add-retry_except_exception_type-31b31da1924d55f4.yaml
+releasenotes/notes/add_omitted_modules_to_import_all-2ab282f20a2c22f7.yaml
 releasenotes/notes/add_retry_if_exception_cause_type-d16b918ace4ae0ad.yaml
 releasenotes/notes/after_log-50f4d73b24ce9203.yaml
 releasenotes/notes/allow-mocking-of-nap-sleep-6679c50e702446f1.yaml
 releasenotes/notes/annotate_code-197b93130df14042.yaml
 releasenotes/notes/before_sleep_log-improvements-d8149274dfb37d7c.yaml
+releasenotes/notes/clarify-reraise-option-6829667eacf4f599.yaml
 releasenotes/notes/do_not_package_tests-fe5ac61940b0a5ed.yaml
 releasenotes/notes/drop-deprecated-python-versions-69a05cb2e0f1034c.yaml
 releasenotes/notes/drop_deprecated-7ea90b212509b082.yaml
+releasenotes/notes/export-convenience-symbols-981d9611c8b754f3.yaml
+releasenotes/notes/fix-async-loop-with-result-f68e913ccb425aca.yaml
+releasenotes/notes/fix-wait-typing-b26eecdb6cc0a1de.yaml
 releasenotes/notes/fix_async-52b6594c8e75c4bc.yaml
 releasenotes/notes/make-logger-more-compatible-5da1ddf1bab77047.yaml
+releasenotes/notes/no-async-iter-6132a42e52348a75.yaml
 releasenotes/notes/pr320-py3-only-wheel-tag.yaml
 releasenotes/notes/py36_plus-c425fb3aa17c6682.yaml
 releasenotes/notes/retrycallstate-repr-94947f7b00ee15e1.yaml
 releasenotes/notes/sphinx_define_error-642c9cd5c165d39a.yaml
 releasenotes/notes/support-timedelta-wait-unit-type-5ba1e9fc0fe45523.yaml
+releasenotes/notes/timedelta-for-stop-ef6bf71b88ce9988.yaml
 releasenotes/notes/wait_exponential_jitter-6ffc81dddcbaa6d3.yaml
 tenacity/__init__.py
 tenacity/_asyncio.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tests/test_after.py 
new/tenacity-8.2.2/tests/test_after.py
--- old/tenacity-8.1.0/tests/test_after.py      2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/tests/test_after.py      2023-02-28 15:21:48.000000000 
+0100
@@ -2,8 +2,8 @@
 import random
 import unittest.mock
 
-from tenacity import after_log
 from tenacity import _utils  # noqa
+from tenacity import after_log
 
 from . import test_tenacity
 
@@ -24,9 +24,10 @@
         retry_state = 
test_tenacity.make_retry_state(self.previous_attempt_number, 
delay_since_first_attempt)
         fun = after_log(logger=logger, log_level=self.log_level)  # use 
default sec_format
         fun(retry_state)
+        fn_name = "<unknown>" if retry_state.fn is None else 
_utils.get_callback_name(retry_state.fn)
         log.assert_called_once_with(
             self.log_level,
-            f"Finished call to '{_utils.get_callback_name(retry_state.fn)}' "
+            f"Finished call to '{fn_name}' "
             f"after {sec_format % retry_state.seconds_since_start}(s), "
             f"this was the {_utils.to_ordinal(retry_state.attempt_number)} 
time calling it.",
         )
@@ -42,9 +43,10 @@
         retry_state = 
test_tenacity.make_retry_state(self.previous_attempt_number, 
delay_since_first_attempt)
         fun = after_log(logger=logger, log_level=self.log_level, 
sec_format=sec_format)
         fun(retry_state)
+        fn_name = "<unknown>" if retry_state.fn is None else 
_utils.get_callback_name(retry_state.fn)
         log.assert_called_once_with(
             self.log_level,
-            f"Finished call to '{_utils.get_callback_name(retry_state.fn)}' "
+            f"Finished call to '{fn_name}' "
             f"after {sec_format % retry_state.seconds_since_start}(s), "
             f"this was the {_utils.to_ordinal(retry_state.attempt_number)} 
time calling it.",
         )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tests/test_asyncio.py 
new/tenacity-8.2.2/tests/test_asyncio.py
--- old/tenacity-8.1.0/tests/test_asyncio.py    2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/tests/test_asyncio.py    2023-02-28 15:21:48.000000000 
+0100
@@ -18,9 +18,11 @@
 import unittest
 from functools import wraps
 
+import pytest
+
 from tenacity import AsyncRetrying, RetryError
 from tenacity import _asyncio as tasyncio
-from tenacity import retry, stop_after_attempt
+from tenacity import retry, retry_if_result, stop_after_attempt
 from tenacity.wait import wait_fixed
 
 from .test_tenacity import NoIOErrorAfterCount, current_time_ms
@@ -88,7 +90,6 @@
 
     @asynctest
     async def test_attempt_number_is_correct_for_interleaved_coroutines(self):
-
         attempts = []
 
         def after(retry_state):
@@ -156,6 +157,28 @@
         t = current_time_ms() - start
         self.assertLess(t, 1.1)
 
+    @asynctest
+    async def test_retry_with_result(self):
+        async def test():
+            attempts = 0
+            async for attempt in 
tasyncio.AsyncRetrying(retry=retry_if_result(lambda x: x < 3)):
+                with attempt:
+                    attempts += 1
+                attempt.retry_state.set_result(attempts)
+            return attempts
+
+        result = await test()
+
+        self.assertEqual(3, result)
+
+    @asynctest
+    async def test_async_retying_iterator(self):
+        thing = NoIOErrorAfterCount(5)
+        with pytest.raises(TypeError):
+            for attempts in AsyncRetrying():
+                with attempts:
+                    await _async_function(thing)
+
 
 if __name__ == "__main__":
     unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tests/test_tenacity.py 
new/tenacity-8.2.2/tests/test_tenacity.py
--- old/tenacity-8.1.0/tests/test_tenacity.py   2022-09-21 14:23:59.000000000 
+0200
+++ new/tenacity-8.2.2/tests/test_tenacity.py   2023-02-28 15:21:48.000000000 
+0100
@@ -155,10 +155,12 @@
         self.assertTrue(r.stop(make_retry_state(4, 6546)))
 
     def test_stop_after_delay(self):
-        r = Retrying(stop=tenacity.stop_after_delay(1))
-        self.assertFalse(r.stop(make_retry_state(2, 0.999)))
-        self.assertTrue(r.stop(make_retry_state(2, 1)))
-        self.assertTrue(r.stop(make_retry_state(2, 1.001)))
+        for delay in (1, datetime.timedelta(seconds=1)):
+            with self.subTest():
+                r = Retrying(stop=tenacity.stop_after_delay(delay))
+                self.assertFalse(r.stop(make_retry_state(2, 0.999)))
+                self.assertTrue(r.stop(make_retry_state(2, 1)))
+                self.assertTrue(r.stop(make_retry_state(2, 1.001)))
 
     def test_legacy_explicit_stop_type(self):
         Retrying(stop="stop_after_attempt")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tenacity-8.1.0/tox.ini new/tenacity-8.2.2/tox.ini
--- old/tenacity-8.1.0/tox.ini  2022-09-21 14:23:59.000000000 +0200
+++ new/tenacity-8.2.2/tox.ini  2023-02-28 15:21:48.000000000 +0100
@@ -1,5 +1,5 @@
 [tox]
-envlist = py3{6,7,8,9,10}, pep8, pypy3
+envlist = py3{6,7,8,9,10,11}, pep8, pypy3
 skip_missing_interpreters = True
 
 [testenv]
@@ -10,9 +10,9 @@
     pytest
     typeguard
 commands =
-    py3{6,7,8,9,10},pypy3: pytest {posargs}
-    py3{6,7,8,9,10},pypy3: sphinx-build -a -E -W -b doctest doc/source 
doc/build
-    py3{6,7,8,9,10},pypy3: sphinx-build -a -E -W -b html doc/source doc/build
+    py3{6,7,8,9,10,11},pypy3: pytest {posargs}
+    py3{6,7,8,9,10,11},pypy3: sphinx-build -a -E -W -b doctest doc/source 
doc/build
+    py3{6,7,8,9,10,11},pypy3: sphinx-build -a -E -W -b html doc/source 
doc/build
 
 [testenv:pep8]
 basepython = python3
@@ -31,6 +31,12 @@
 commands =
     black .
 
+[testenv:mypy]
+deps =
+    mypy>=1.0.0
+commands =
+    mypy tenacity
+
 [testenv:black-ci]
 deps =
     black

Reply via email to