diff --git a/acme/.readthedocs.yaml b/acme/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/acme/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-ci/certbot_integration_tests/utils/misc.py b/certbot-ci/certbot_integration_tests/utils/misc.py index 8260ccf5e..8ef59fe1b 100644 --- a/certbot-ci/certbot_integration_tests/utils/misc.py +++ b/certbot-ci/certbot_integration_tests/utils/misc.py @@ -47,15 +47,8 @@ ECDSA_KEY_TYPE = 'ecdsa' def _suppress_x509_verification_warnings() -> None: - try: - import urllib3 - urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) - except ImportError: - # Handle old versions of request with vendorized urllib3 - # pylint: disable=no-member - from requests.packages.urllib3.exceptions import InsecureRequestWarning - requests.packages.urllib3.disable_warnings( # type: ignore[attr-defined] - InsecureRequestWarning) + import urllib3 + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def check_until_timeout(url: str, attempts: int = 30) -> None: diff --git a/certbot-ci/setup.py b/certbot-ci/setup.py index 3fddcf104..067b26678 100644 --- a/certbot-ci/setup.py +++ b/certbot-ci/setup.py @@ -19,9 +19,11 @@ install_requires = [ 'pywin32>=300 ; sys_platform == "win32"', 'pyyaml', 'pytz>=2019.3', - 'requests', + # requests unvendored its dependencies in version 2.16.0 and this code relies on that for + # calling `urllib3.disable_warnings`. + 'requests>=2.16.0', 'setuptools', - 'types-python-dateutil' + 'types-python-dateutil', ] setup( diff --git a/certbot-dns-cloudflare/.readthedocs.yaml b/certbot-dns-cloudflare/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-cloudflare/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-digitalocean/.readthedocs.yaml b/certbot-dns-digitalocean/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-digitalocean/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-dnsimple/.readthedocs.yaml b/certbot-dns-dnsimple/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-dnsimple/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-dnsimple/certbot_dns_dnsimple/_internal/tests/dns_dnsimple_test.py b/certbot-dns-dnsimple/certbot_dns_dnsimple/_internal/tests/dns_dnsimple_test.py index ff299ad49..e0d389be1 100644 --- a/certbot-dns-dnsimple/certbot_dns_dnsimple/_internal/tests/dns_dnsimple_test.py +++ b/certbot-dns-dnsimple/certbot_dns_dnsimple/_internal/tests/dns_dnsimple_test.py @@ -3,6 +3,7 @@ from unittest import mock import sys import pytest +from requests import Response from requests.exceptions import HTTPError from certbot.compat import os @@ -16,7 +17,7 @@ TOKEN = 'foo' class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common_lexicon.BaseLexiconDNSAuthenticatorTest): - LOGIN_ERROR = HTTPError('401 Client Error: Unauthorized for url: ...') + LOGIN_ERROR = HTTPError('401 Client Error: Unauthorized for url: ...', response=Response()) def setUp(self): super().setUp() diff --git a/certbot-dns-dnsmadeeasy/.readthedocs.yaml b/certbot-dns-dnsmadeeasy/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-dnsmadeeasy/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/_internal/tests/dns_dnsmadeeasy_test.py b/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/_internal/tests/dns_dnsmadeeasy_test.py index 286e65ed9..4adb70643 100644 --- a/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/_internal/tests/dns_dnsmadeeasy_test.py +++ b/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/_internal/tests/dns_dnsmadeeasy_test.py @@ -4,6 +4,7 @@ import sys from unittest import mock import pytest +from requests import Response from requests.exceptions import HTTPError from certbot.compat import os @@ -19,8 +20,8 @@ SECRET_KEY = 'bar' class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common_lexicon.BaseLexiconDNSAuthenticatorTest): - DOMAIN_NOT_FOUND = HTTPError(f'404 Client Error: Not Found for url: {DOMAIN}.') - LOGIN_ERROR = HTTPError(f'403 Client Error: Forbidden for url: {DOMAIN}.') + DOMAIN_NOT_FOUND = HTTPError(f'404 Client Error: Not Found for url: {DOMAIN}.', response=Response()) + LOGIN_ERROR = HTTPError(f'403 Client Error: Forbidden for url: {DOMAIN}.', response=Response()) def setUp(self): super().setUp() diff --git a/certbot-dns-gehirn/.readthedocs.yaml b/certbot-dns-gehirn/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-gehirn/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-gehirn/certbot_dns_gehirn/_internal/tests/dns_gehirn_test.py b/certbot-dns-gehirn/certbot_dns_gehirn/_internal/tests/dns_gehirn_test.py index 3d082049d..3df3c5431 100644 --- a/certbot-dns-gehirn/certbot_dns_gehirn/_internal/tests/dns_gehirn_test.py +++ b/certbot-dns-gehirn/certbot_dns_gehirn/_internal/tests/dns_gehirn_test.py @@ -5,6 +5,7 @@ import unittest from unittest import mock import pytest +from requests import Response from requests.exceptions import HTTPError from certbot.compat import os @@ -20,8 +21,8 @@ API_SECRET = 'MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw' class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common_lexicon.BaseLexiconDNSAuthenticatorTest): - DOMAIN_NOT_FOUND = HTTPError(f'404 Client Error: Not Found for url: {DOMAIN}.') - LOGIN_ERROR = HTTPError(f'401 Client Error: Unauthorized for url: {DOMAIN}.') + DOMAIN_NOT_FOUND = HTTPError(f'404 Client Error: Not Found for url: {DOMAIN}.', response=Response()) + LOGIN_ERROR = HTTPError(f'401 Client Error: Unauthorized for url: {DOMAIN}.', response=Response()) def setUp(self): super().setUp() diff --git a/certbot-dns-google/.readthedocs.yaml b/certbot-dns-google/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-google/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-linode/.readthedocs.yaml b/certbot-dns-linode/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-linode/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-luadns/.readthedocs.yaml b/certbot-dns-luadns/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-luadns/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-luadns/certbot_dns_luadns/_internal/tests/dns_luadns_test.py b/certbot-dns-luadns/certbot_dns_luadns/_internal/tests/dns_luadns_test.py index 0b424e860..890616b5e 100644 --- a/certbot-dns-luadns/certbot_dns_luadns/_internal/tests/dns_luadns_test.py +++ b/certbot-dns-luadns/certbot_dns_luadns/_internal/tests/dns_luadns_test.py @@ -3,6 +3,7 @@ import sys from unittest import mock import pytest +from requests import Response from requests.exceptions import HTTPError from certbot.compat import os @@ -17,7 +18,7 @@ TOKEN = 'foo' class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common_lexicon.BaseLexiconDNSAuthenticatorTest): - LOGIN_ERROR = HTTPError("401 Client Error: Unauthorized for url: ...") + LOGIN_ERROR = HTTPError("401 Client Error: Unauthorized for url: ...", response=Response()) def setUp(self): super().setUp() diff --git a/certbot-dns-nsone/.readthedocs.yaml b/certbot-dns-nsone/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-nsone/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-nsone/certbot_dns_nsone/_internal/tests/dns_nsone_test.py b/certbot-dns-nsone/certbot_dns_nsone/_internal/tests/dns_nsone_test.py index ae0ff4c21..3f6e7e7c7 100644 --- a/certbot-dns-nsone/certbot_dns_nsone/_internal/tests/dns_nsone_test.py +++ b/certbot-dns-nsone/certbot_dns_nsone/_internal/tests/dns_nsone_test.py @@ -3,6 +3,7 @@ import sys from unittest import mock import pytest +from requests import Response from requests.exceptions import HTTPError from certbot.compat import os @@ -17,8 +18,8 @@ API_KEY = 'foo' class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common_lexicon.BaseLexiconDNSAuthenticatorTest): - DOMAIN_NOT_FOUND = HTTPError(f'404 Client Error: Not Found for url: {DOMAIN}.') - LOGIN_ERROR = HTTPError(f'401 Client Error: Unauthorized for url: {DOMAIN}.') + DOMAIN_NOT_FOUND = HTTPError(f'404 Client Error: Not Found for url: {DOMAIN}.', response=Response()) + LOGIN_ERROR = HTTPError(f'401 Client Error: Unauthorized for url: {DOMAIN}.', response=Response()) def setUp(self): super().setUp() diff --git a/certbot-dns-ovh/.readthedocs.yaml b/certbot-dns-ovh/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-ovh/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-ovh/certbot_dns_ovh/_internal/tests/dns_ovh_test.py b/certbot-dns-ovh/certbot_dns_ovh/_internal/tests/dns_ovh_test.py index 2b054a304..a5d553cd9 100644 --- a/certbot-dns-ovh/certbot_dns_ovh/_internal/tests/dns_ovh_test.py +++ b/certbot-dns-ovh/certbot_dns_ovh/_internal/tests/dns_ovh_test.py @@ -3,6 +3,7 @@ from unittest import mock import sys import pytest +from requests import Response from requests.exceptions import HTTPError from certbot.compat import os @@ -20,8 +21,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common_lexicon.BaseLexiconDNSAuthenticatorTest): DOMAIN_NOT_FOUND = Exception('Domain example.com not found') - LOGIN_ERROR = HTTPError('403 Client Error: Forbidden for url: https://eu.api.ovh.com/1.0/...') - + LOGIN_ERROR = HTTPError('403 Client Error: Forbidden for url: https://eu.api.ovh.com/1.0/...', response=Response()) def setUp(self): super().setUp() diff --git a/certbot-dns-ovh/setup.py b/certbot-dns-ovh/setup.py index d8315f66a..9b86b1f1d 100644 --- a/certbot-dns-ovh/setup.py +++ b/certbot-dns-ovh/setup.py @@ -7,7 +7,7 @@ from setuptools import setup version = '2.7.1' install_requires = [ - 'dns-lexicon>=3.14.1', + 'dns-lexicon>=3.15.1', 'setuptools>=41.6.0', ] diff --git a/certbot-dns-rfc2136/.readthedocs.yaml b/certbot-dns-rfc2136/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-rfc2136/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-route53/.readthedocs.yaml b/certbot-dns-route53/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-route53/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-sakuracloud/.readthedocs.yaml b/certbot-dns-sakuracloud/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot-dns-sakuracloud/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot-dns-sakuracloud/certbot_dns_sakuracloud/_internal/tests/dns_sakuracloud_test.py b/certbot-dns-sakuracloud/certbot_dns_sakuracloud/_internal/tests/dns_sakuracloud_test.py index e7e0b108e..44a36b9e0 100644 --- a/certbot-dns-sakuracloud/certbot_dns_sakuracloud/_internal/tests/dns_sakuracloud_test.py +++ b/certbot-dns-sakuracloud/certbot_dns_sakuracloud/_internal/tests/dns_sakuracloud_test.py @@ -3,6 +3,7 @@ import sys from unittest import mock import pytest +from requests import Response from requests.exceptions import HTTPError from certbot.compat import os @@ -18,8 +19,8 @@ API_SECRET = 'MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw' class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common_lexicon.BaseLexiconDNSAuthenticatorTest): - DOMAIN_NOT_FOUND = HTTPError(f'404 Client Error: Not Found for url: {DOMAIN}.') - LOGIN_ERROR = HTTPError(f'401 Client Error: Unauthorized for url: {DOMAIN}.') + DOMAIN_NOT_FOUND = HTTPError(f'404 Client Error: Not Found for url: {DOMAIN}.', response=Response()) + LOGIN_ERROR = HTTPError(f'401 Client Error: Unauthorized for url: {DOMAIN}.', response=Response()) def setUp(self): super().setUp() diff --git a/certbot/.readthedocs.yaml b/certbot/.readthedocs.yaml new file mode 100644 index 000000000..9893f2828 --- /dev/null +++ b/certbot/.readthedocs.yaml @@ -0,0 +1,33 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: ../tools/requirements.txt \ No newline at end of file diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index 60973dabb..07ed9a140 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -2,6 +2,16 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). +## 2.7.2 - master + +### Fixed + +* `certbot-dns-ovh` plugin now requires `lexicon>=3.15.1` to ensure a consistent behavior with OVH APIs. +* Fixed a bug where argument sources weren't correctly detected in abbreviated + arguments, short arguments, and some other circumstances + +More details about these changes can be found on our GitHub repo. + ## 2.7.1 - 2023-10-10 ### Fixed diff --git a/certbot/certbot/_internal/cli/helpful.py b/certbot/certbot/_internal/cli/helpful.py index f42096ded..6fea1b131 100644 --- a/certbot/certbot/_internal/cli/helpful.py +++ b/certbot/certbot/_internal/cli/helpful.py @@ -187,10 +187,12 @@ class HelpfulArgumentParser: # 2. config files # 3. env vars (shouldn't be any) # 4. command line + def update_result(settings_dict: Dict[str, Tuple[configargparse.Action, str]], source: ArgumentSource) -> None: - actions = [action for _, (action, _) in settings_dict.items()] - result.update({ action.dest: source for action in actions}) + actions = [self._find_action_for_arg(arg) if action is None else action + for arg, (action, _) in settings_dict.items()] + result.update({ action.dest: source for action in actions }) # config file sources look like "config_file|" for source_key in source_to_settings_dict: @@ -203,17 +205,59 @@ class HelpfulArgumentParser: if 'command_line' in source_to_settings_dict: settings_dict: Dict[str, Tuple[None, List[str]]] settings_dict = source_to_settings_dict['command_line'] # type: ignore - (_, args) = settings_dict[''] - args = [arg for arg in args if arg.startswith('-')] + (_, unprocessed_args) = settings_dict[''] + args = [] + for arg in unprocessed_args: + # ignore non-arguments + if not arg.startswith('-'): + continue + + # special case for config file argument, which we don't have an action for + if arg in ['-c', '--config']: + result['config_dir'] = ArgumentSource.COMMAND_LINE + continue + + if '=' in arg: + arg = arg.split('=')[0] + + if arg.startswith('--'): + args.append(arg) + # for short args (ones that start with a single hyphen), handle + # the case of multiple short args together, e.g. "-tvm" + else: + for short_arg in arg[1:]: + args.append(f"-{short_arg}") + for arg in args: # find the action corresponding to this arg - for action in self.actions: - if arg in action.option_strings: - result[action.dest] = ArgumentSource.COMMAND_LINE - continue + action = self._find_action_for_arg(arg) + result[action.dest] = ArgumentSource.COMMAND_LINE return result + def _find_action_for_arg(self, arg: str) -> configargparse.Action: + # Finds a configargparse Action which matches the given arg, where arg + # can either be preceded by hyphens (as on the command line) or not (as + # in config files) + + # if the argument doesn't have leading hypens, prefix it so it can be + # compared directly w/ action option strings + if arg[0] != '-': + arg = '--' + arg + + # first, check for exact matches + for action in self.actions: + if arg in action.option_strings: + return action + + # now check for abbreviated (i.e. prefix) matches + for action in self.actions: + for option_string in action.option_strings: + if option_string.startswith(arg): + return action + + raise AssertionError(f"Action corresponding to argument {arg} is None") + def parse_args(self) -> NamespaceConfig: """Parses command line arguments and returns the result. diff --git a/certbot/certbot/_internal/plugins/disco.py b/certbot/certbot/_internal/plugins/disco.py index c0426bcd8..9454e176c 100644 --- a/certbot/certbot/_internal/plugins/disco.py +++ b/certbot/certbot/_internal/plugins/disco.py @@ -182,9 +182,9 @@ class PluginsRegistry(Mapping): plugin_paths = plugin_paths_string.split(':') if plugin_paths_string else [] # XXX should ensure this only happens once sys.path.extend(plugin_paths) - entry_points = list(importlib_metadata.entry_points( + entry_points = list(importlib_metadata.entry_points( # pylint: disable=unexpected-keyword-arg group=constants.SETUPTOOLS_PLUGINS_ENTRY_POINT)) - old_entry_points = list(importlib_metadata.entry_points( + old_entry_points = list(importlib_metadata.entry_points( # pylint: disable=unexpected-keyword-arg group=constants.OLD_SETUPTOOLS_PLUGINS_ENTRY_POINT)) for entry_point in entry_points + old_entry_points: try: diff --git a/certbot/certbot/_internal/tests/cli_test.py b/certbot/certbot/_internal/tests/cli_test.py index 446b2252f..e4505dbee 100644 --- a/certbot/certbot/_internal/tests/cli_test.py +++ b/certbot/certbot/_internal/tests/cli_test.py @@ -552,6 +552,48 @@ class ParseTest(unittest.TestCase): ]) assert_value_and_source(namespace, 'server', COMMAND_LINE_VALUE, ArgumentSource.COMMAND_LINE) + def test_abbreviated_arguments(self): + # Argparse's "allow_abbrev" option (which is True by default) allows + # for unambiguous partial arguments (e.g. "--preferred-chal dns" will be + # interepreted the same as "--preferred-challenges dns") + namespace = self.parse('--preferred-chal dns --no-dir') + assert_set_by_user_with_value(namespace, 'pref_challs', ['dns-01']) + assert_set_by_user_with_value(namespace, 'directory_hooks', False) + + with tempfile.NamedTemporaryFile() as tmp_config: + tmp_config.close() # close now because of compatibility issues on Windows + with open(tmp_config.name, 'w') as file_h: + file_h.write('preferred-chal = dns') + + namespace = self.parse([ + 'certonly', + '--config', tmp_config.name, + ]) + assert_set_by_user_with_value(namespace, 'pref_challs', ['dns-01']) + + @mock.patch('certbot._internal.hooks.validate_hooks') + def test_argument_with_equals(self, unsused_mock_validate_hooks): + namespace = self.parse('-d=example.com') + assert_set_by_user_with_value(namespace, 'domains', ['example.com']) + + # make sure it doesn't choke on equals signs being present in the argument value + plugins = disco.PluginsRegistry.find_all() + namespace = cli.prepare_and_parse_args(plugins, ['run', '--pre-hook="foo=bar"']) + assert_set_by_user_with_value(namespace, 'pre_hook', '"foo=bar"') + + def test_adjacent_short_args(self): + namespace = self.parse('-tv') + assert_set_by_user_with_value(namespace, 'text_mode', True) + assert_set_by_user_with_value(namespace, 'verbose_count', 1) + + namespace = self.parse('-tvvv') + assert_set_by_user_with_value(namespace, 'text_mode', True) + assert_set_by_user_with_value(namespace, 'verbose_count', 3) + + namespace = self.parse('-tvm foo@example.com') + assert_set_by_user_with_value(namespace, 'text_mode', True) + assert_set_by_user_with_value(namespace, 'verbose_count', 1) + assert_set_by_user_with_value(namespace, 'email', 'foo@example.com') if __name__ == '__main__': sys.exit(pytest.main(sys.argv[1:] + [__file__])) # pragma: no cover diff --git a/certbot/certbot/plugins/dns_common_lexicon.py b/certbot/certbot/plugins/dns_common_lexicon.py index d61534a10..6e07e6dc4 100644 --- a/certbot/certbot/plugins/dns_common_lexicon.py +++ b/certbot/certbot/plugins/dns_common_lexicon.py @@ -30,9 +30,9 @@ try: from lexicon.config import ConfigResolver from lexicon.interfaces import Provider except ImportError: # pragma: no cover - Client = None - ConfigResolver = None - Provider = None + Client = None # type: ignore + ConfigResolver = None # type: ignore + Provider = None # type: ignore logger = logging.getLogger(__name__) @@ -148,19 +148,18 @@ def build_lexicon_config(lexicon_provider_name: str, .. deprecated:: 2.7.0 Please use certbot.plugins.dns_common_lexicon.LexiconDNSAuthenticator instead. """ - config: Union[ConfigResolver, Dict[str, Any]] = {'provider_name': lexicon_provider_name} - config.update(lexicon_options) - if not ConfigResolver: + config_dict: Dict[str, Any] = {'provider_name': lexicon_provider_name} + config_dict.update(lexicon_options) + if ConfigResolver is None: # Lexicon 2.x - config.update(provider_options) + config_dict.update(provider_options) + return config_dict else: # Lexicon 3.x provider_config: Dict[str, Any] = {} provider_config.update(provider_options) - config[lexicon_provider_name] = provider_config - config = ConfigResolver().with_dict(config).with_env() - - return config + config_dict[lexicon_provider_name] = provider_config + return ConfigResolver().with_dict(config_dict).with_env() class LexiconDNSAuthenticator(dns_common.DNSAuthenticator): diff --git a/certbot/certbot/plugins/dns_test_common_lexicon.py b/certbot/certbot/plugins/dns_test_common_lexicon.py index f1de1b76e..451acbb05 100644 --- a/certbot/certbot/plugins/dns_test_common_lexicon.py +++ b/certbot/certbot/plugins/dns_test_common_lexicon.py @@ -13,6 +13,7 @@ from unittest.mock import MagicMock import warnings import josepy as jose +from requests import Response from requests.exceptions import HTTPError from requests.exceptions import RequestException @@ -37,8 +38,8 @@ KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key.pem")) DOMAIN_NOT_FOUND = Exception('No domain found') GENERIC_ERROR = RequestException -LOGIN_ERROR = HTTPError('400 Client Error: ...') -UNKNOWN_LOGIN_ERROR = HTTPError('500 Surprise! Error: ...') +LOGIN_ERROR = HTTPError('400 Client Error: ...', response=Response()) +UNKNOWN_LOGIN_ERROR = HTTPError('500 Surprise! Error: ...', response=Response()) class _AuthenticatorCallableLexiconTestCase(_AuthenticatorCallableTestCase, Protocol): diff --git a/tools/finish_release.py b/tools/finish_release.py index 723f38004..9b90ad322 100755 --- a/tools/finish_release.py +++ b/tools/finish_release.py @@ -73,7 +73,7 @@ def parse_args(args): parser.add_argument('--css', type=str, required=True, help='hostname of code signing server') return parser.parse_args(args) - + def publish_windows(css): """SSH into CSS and trigger downloading Azure Pipeline assets, sign, and upload to Github @@ -83,7 +83,7 @@ def publish_windows(css): username = input("CSS username (usually EFF username): ") host = css command = "ssh -t {}@{} bash /opt/certbot-misc/css/venv.sh".format(username,host) - + print("SSH into CSS to trigger signing and uploading of Windows installer...") subprocess.run(command, check=True, universal_newlines=True, shell=True) @@ -182,16 +182,16 @@ def fetch_version_number(major_version=None): :type major_version: str or None :returns: version number - + """ # Create a connection to the azure org organization_url = 'https://dev.azure.com/certbot' connection = Connection(base_url=organization_url) - + # Find the build artifacts build_client = connection.clients.get_build_client() - get_builds_response = build_client.get_builds('certbot', definitions='3') - for build in get_builds_response.value: + builds = build_client.get_builds('certbot', definitions='3') + for build in builds: version = build_client.get_build('certbot', build.id).source_branch.split('v')[1] if major_version is None or version.split('.')[0] == major_version: return version @@ -206,7 +206,7 @@ def main(args): # Once the GitHub release has been published, trying to publish it # again fails. Publishing the snaps can be done multiple times though # so we do that first to make it easier to run the script again later - # if something goes wrong. + # if something goes wrong. promote_snaps(ALL_SNAPS, 'beta', version) publish_windows(css) diff --git a/tools/oldest_constraints.txt b/tools/oldest_constraints.txt index 9cdff4f24..3fb34a46e 100644 --- a/tools/oldest_constraints.txt +++ b/tools/oldest_constraints.txt @@ -3,7 +3,7 @@ apacheconfig==0.3.2 ; python_version >= "3.7" and python_version < "3.8" appdirs==1.4.4 ; python_version >= "3.7" and python_version < "3.8" asn1crypto==0.24.0 ; python_version >= "3.7" and python_version < "3.8" -astroid==2.15.6 ; python_full_version >= "3.7.2" and python_version < "3.8" +astroid==2.15.8 ; python_full_version >= "3.7.2" and python_version < "3.8" beautifulsoup4==4.12.2 ; python_version >= "3.7" and python_version < "3.8" boto3==1.15.15 ; python_version >= "3.7" and python_version < "3.8" botocore==1.18.15 ; python_version >= "3.7" and python_version < "3.8" @@ -21,7 +21,7 @@ cython==0.29.36 ; python_version >= "3.7" and python_version < "3.8" dill==0.3.7 ; python_full_version >= "3.7.2" and python_version < "3.8" distlib==0.3.7 ; python_version >= "3.7" and python_version < "3.8" distro==1.0.1 ; python_version >= "3.7" and python_version < "3.8" -dns-lexicon==3.14.1 ; python_version >= "3.7" and python_version < "3.8" +dns-lexicon==3.15.1 ; python_version >= "3.7" and python_version < "3.8" dnspython==1.15.0 ; python_version >= "3.7" and python_version < "3.8" exceptiongroup==1.1.3 ; python_version >= "3.7" and python_version < "3.8" execnet==2.0.2 ; python_version >= "3.7" and python_version < "3.8" @@ -46,19 +46,20 @@ mypy-extensions==1.0.0 ; python_version >= "3.7" and python_version < "3.8" mypy==1.4.1 ; python_version >= "3.7" and python_version < "3.8" ndg-httpsclient==0.3.2 ; python_version >= "3.7" and python_version < "3.8" oauth2client==4.1.3 ; python_version >= "3.7" and python_version < "3.8" -packaging==23.1 ; python_version >= "3.7" and python_version < "3.8" +packaging==23.2 ; python_version >= "3.7" and python_version < "3.8" parsedatetime==2.4 ; python_version >= "3.7" and python_version < "3.8" pbr==1.8.0 ; python_version >= "3.7" and python_version < "3.8" -pip==23.2.1 ; python_version >= "3.7" and python_version < "3.8" -platformdirs==3.10.0 ; python_full_version >= "3.7.2" and python_version < "3.8" +pip==23.3 ; python_version >= "3.7" and python_version < "3.8" +platformdirs==3.11.0 ; python_full_version >= "3.7.2" and python_version < "3.8" pluggy==1.2.0 ; python_version >= "3.7" and python_version < "3.8" ply==3.4 ; python_version >= "3.7" and python_version < "3.8" py==1.11.0 ; python_version >= "3.7" and python_version < "3.8" pyasn1-modules==0.3.0 ; python_version >= "3.7" and python_version < "3.8" pyasn1==0.4.8 ; python_version >= "3.7" and python_version < "3.8" pycparser==2.14 ; python_version >= "3.7" and python_version < "3.8" -pylint==2.17.5 ; python_full_version >= "3.7.2" and python_version < "3.8" +pylint==2.17.7 ; python_full_version >= "3.7.2" and python_version < "3.8" pyopenssl==17.5.0 ; python_version >= "3.7" and python_version < "3.8" +pyotp==2.9.0 ; python_version >= "3.7" and python_version < "3.8" pyparsing==2.2.1 ; python_version >= "3.7" and python_version < "3.8" pyrfc3339==1.0 ; python_version >= "3.7" and python_version < "3.8" pytest-cov==4.1.0 ; python_version >= "3.7" and python_version < "3.8" @@ -77,7 +78,7 @@ s3transfer==0.3.7 ; python_version >= "3.7" and python_version < "3.8" setuptools==41.6.0 ; python_version >= "3.7" and python_version < "3.8" six==1.11.0 ; python_version >= "3.7" and python_version < "3.8" soupsieve==2.4.1 ; python_version >= "3.7" and python_version < "3.8" -tldextract==3.5.0 ; python_version >= "3.7" and python_version < "3.8" +tldextract==4.0.0 ; python_version >= "3.7" and python_version < "3.8" tomli==2.0.1 ; python_version < "3.8" and python_version >= "3.7" tomlkit==0.12.1 ; python_full_version >= "3.7.2" and python_version < "3.8" tox==1.9.2 ; python_version >= "3.7" and python_version < "3.8" @@ -87,9 +88,9 @@ types-httplib2==0.22.0.2 ; python_version >= "3.7" and python_version < "3.8" types-pyopenssl==23.0.0.0 ; python_version >= "3.7" and python_version < "3.8" types-pyrfc3339==1.1.1.5 ; python_version >= "3.7" and python_version < "3.8" types-python-dateutil==2.8.19.14 ; python_version >= "3.7" and python_version < "3.8" -types-pytz==2023.3.0.1 ; python_version >= "3.7" and python_version < "3.8" -types-pywin32==306.0.0.4 ; python_version >= "3.7" and python_version < "3.8" -types-requests==2.31.0.2 ; python_version >= "3.7" and python_version < "3.8" +types-pytz==2023.3.1.1 ; python_version >= "3.7" and python_version < "3.8" +types-pywin32==306.0.0.5 ; python_version >= "3.7" and python_version < "3.8" +types-requests==2.31.0.6 ; python_version >= "3.7" and python_version < "3.8" types-setuptools==68.2.0.0 ; python_version >= "3.7" and python_version < "3.8" types-six==1.16.21.9 ; python_version >= "3.7" and python_version < "3.8" types-urllib3==1.26.25.14 ; python_version >= "3.7" and python_version < "3.8" diff --git a/tools/pinning/oldest/pyproject.toml b/tools/pinning/oldest/pyproject.toml index 58e763be3..b1884fc68 100644 --- a/tools/pinning/oldest/pyproject.toml +++ b/tools/pinning/oldest/pyproject.toml @@ -54,7 +54,7 @@ cloudflare = "1.5.1" configobj = "5.0.6" cryptography = "3.2.1" distro = "1.0.1" -dns-lexicon = "3.14.1" +dns-lexicon = "3.15.1" dnspython = "1.15.0" funcsigs = "0.4" google-api-python-client = "1.6.5" diff --git a/tools/requirements.txt b/tools/requirements.txt index be328117e..123bae6d1 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -18,8 +18,8 @@ backports-cached-property==1.0.2 ; python_version >= "3.7" and python_version < bcrypt==4.0.1 ; python_version >= "3.7" and python_version < "4.0" beautifulsoup4==4.12.2 ; python_version >= "3.7" and python_version < "4.0" bleach==6.0.0 ; python_version >= "3.7" and python_version < "4.0" -boto3==1.28.60 ; python_version >= "3.7" and python_version < "4.0" -botocore==1.31.60 ; python_version >= "3.7" and python_version < "4.0" +boto3==1.28.66 ; python_version >= "3.7" and python_version < "4.0" +botocore==1.31.66 ; python_version >= "3.7" and python_version < "4.0" cachecontrol==0.12.14 ; python_version >= "3.7" and python_version < "4.0" cachetools==5.3.1 ; python_version >= "3.7" and python_version < "4.0" cachy==0.3.0 ; python_version >= "3.7" and python_version < "4.0" @@ -40,7 +40,7 @@ deprecated==1.2.14 ; python_version >= "3.7" and python_version < "4.0" dill==0.3.7 ; python_full_version >= "3.7.2" and python_version < "4.0" distlib==0.3.7 ; python_version >= "3.7" and python_version < "4.0" distro==1.8.0 ; python_version >= "3.7" and python_version < "4.0" -dns-lexicon==3.14.1 ; python_version >= "3.7" and python_version < "4.0" +dns-lexicon==3.15.1 ; python_version >= "3.7" and python_version < "4.0" dnspython==2.3.0 ; python_version >= "3.7" and python_version < "4.0" docutils==0.18.1 ; python_version >= "3.7" and python_version < "4.0" dulwich==0.20.50 ; python_version >= "3.7" and python_version < "4.0" @@ -49,10 +49,10 @@ execnet==2.0.2 ; python_version >= "3.7" and python_version < "4.0" fabric==3.2.2 ; python_version >= "3.7" and python_version < "4.0" filelock==3.12.2 ; python_version >= "3.7" and python_version < "4.0" google-api-core==2.12.0 ; python_version >= "3.7" and python_version < "4.0" -google-api-python-client==2.102.0 ; python_version >= "3.7" and python_version < "4.0" +google-api-python-client==2.104.0 ; python_version >= "3.7" and python_version < "4.0" google-auth-httplib2==0.1.1 ; python_version >= "3.7" and python_version < "4.0" -google-auth==2.23.2 ; python_version >= "3.7" and python_version < "4.0" -googleapis-common-protos==1.60.0 ; python_version >= "3.7" and python_version < "4.0" +google-auth==2.23.3 ; python_version >= "3.7" and python_version < "4.0" +googleapis-common-protos==1.61.0 ; python_version >= "3.7" and python_version < "4.0" html5lib==1.1 ; python_version >= "3.7" and python_version < "4.0" httplib2==0.22.0 ; python_version >= "3.7" and python_version < "4.0" idna==3.4 ; python_version >= "3.7" and python_version < "4.0" @@ -94,7 +94,7 @@ parsedatetime==2.6 ; python_version >= "3.7" and python_version < "4.0" parso==0.8.3 ; python_version >= "3.7" and python_version < "4.0" pexpect==4.8.0 ; python_version >= "3.7" and python_version < "4.0" pickleshare==0.7.5 ; python_version >= "3.7" and python_version < "4.0" -pip==23.2.1 ; python_version >= "3.7" and python_version < "4.0" +pip==23.3 ; python_version >= "3.7" and python_version < "4.0" pkginfo==1.9.6 ; python_version >= "3.7" and python_version < "4.0" pkgutil-resolve-name==1.3.10 ; python_version >= "3.7" and python_version < "3.9" platformdirs==2.6.2 ; python_version < "4.0" and python_version >= "3.7" @@ -116,6 +116,7 @@ pylint==2.15.5 ; python_full_version >= "3.7.2" and python_version < "4.0" pynacl==1.5.0 ; python_version >= "3.7" and python_version < "4.0" pynsist==2.7 ; python_version >= "3.7" and python_version < "4.0" pyopenssl==23.2.0 ; python_version >= "3.7" and python_version < "4.0" +pyotp==2.9.0 ; python_version >= "3.7" and python_version < "4.0" pyparsing==3.1.1 ; python_version >= "3.7" and python_version < "4.0" pyrfc3339==1.1 ; python_version >= "3.7" and python_version < "4.0" pyrsistent==0.19.3 ; python_version >= "3.7" and python_version < "4.0" @@ -156,7 +157,7 @@ sphinxcontrib-jquery==4.1 ; python_version >= "3.7" and python_version < "4.0" sphinxcontrib-jsmath==1.0.1 ; python_version >= "3.7" and python_version < "4.0" sphinxcontrib-qthelp==1.0.3 ; python_version >= "3.7" and python_version < "4.0" sphinxcontrib-serializinghtml==1.1.5 ; python_version >= "3.7" and python_version < "4.0" -tldextract==3.6.0 ; python_version >= "3.7" and python_version < "4.0" +tldextract==4.0.0 ; python_version >= "3.7" and python_version < "4.0" tomli==2.0.1 ; python_version >= "3.7" and python_full_version <= "3.11.0a6" tomlkit==0.12.1 ; python_version < "4.0" and python_version >= "3.7" tox==3.28.0 ; python_version >= "3.7" and python_version < "4.0" @@ -168,14 +169,14 @@ types-pyopenssl==23.2.0.2 ; python_version >= "3.7" and python_version < "4.0" types-pyrfc3339==1.1.1.5 ; python_version >= "3.7" and python_version < "4.0" types-python-dateutil==2.8.19.14 ; python_version >= "3.7" and python_version < "4.0" types-pytz==2023.3.1.1 ; python_version >= "3.7" and python_version < "4.0" -types-pywin32==306.0.0.4 ; python_version >= "3.7" and python_version < "4.0" -types-requests==2.31.0.2 ; python_version >= "3.7" and python_version < "4.0" +types-pywin32==306.0.0.5 ; python_version >= "3.7" and python_version < "4.0" +types-requests==2.31.0.6 ; python_version >= "3.7" and python_version < "4.0" types-setuptools==68.2.0.0 ; python_version >= "3.7" and python_version < "4.0" types-six==1.16.21.9 ; python_version >= "3.7" and python_version < "4.0" types-urllib3==1.26.25.14 ; python_version >= "3.7" and python_version < "4.0" typing-extensions==4.7.1 ; python_version >= "3.7" and python_version < "4.0" uritemplate==4.1.1 ; python_version >= "3.7" and python_version < "4.0" -urllib3==1.26.17 ; python_version >= "3.7" and python_version < "4.0" +urllib3==1.26.18 ; python_version < "4.0" and python_version >= "3.7" virtualenv==20.21.1 ; python_version >= "3.7" and python_version < "4.0" wcwidth==0.2.8 ; python_version >= "3.7" and python_version < "4.0" webencodings==0.5.1 ; python_version >= "3.7" and python_version < "4.0"