mirror of
https://github.com/certbot/certbot.git
synced 2026-07-28 00:24:35 +02:00
Upgrade pylint (#8855)
This is part of https://github.com/certbot/certbot/issues/8782. I took it on now because the currently pinned version of `pylint` doesn't work with newer versions of `poetry` which I wanted to upgrade as part of https://github.com/certbot/certbot/issues/8787. To say a bit more about the specific changes in this PR: * Newer versions of `pylint` complain if `Popen` isn't used as a context manager. Instead of making this change, I switched to using `subprocess.run` which is simpler and [recommended in the Python docs](https://docs.python.org/3/library/subprocess.html#using-the-subprocess-module). I also disabled this check in a few places where no longer using `Popen` would require significant refactoring. * The deleted code in `certbot/certbot/_internal/renewal.py` is cruft since https://github.com/certbot/certbot/pull/8685. * The unused argument to `enable_mod` in the Apache plugin is used in some over the override classes that subclass that class. * unpin pylint and repin dependencies * disable raise-missing-from * disable wrong-input-order * remove unused code * misc lint fixes * remove unused import * various lint fixes
This commit is contained in:
@@ -56,7 +56,18 @@ extension-pkg-whitelist=pywintypes,win32api,win32file,win32security
|
||||
# See https://github.com/PyCQA/pylint/issues/1498.
|
||||
# 3) Same as point 2 for no-value-for-parameter.
|
||||
# See https://github.com/PyCQA/pylint/issues/2820.
|
||||
disable=fixme,locally-disabled,locally-enabled,bad-continuation,no-self-use,invalid-name,cyclic-import,duplicate-code,design,import-outside-toplevel,useless-object-inheritance,unsubscriptable-object,no-value-for-parameter,no-else-return,no-else-raise,no-else-break,no-else-continue
|
||||
# 4) raise-missing-from makes it an error to raise an exception from except
|
||||
# block without using explicit exception chaining. While explicit exception
|
||||
# chaining results in a slightly more informative traceback, I don't think
|
||||
# it's beneficial enough for us to change all of our current instances and
|
||||
# give Certbot developers errors about this when they're working on new code
|
||||
# in the future. You can read more about exception chaining and this pylint
|
||||
# check at
|
||||
# https://blog.ram.rachum.com/post/621791438475296768/improving-python-exception-chaining-with.
|
||||
# 5) wrong-import-order generates false positives and a pylint developer
|
||||
# suggests that people using isort should disable this check at
|
||||
# https://github.com/PyCQA/pylint/issues/3817#issuecomment-687892090.
|
||||
disable=fixme,locally-disabled,locally-enabled,bad-continuation,no-self-use,invalid-name,cyclic-import,duplicate-code,design,import-outside-toplevel,useless-object-inheritance,unsubscriptable-object,no-value-for-parameter,no-else-return,no-else-raise,no-else-break,no-else-continue,raise-missing-from,wrong-import-order
|
||||
|
||||
[REPORTS]
|
||||
|
||||
|
||||
@@ -220,13 +220,14 @@ def _get_runtime_cfg(command):
|
||||
|
||||
"""
|
||||
try:
|
||||
proc = subprocess.Popen(
|
||||
proc = subprocess.run(
|
||||
command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True,
|
||||
check=False,
|
||||
env=util.env_no_snap_for_external_calls())
|
||||
stdout, stderr = proc.communicate()
|
||||
stdout, stderr = proc.stdout, proc.stderr
|
||||
|
||||
except (OSError, ValueError):
|
||||
logger.error(
|
||||
|
||||
@@ -136,6 +136,6 @@ def assertEqualPathsList(first, second): # pragma: no cover
|
||||
if any(isPass(path) for path in second):
|
||||
return
|
||||
for fpath in first:
|
||||
assert any([fnmatch.fnmatch(fpath, spath) for spath in second])
|
||||
assert any(fnmatch.fnmatch(fpath, spath) for spath in second)
|
||||
for spath in second:
|
||||
assert any([fnmatch.fnmatch(fpath, spath) for fpath in first])
|
||||
assert any(fnmatch.fnmatch(fpath, spath) for fpath in first)
|
||||
|
||||
@@ -2396,7 +2396,7 @@ class ApacheConfigurator(common.Installer):
|
||||
vhost.enabled = True
|
||||
return
|
||||
|
||||
def enable_mod(self, mod_name, temp=False):
|
||||
def enable_mod(self, mod_name, temp=False): # pylint: disable=unused-argument
|
||||
"""Enables module in Apache.
|
||||
|
||||
Both enables and reloads Apache so module is active.
|
||||
|
||||
@@ -49,10 +49,11 @@ class MultipleVhostsTestDebian(util.ApacheTest):
|
||||
|
||||
@mock.patch("certbot.util.run_script")
|
||||
@mock.patch("certbot.util.exe_exists")
|
||||
@mock.patch("certbot_apache._internal.apache_util.subprocess.Popen")
|
||||
def test_enable_mod(self, mock_popen, mock_exe_exists, mock_run_script):
|
||||
mock_popen().communicate.return_value = ("Define: DUMP_RUN_CFG", "")
|
||||
mock_popen().returncode = 0
|
||||
@mock.patch("certbot_apache._internal.apache_util.subprocess.run")
|
||||
def test_enable_mod(self, mock_run, mock_exe_exists, mock_run_script):
|
||||
mock_run.return_value.stdout = "Define: DUMP_RUN_CFG"
|
||||
mock_run.return_value.stderr = ""
|
||||
mock_run.return_value.returncode = 0
|
||||
mock_exe_exists.return_value = True
|
||||
|
||||
self.config.enable_mod("ssl")
|
||||
|
||||
@@ -305,17 +305,19 @@ class BasicParserTest(util.ParserTest):
|
||||
self.assertRaises(
|
||||
errors.PluginError, self.parser.update_runtime_variables)
|
||||
|
||||
@mock.patch("certbot_apache._internal.apache_util.subprocess.Popen")
|
||||
def test_update_runtime_vars_bad_ctl(self, mock_popen):
|
||||
mock_popen.side_effect = OSError
|
||||
@mock.patch("certbot_apache._internal.apache_util.subprocess.run")
|
||||
def test_update_runtime_vars_bad_ctl(self, mock_run):
|
||||
mock_run.side_effect = OSError
|
||||
self.assertRaises(
|
||||
errors.MisconfigurationError,
|
||||
self.parser.update_runtime_variables)
|
||||
|
||||
@mock.patch("certbot_apache._internal.apache_util.subprocess.Popen")
|
||||
def test_update_runtime_vars_bad_exit(self, mock_popen):
|
||||
mock_popen().communicate.return_value = ("", "")
|
||||
mock_popen.returncode = -1
|
||||
@mock.patch("certbot_apache._internal.apache_util.subprocess.run")
|
||||
def test_update_runtime_vars_bad_exit(self, mock_run):
|
||||
mock_proc = mock_run.return_value
|
||||
mock_proc.stdout = ""
|
||||
mock_proc.stderr = ""
|
||||
mock_proc.returncode = -1
|
||||
self.assertRaises(
|
||||
errors.MisconfigurationError,
|
||||
self.parser.update_runtime_variables)
|
||||
|
||||
@@ -51,6 +51,7 @@ class IntegrationTestsContext(certbot_context.IntegrationTestsContext):
|
||||
with open(self.nginx_config_path, 'w') as file:
|
||||
file.write(self.nginx_config)
|
||||
|
||||
# pylint: disable=consider-using-with
|
||||
process = subprocess.Popen(['nginx', '-c', self.nginx_config_path, '-g', 'daemon off;'])
|
||||
|
||||
assert process.poll() is None
|
||||
|
||||
@@ -240,6 +240,7 @@ class ACMEServer:
|
||||
if not env:
|
||||
env = os.environ
|
||||
stdout = sys.stderr if force_stderr else self._stdout
|
||||
# pylint: disable=consider-using-with
|
||||
process = subprocess.Popen(
|
||||
command, stdout=stdout, stderr=subprocess.STDOUT, cwd=cwd, env=env
|
||||
)
|
||||
|
||||
@@ -83,6 +83,7 @@ class DNSServer:
|
||||
def _start_bind(self):
|
||||
"""Launch the BIND9 server as a Docker container"""
|
||||
addr_str = "{}:{}".format(BIND_BIND_ADDRESS[0], BIND_BIND_ADDRESS[1])
|
||||
# pylint: disable=consider-using-with
|
||||
self.process = subprocess.Popen(
|
||||
[
|
||||
"docker",
|
||||
|
||||
@@ -985,13 +985,14 @@ class NginxConfigurator(common.Installer):
|
||||
Unable to run Nginx version command
|
||||
"""
|
||||
try:
|
||||
proc = subprocess.Popen(
|
||||
proc = subprocess.run(
|
||||
[self.conf('ctl'), "-c", self.nginx_conf, "-V"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True,
|
||||
check=False,
|
||||
env=util.env_no_snap_for_external_calls())
|
||||
text = proc.communicate()[1] # nginx prints output to stderr
|
||||
text = proc.stderr # nginx prints output to stderr
|
||||
except (OSError, ValueError) as error:
|
||||
logger.debug(str(error), exc_info=True)
|
||||
raise errors.PluginError(
|
||||
@@ -1224,10 +1225,9 @@ def nginx_restart(nginx_ctl, nginx_conf, sleep_duration):
|
||||
try:
|
||||
reload_output: Text = u""
|
||||
with tempfile.TemporaryFile() as out:
|
||||
proc = subprocess.Popen([nginx_ctl, "-c", nginx_conf, "-s", "reload"],
|
||||
env=util.env_no_snap_for_external_calls(),
|
||||
stdout=out, stderr=out)
|
||||
proc.communicate()
|
||||
proc = subprocess.run([nginx_ctl, "-c", nginx_conf, "-s", "reload"],
|
||||
env=util.env_no_snap_for_external_calls(),
|
||||
stdout=out, stderr=out, check=False)
|
||||
out.seek(0)
|
||||
reload_output = out.read().decode("utf-8")
|
||||
|
||||
@@ -1237,9 +1237,8 @@ def nginx_restart(nginx_ctl, nginx_conf, sleep_duration):
|
||||
# Write to temporary files instead of piping because of communication issues on Arch
|
||||
# https://github.com/certbot/certbot/issues/4324
|
||||
with tempfile.TemporaryFile() as out:
|
||||
nginx_proc = subprocess.Popen([nginx_ctl, "-c", nginx_conf],
|
||||
stdout=out, stderr=out, env=util.env_no_snap_for_external_calls())
|
||||
nginx_proc.communicate()
|
||||
nginx_proc = subprocess.run([nginx_ctl, "-c", nginx_conf],
|
||||
stdout=out, stderr=out, env=util.env_no_snap_for_external_calls(), check=False)
|
||||
if nginx_proc.returncode != 0:
|
||||
out.seek(0)
|
||||
# Enter recovery routine...
|
||||
|
||||
@@ -42,15 +42,16 @@ class NginxConfiguratorTest(util.NginxTest):
|
||||
self.assertEqual(13, len(self.config.parser.parsed))
|
||||
|
||||
@mock.patch("certbot_nginx._internal.configurator.util.exe_exists")
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.Popen")
|
||||
def test_prepare_initializes_version(self, mock_popen, mock_exe_exists):
|
||||
mock_popen().communicate.return_value = (
|
||||
"", "\n".join(["nginx version: nginx/1.6.2",
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.run")
|
||||
def test_prepare_initializes_version(self, mock_run, mock_exe_exists):
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = "\n".join(
|
||||
["nginx version: nginx/1.6.2",
|
||||
"built by clang 6.0 (clang-600.0.56)"
|
||||
" (based on LLVM 3.5svn)",
|
||||
"TLS SNI support enabled",
|
||||
"configure arguments: --prefix=/usr/local/Cellar/"
|
||||
"nginx/1.6.2 --with-http_ssl_module"]))
|
||||
"nginx/1.6.2 --with-http_ssl_module"])
|
||||
|
||||
mock_exe_exists.return_value = True
|
||||
|
||||
@@ -347,141 +348,149 @@ class NginxConfiguratorTest(util.NginxTest):
|
||||
self.assertEqual(mock_revert.call_count, 1)
|
||||
self.assertEqual(mock_restart.call_count, 2)
|
||||
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.Popen")
|
||||
def test_get_version(self, mock_popen):
|
||||
mock_popen().communicate.return_value = (
|
||||
"", "\n".join(["nginx version: nginx/1.4.2",
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.run")
|
||||
def test_get_version(self, mock_run):
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = "\n".join(
|
||||
["nginx version: nginx/1.4.2",
|
||||
"built by clang 6.0 (clang-600.0.56)"
|
||||
" (based on LLVM 3.5svn)",
|
||||
"TLS SNI support enabled",
|
||||
"configure arguments: --prefix=/usr/local/Cellar/"
|
||||
"nginx/1.6.2 --with-http_ssl_module"]))
|
||||
"nginx/1.6.2 --with-http_ssl_module"])
|
||||
self.assertEqual(self.config.get_version(), (1, 4, 2))
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", "\n".join(["nginx version: nginx/0.9",
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = "\n".join(
|
||||
["nginx version: nginx/0.9",
|
||||
"built by clang 6.0 (clang-600.0.56)"
|
||||
" (based on LLVM 3.5svn)",
|
||||
"TLS SNI support enabled",
|
||||
"configure arguments: --with-http_ssl_module"]))
|
||||
"configure arguments: --with-http_ssl_module"])
|
||||
self.assertEqual(self.config.get_version(), (0, 9))
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", "\n".join(["blah 0.0.1",
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = "\n".join(
|
||||
["blah 0.0.1",
|
||||
"built by clang 6.0 (clang-600.0.56)"
|
||||
" (based on LLVM 3.5svn)",
|
||||
"TLS SNI support enabled",
|
||||
"configure arguments: --with-http_ssl_module"]))
|
||||
"configure arguments: --with-http_ssl_module"])
|
||||
self.assertRaises(errors.PluginError, self.config.get_version)
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", "\n".join(["nginx version: nginx/1.4.2",
|
||||
"TLS SNI support enabled"]))
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = "\n".join(
|
||||
["nginx version: nginx/1.4.2",
|
||||
"TLS SNI support enabled"])
|
||||
self.assertRaises(errors.PluginError, self.config.get_version)
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", "\n".join(["nginx version: nginx/1.4.2",
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = "\n".join(
|
||||
["nginx version: nginx/1.4.2",
|
||||
"built by clang 6.0 (clang-600.0.56)"
|
||||
" (based on LLVM 3.5svn)",
|
||||
"configure arguments: --with-http_ssl_module"]))
|
||||
"configure arguments: --with-http_ssl_module"])
|
||||
self.assertRaises(errors.PluginError, self.config.get_version)
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", "\n".join(["nginx version: nginx/0.8.1",
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = "\n".join(
|
||||
["nginx version: nginx/0.8.1",
|
||||
"built by clang 6.0 (clang-600.0.56)"
|
||||
" (based on LLVM 3.5svn)",
|
||||
"TLS SNI support enabled",
|
||||
"configure arguments: --with-http_ssl_module"]))
|
||||
"configure arguments: --with-http_ssl_module"])
|
||||
self.assertRaises(errors.NotSupportedError, self.config.get_version)
|
||||
|
||||
mock_popen.side_effect = OSError("Can't find program")
|
||||
mock_run.side_effect = OSError("Can't find program")
|
||||
self.assertRaises(errors.PluginError, self.config.get_version)
|
||||
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.Popen")
|
||||
def test_get_openssl_version(self, mock_popen):
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.run")
|
||||
def test_get_openssl_version(self, mock_run):
|
||||
# pylint: disable=protected-access
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
built with OpenSSL 1.0.2g 1 Mar 2016
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
"""
|
||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2g")
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
built with OpenSSL 1.0.2-beta1 1 Mar 2016
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
"""
|
||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2-beta1")
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
built with OpenSSL 1.0.2 1 Mar 2016
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
"""
|
||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2")
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
built with OpenSSL 1.0.2g 1 Mar 2016 (running with OpenSSL 1.0.2a 1 Mar 2016)
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
"""
|
||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2a")
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
built with LibreSSL 2.2.2
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
"""
|
||||
self.assertEqual(self.config._get_openssl_version(), "")
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
mock_run.return_value.stdout = ""
|
||||
mock_run.return_value.stderr = """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
"""
|
||||
self.assertEqual(self.config._get_openssl_version(), "")
|
||||
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.Popen")
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.run")
|
||||
@mock.patch("certbot_nginx._internal.configurator.time")
|
||||
def test_nginx_restart(self, mock_time, mock_popen):
|
||||
mocked = mock_popen()
|
||||
mocked.communicate.return_value = ('', '')
|
||||
def test_nginx_restart(self, mock_time, mock_run):
|
||||
mocked = mock_run.return_value
|
||||
mocked.stdout = ''
|
||||
mocked.stderr = ''
|
||||
mocked.returncode = 0
|
||||
self.config.restart()
|
||||
self.assertEqual(mocked.communicate.call_count, 1)
|
||||
self.assertEqual(mock_run.call_count, 1)
|
||||
mock_time.sleep.assert_called_once_with(0.1234)
|
||||
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.Popen")
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.run")
|
||||
@mock.patch("certbot_nginx._internal.configurator.logger.debug")
|
||||
def test_nginx_restart_fail(self, mock_log_debug, mock_popen):
|
||||
mocked = mock_popen()
|
||||
mocked.communicate.return_value = ('', '')
|
||||
def test_nginx_restart_fail(self, mock_log_debug, mock_run):
|
||||
mocked = mock_run.return_value
|
||||
mocked.stdout = ''
|
||||
mocked.stderr = ''
|
||||
mocked.returncode = 1
|
||||
self.assertRaises(errors.MisconfigurationError, self.config.restart)
|
||||
self.assertEqual(mocked.communicate.call_count, 2)
|
||||
self.assertEqual(mock_run.call_count, 2)
|
||||
mock_log_debug.assert_called_once_with("nginx reload failed:\n%s", "")
|
||||
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.Popen")
|
||||
def test_no_nginx_start(self, mock_popen):
|
||||
mock_popen.side_effect = OSError("Can't find program")
|
||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.run")
|
||||
def test_no_nginx_start(self, mock_run):
|
||||
mock_run.side_effect = OSError("Can't find program")
|
||||
self.assertRaises(errors.MisconfigurationError, self.config.restart)
|
||||
|
||||
@mock.patch("certbot.util.run_script")
|
||||
|
||||
@@ -1361,7 +1361,7 @@ def make_displayer(config: configuration.NamespaceConfig
|
||||
|
||||
if config.quiet:
|
||||
config.noninteractive_mode = True
|
||||
devnull = open(os.devnull, "w")
|
||||
devnull = open(os.devnull, "w") # pylint: disable=consider-using-with
|
||||
displayer = display_util.NoninteractiveDisplay(devnull)
|
||||
elif config.noninteractive_mode:
|
||||
displayer = display_util.NoninteractiveDisplay(sys.stdout)
|
||||
|
||||
@@ -134,7 +134,7 @@ to serve all files under specified web root ({0})."""
|
||||
"webroot when using the webroot plugin.")
|
||||
return None if index == 0 else known_webroots[index - 1] # code == display_util.OK
|
||||
|
||||
def _prompt_for_new_webroot(self, domain, allowraise=False): # pylint: no-self-use
|
||||
def _prompt_for_new_webroot(self, domain, allowraise=False):
|
||||
code, webroot = ops.validated_directory(
|
||||
_validate_webroot,
|
||||
"Input the webroot for {0}:".format(domain),
|
||||
@@ -192,7 +192,7 @@ to serve all files under specified web root ({0})."""
|
||||
finally:
|
||||
filesystem.umask(old_umask)
|
||||
|
||||
def _get_validation_path(self, root_path, achall): # pylint: no-self-use
|
||||
def _get_validation_path(self, root_path, achall):
|
||||
return os.path.join(root_path, achall.chall.encode("token"))
|
||||
|
||||
def _perform_single(self, achall):
|
||||
|
||||
@@ -14,7 +14,6 @@ from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||
import OpenSSL
|
||||
import zope.component
|
||||
|
||||
from certbot import crypto_util
|
||||
@@ -306,13 +305,6 @@ def should_renew(config, lineage):
|
||||
|
||||
def _avoid_invalidating_lineage(config, lineage, original_server):
|
||||
"""Do not renew a valid cert with one from a staging server!"""
|
||||
# Some lineages may have begun with --staging, but then had production
|
||||
# certificates added to them
|
||||
with open(lineage.cert) as the_file:
|
||||
contents = the_file.read()
|
||||
latest_cert = OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_PEM, contents)
|
||||
|
||||
if util.is_staging(config.server):
|
||||
if not util.is_staging(original_server):
|
||||
if not config.break_my_certs:
|
||||
|
||||
@@ -115,35 +115,36 @@ def underscores_for_unsupported_characters_in_path(path: str) -> str:
|
||||
def execute_command(cmd_name: str, shell_cmd: str, env: Optional[dict] = None) -> Tuple[str, str]:
|
||||
"""
|
||||
Run a command:
|
||||
- on Linux command will be run by the standard shell selected with Popen(shell=True)
|
||||
- on Linux command will be run by the standard shell selected with
|
||||
subprocess.run(shell=True)
|
||||
- on Windows command will be run in a Powershell shell
|
||||
|
||||
:param str cmd_name: the user facing name of the hook being run
|
||||
:param str shell_cmd: shell command to execute
|
||||
:param dict env: environ to pass into Popen
|
||||
:param dict env: environ to pass into subprocess.run
|
||||
|
||||
:returns: `tuple` (`str` stderr, `str` stdout)
|
||||
"""
|
||||
logger.info("Running %s command: %s", cmd_name, shell_cmd)
|
||||
|
||||
if POSIX_MODE:
|
||||
cmd = subprocess.Popen(shell_cmd, shell=True, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, universal_newlines=True,
|
||||
env=env)
|
||||
proc = subprocess.run(shell_cmd, shell=True, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, universal_newlines=True,
|
||||
check=False, env=env)
|
||||
else:
|
||||
line = ['powershell.exe', '-Command', shell_cmd]
|
||||
cmd = subprocess.Popen(line, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
universal_newlines=True, env=env)
|
||||
proc = subprocess.run(line, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
universal_newlines=True, check=False, env=env)
|
||||
|
||||
# universal_newlines causes Popen.communicate()
|
||||
# to return str objects instead of bytes in Python 3
|
||||
out, err = cmd.communicate()
|
||||
# universal_newlines causes stdout and stderr to be str objects instead of
|
||||
# bytes in Python 3
|
||||
out, err = proc.stdout, proc.stderr
|
||||
base_cmd = os.path.basename(shell_cmd.split(None, 1)[0])
|
||||
if out:
|
||||
logger.info('Output from %s command %s:\n%s', cmd_name, base_cmd, out)
|
||||
if cmd.returncode != 0:
|
||||
if proc.returncode != 0:
|
||||
logger.error('%s command "%s" returned error code %d',
|
||||
cmd_name, shell_cmd, cmd.returncode)
|
||||
cmd_name, shell_cmd, proc.returncode)
|
||||
if err:
|
||||
logger.error('Error output from %s command %s:\n%s', cmd_name, base_cmd, err)
|
||||
return err, out
|
||||
|
||||
@@ -3,8 +3,8 @@ from datetime import datetime
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
import re
|
||||
import subprocess
|
||||
from subprocess import PIPE
|
||||
from subprocess import Popen
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
|
||||
@@ -50,11 +50,10 @@ class RevocationChecker:
|
||||
return
|
||||
|
||||
# New versions of openssl want -header var=val, old ones want -header var val
|
||||
test_host_format = Popen(["openssl", "ocsp", "-header", "var", "val"],
|
||||
test_host_format = subprocess.run(["openssl", "ocsp", "-header", "var", "val"],
|
||||
stdout=PIPE, stderr=PIPE, universal_newlines=True,
|
||||
env=util.env_no_snap_for_external_calls())
|
||||
_out, err = test_host_format.communicate()
|
||||
if "Missing =" in err:
|
||||
check=False, env=util.env_no_snap_for_external_calls())
|
||||
if "Missing =" in test_host_format.stderr:
|
||||
self.host_args = lambda host: ["Host=" + host]
|
||||
else:
|
||||
self.host_args = lambda host: ["Host", host]
|
||||
|
||||
@@ -198,6 +198,7 @@ class Reverter:
|
||||
Read the file returning the lines, and a pointer to the end of the file.
|
||||
|
||||
"""
|
||||
# pylint: disable=consider-using-with
|
||||
# Open up filepath differently depending on if it already exists
|
||||
if os.path.isfile(filepath):
|
||||
op_fd = open(filepath, "r+")
|
||||
@@ -348,26 +349,18 @@ class Reverter:
|
||||
|
||||
"""
|
||||
commands_fp = os.path.join(self._get_cp_dir(temporary), "COMMANDS")
|
||||
command_file = None
|
||||
# It is strongly advised to set newline = '' on Python 3 with CSV,
|
||||
# and it fixes problems on Windows.
|
||||
kwargs = {'newline': ''}
|
||||
try:
|
||||
if os.path.isfile(commands_fp):
|
||||
command_file = open(commands_fp, "a", **kwargs) # type: ignore
|
||||
else:
|
||||
command_file = open(commands_fp, "w", **kwargs) # type: ignore
|
||||
|
||||
csvwriter = csv.writer(command_file)
|
||||
csvwriter.writerow(command)
|
||||
|
||||
mode = "a" if os.path.isfile(commands_fp) else "w"
|
||||
with open(commands_fp, mode, **kwargs) as f: # type: ignore
|
||||
csvwriter = csv.writer(f)
|
||||
csvwriter.writerow(command)
|
||||
except (IOError, OSError):
|
||||
logger.error("Unable to register undo command")
|
||||
raise errors.ReverterError(
|
||||
"Unable to register undo command.")
|
||||
finally:
|
||||
if command_file is not None:
|
||||
command_file.close()
|
||||
|
||||
def _get_cp_dir(self, temporary):
|
||||
"""Return the proper reverter directory."""
|
||||
|
||||
@@ -259,7 +259,7 @@ class FreezableMock:
|
||||
def _create_get_utility_mock():
|
||||
display = FreezableMock()
|
||||
# Use pylint code for disable to keep on single line under line length limit
|
||||
for name in interfaces.IDisplay.names(): # pylint: E1120
|
||||
for name in interfaces.IDisplay.names():
|
||||
if name != 'notification':
|
||||
frozen_mock = FreezableMock(frozen=True, func=_assert_valid_call)
|
||||
setattr(display, name, frozen_mock)
|
||||
@@ -284,7 +284,7 @@ def _create_get_utility_mock_with_stdout(stdout):
|
||||
|
||||
display = FreezableMock()
|
||||
# Use pylint code for disable to keep on single line under line length limit
|
||||
for name in interfaces.IDisplay.names(): # pylint: E1120
|
||||
for name in interfaces.IDisplay.names():
|
||||
if name == 'notification':
|
||||
frozen_mock = FreezableMock(frozen=True,
|
||||
func=_write_msg)
|
||||
|
||||
+14
-15
@@ -89,32 +89,31 @@ def env_no_snap_for_external_calls():
|
||||
def run_script(params, log=logger.error):
|
||||
"""Run the script with the given params.
|
||||
|
||||
:param list params: List of parameters to pass to Popen
|
||||
:param list params: List of parameters to pass to subprocess.run
|
||||
:param callable log: Logger method to use for errors
|
||||
|
||||
"""
|
||||
try:
|
||||
proc = subprocess.Popen(params,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True,
|
||||
env=env_no_snap_for_external_calls())
|
||||
proc = subprocess.run(params,
|
||||
check=False,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True,
|
||||
env=env_no_snap_for_external_calls())
|
||||
|
||||
except (OSError, ValueError):
|
||||
msg = "Unable to run the command: %s" % " ".join(params)
|
||||
log(msg)
|
||||
raise errors.SubprocessError(msg)
|
||||
|
||||
stdout, stderr = proc.communicate()
|
||||
|
||||
if proc.returncode != 0:
|
||||
msg = "Error while running %s.\n%s\n%s" % (
|
||||
" ".join(params), stdout, stderr)
|
||||
" ".join(params), proc.stdout, proc.stderr)
|
||||
# Enter recovery routine...
|
||||
log(msg)
|
||||
raise errors.SubprocessError(msg)
|
||||
|
||||
return stdout, stderr
|
||||
return proc.stdout, proc.stderr
|
||||
|
||||
|
||||
def exe_exists(exe):
|
||||
@@ -399,20 +398,20 @@ def get_python_os_info(pretty=False):
|
||||
os_ver = info[1]
|
||||
elif os_type.startswith('darwin'):
|
||||
try:
|
||||
proc = subprocess.Popen(
|
||||
proc = subprocess.run(
|
||||
["/usr/bin/sw_vers", "-productVersion"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
universal_newlines=True,
|
||||
check=False, universal_newlines=True,
|
||||
env=env_no_snap_for_external_calls(),
|
||||
)
|
||||
except OSError:
|
||||
proc = subprocess.Popen(
|
||||
proc = subprocess.run(
|
||||
["sw_vers", "-productVersion"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
universal_newlines=True,
|
||||
check=False, universal_newlines=True,
|
||||
env=env_no_snap_for_external_calls(),
|
||||
)
|
||||
os_ver = proc.communicate()[0].rstrip('\n')
|
||||
os_ver = proc.stdout.rstrip('\n')
|
||||
elif os_type.startswith('freebsd'):
|
||||
# eg "9.3-RC3-p1"
|
||||
os_ver = os_ver.partition("-")[0]
|
||||
|
||||
@@ -25,14 +25,15 @@ class ExecuteTest(unittest.TestCase):
|
||||
def _test_common(self, returncode, stdout, stderr):
|
||||
given_command = "foo"
|
||||
given_name = "foo-hook"
|
||||
with mock.patch("certbot.compat.misc.subprocess.Popen") as mock_popen:
|
||||
mock_popen.return_value.communicate.return_value = (stdout, stderr)
|
||||
mock_popen.return_value.returncode = returncode
|
||||
with mock.patch("certbot.compat.misc.subprocess.run") as mock_run:
|
||||
mock_run.return_value.stdout = stdout
|
||||
mock_run.return_value.stderr = stderr
|
||||
mock_run.return_value.returncode = returncode
|
||||
with mock.patch("certbot.compat.misc.logger") as mock_logger:
|
||||
self.assertEqual(self._call(given_name, given_command), (stderr, stdout))
|
||||
|
||||
executed_command = mock_popen.call_args[1].get(
|
||||
"args", mock_popen.call_args[0][0])
|
||||
executed_command = mock_run.call_args[1].get(
|
||||
"args", mock_run.call_args[0][0])
|
||||
if os.name == 'nt':
|
||||
expected_command = ['powershell.exe', '-Command', given_command]
|
||||
else:
|
||||
|
||||
+19
-23
@@ -1078,29 +1078,25 @@ class MainTest(test_util.ConfigTestCase):
|
||||
with test_util.patch_get_utility() as mock_get_utility:
|
||||
if not quiet_mode:
|
||||
mock_get_utility().notification.side_effect = write_msg
|
||||
with mock.patch('certbot._internal.main.renewal.OpenSSL') as mock_ssl:
|
||||
mock_latest = mock.MagicMock()
|
||||
mock_latest.get_issuer.return_value = "Artificial pretend"
|
||||
mock_ssl.crypto.load_certificate.return_value = mock_latest
|
||||
with mock.patch('certbot._internal.main.renewal.crypto_util') \
|
||||
as mock_crypto_util:
|
||||
mock_crypto_util.notAfter.return_value = expiry_date
|
||||
with mock.patch('certbot._internal.eff.handle_subscription'):
|
||||
if not args:
|
||||
args = ['-d', 'isnot.org', '-a', 'standalone', 'certonly']
|
||||
if extra_args:
|
||||
args += extra_args
|
||||
try:
|
||||
ret, stdout, _, _ = self._call(args, stdout)
|
||||
if ret:
|
||||
print("Returned", ret)
|
||||
raise AssertionError(ret)
|
||||
assert not error_expected, "renewal should have errored"
|
||||
except: # pylint: disable=bare-except
|
||||
if not error_expected:
|
||||
raise AssertionError(
|
||||
"Unexpected renewal error:\n" +
|
||||
traceback.format_exc())
|
||||
with mock.patch('certbot._internal.main.renewal.crypto_util') \
|
||||
as mock_crypto_util:
|
||||
mock_crypto_util.notAfter.return_value = expiry_date
|
||||
with mock.patch('certbot._internal.eff.handle_subscription'):
|
||||
if not args:
|
||||
args = ['-d', 'isnot.org', '-a', 'standalone', 'certonly']
|
||||
if extra_args:
|
||||
args += extra_args
|
||||
try:
|
||||
ret, stdout, _, _ = self._call(args, stdout)
|
||||
if ret:
|
||||
print("Returned", ret)
|
||||
raise AssertionError(ret)
|
||||
assert not error_expected, "renewal should have errored"
|
||||
except: # pylint: disable=bare-except
|
||||
if not error_expected:
|
||||
raise AssertionError(
|
||||
"Unexpected renewal error:\n" +
|
||||
traceback.format_exc())
|
||||
|
||||
if should_renew:
|
||||
if reuse_key:
|
||||
|
||||
@@ -40,11 +40,9 @@ class OCSPTestOpenSSL(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from certbot import ocsp
|
||||
with mock.patch('certbot.ocsp.Popen') as mock_popen:
|
||||
with mock.patch('certbot.ocsp.subprocess.run') as mock_run:
|
||||
with mock.patch('certbot.util.exe_exists') as mock_exists:
|
||||
mock_communicate = mock.MagicMock()
|
||||
mock_communicate.communicate.return_value = (None, out)
|
||||
mock_popen.return_value = mock_communicate
|
||||
mock_run.stderr = out
|
||||
mock_exists.return_value = True
|
||||
self.checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True)
|
||||
|
||||
@@ -52,28 +50,26 @@ class OCSPTestOpenSSL(unittest.TestCase):
|
||||
pass
|
||||
|
||||
@mock.patch('certbot.ocsp.logger.info')
|
||||
@mock.patch('certbot.ocsp.Popen')
|
||||
@mock.patch('certbot.ocsp.subprocess.run')
|
||||
@mock.patch('certbot.util.exe_exists')
|
||||
def test_init(self, mock_exists, mock_popen, mock_log):
|
||||
mock_communicate = mock.MagicMock()
|
||||
mock_communicate.communicate.return_value = (None, out)
|
||||
mock_popen.return_value = mock_communicate
|
||||
def test_init(self, mock_exists, mock_run, mock_log):
|
||||
mock_run.return_value.stderr = out
|
||||
mock_exists.return_value = True
|
||||
|
||||
from certbot import ocsp
|
||||
checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True)
|
||||
self.assertEqual(mock_popen.call_count, 1)
|
||||
self.assertEqual(mock_run.call_count, 1)
|
||||
self.assertEqual(checker.host_args("x"), ["Host=x"])
|
||||
|
||||
mock_communicate.communicate.return_value = (None, out.partition("\n")[2])
|
||||
mock_run.return_value.stderr = out.partition("\n")[2]
|
||||
checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True)
|
||||
self.assertEqual(checker.host_args("x"), ["Host", "x"])
|
||||
self.assertIs(checker.broken, False)
|
||||
|
||||
mock_exists.return_value = False
|
||||
mock_popen.call_count = 0
|
||||
mock_run.call_count = 0
|
||||
checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True)
|
||||
self.assertEqual(mock_popen.call_count, 0)
|
||||
self.assertEqual(mock_run.call_count, 0)
|
||||
self.assertEqual(mock_log.call_count, 1)
|
||||
self.assertIs(checker.broken, True)
|
||||
|
||||
|
||||
+13
-17
@@ -59,26 +59,26 @@ class RunScriptTest(unittest.TestCase):
|
||||
from certbot.util import run_script
|
||||
return run_script(params)
|
||||
|
||||
@mock.patch("certbot.util.subprocess.Popen")
|
||||
def test_default(self, mock_popen):
|
||||
@mock.patch("certbot.util.subprocess.run")
|
||||
def test_default(self, mock_run):
|
||||
"""These will be changed soon enough with reload."""
|
||||
mock_popen().returncode = 0
|
||||
mock_popen().communicate.return_value = ("stdout", "stderr")
|
||||
mock_run().returncode = 0
|
||||
mock_run().stdout = "stdout"
|
||||
mock_run().stderr = "stderr"
|
||||
|
||||
out, err = self._call(["test"])
|
||||
self.assertEqual(out, "stdout")
|
||||
self.assertEqual(err, "stderr")
|
||||
|
||||
@mock.patch("certbot.util.subprocess.Popen")
|
||||
def test_bad_process(self, mock_popen):
|
||||
mock_popen.side_effect = OSError
|
||||
@mock.patch("certbot.util.subprocess.run")
|
||||
def test_bad_process(self, mock_run):
|
||||
mock_run.side_effect = OSError
|
||||
|
||||
self.assertRaises(errors.SubprocessError, self._call, ["test"])
|
||||
|
||||
@mock.patch("certbot.util.subprocess.Popen")
|
||||
def test_failure(self, mock_popen):
|
||||
mock_popen().communicate.return_value = ("", "")
|
||||
mock_popen().returncode = 1
|
||||
@mock.patch("certbot.util.subprocess.run")
|
||||
def test_failure(self, mock_run):
|
||||
mock_run().returncode = 1
|
||||
|
||||
self.assertRaises(errors.SubprocessError, self._call, ["test"])
|
||||
|
||||
@@ -557,12 +557,8 @@ class OsInfoTest(unittest.TestCase):
|
||||
|
||||
with mock.patch('platform.system_alias',
|
||||
return_value=('darwin', '', '')):
|
||||
with mock.patch("subprocess.Popen") as popen_mock:
|
||||
comm_mock = mock.Mock()
|
||||
comm_attrs = {'communicate.return_value':
|
||||
('42.42.42', 'error')}
|
||||
comm_mock.configure_mock(**comm_attrs)
|
||||
popen_mock.return_value = comm_mock
|
||||
with mock.patch("subprocess.run") as run_mock:
|
||||
run_mock().stdout = '42.42.42'
|
||||
self.assertEqual(cbutil.get_python_os_info()[0], 'darwin')
|
||||
self.assertEqual(cbutil.get_python_os_info()[1], '42.42.42')
|
||||
|
||||
|
||||
+3
-3
@@ -264,9 +264,9 @@ def subprocess_call(args):
|
||||
:rtype: tuple
|
||||
|
||||
"""
|
||||
process = subprocess.Popen(args, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, universal_newlines=True)
|
||||
out, err = process.communicate()
|
||||
process = subprocess.run(args, stdout=subprocess.PIPE, check=False,
|
||||
stderr=subprocess.PIPE, universal_newlines=True)
|
||||
out, err = process.stdout, process.stderr
|
||||
logger.debug('Return code was %d', process.returncode)
|
||||
log_output(logging.DEBUG, out, err)
|
||||
return process.returncode, out, err
|
||||
|
||||
@@ -58,10 +58,9 @@ cython = "*"
|
||||
# needed. This dependency can be removed here once Certbot's support for the
|
||||
# 3rd party mock library has been dropped.
|
||||
mock = "*"
|
||||
# Upgrading coverage, pylint, pytest, and some of pytest's plugins causes many
|
||||
# test failures so let's pin these packages back for now.
|
||||
# Upgrading coverage, pytest, and some of pytest's plugins causes many test
|
||||
# failures so let's pin these packages back for now.
|
||||
coverage = "4.5.4"
|
||||
pylint = "2.4.3"
|
||||
pytest = "3.2.5"
|
||||
pytest-forked = "0.2"
|
||||
# We were originally pinning back python-augeas for certbot-auto because we
|
||||
|
||||
+19
-19
@@ -10,17 +10,17 @@ apacheconfig==0.3.2; python_version >= "3.6"
|
||||
apipkg==1.5; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
appdirs==1.4.4; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
appnope==0.1.2
|
||||
astroid==2.3.3; python_version >= "3.6"
|
||||
astroid==2.5.6; python_version >= "3.6" and python_version < "4.0"
|
||||
attrs==21.2.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
awscli==1.19.69; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0")
|
||||
awscli==1.19.77; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0")
|
||||
azure-devops==6.0.0b4; python_version >= "3.6"
|
||||
babel==2.9.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.4.0"
|
||||
backcall==0.2.0
|
||||
bcrypt==3.2.0; python_version >= "3.6"
|
||||
beautifulsoup4==4.9.3; python_version >= "3.6" and python_version < "4.0"
|
||||
bleach==3.3.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
boto3==1.17.69; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
botocore==1.20.69; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
boto3==1.17.77; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
botocore==1.20.77; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
cachecontrol==0.12.6; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
cached-property==1.5.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
|
||||
cachetools==4.2.2; python_version >= "3.5" and python_version < "4.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6")
|
||||
@@ -32,13 +32,13 @@ cleo==0.8.1; python_version >= "3.6" and python_full_version < "3.0.0" or python
|
||||
clikit==0.6.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
cloudflare==2.8.15; python_version >= "3.6"
|
||||
colorama==0.4.3; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0")
|
||||
configargparse==1.4; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
configargparse==1.4.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
configobj==5.0.6; python_version >= "3.6"
|
||||
coverage==4.5.4; (python_version >= "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0" and python_version < "4")
|
||||
crashtest==0.3.1; python_version >= "3.6" and python_version < "4.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0")
|
||||
cryptography==3.4.7; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "4.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0") and sys_platform == "linux" or python_full_version >= "3.5.0" and python_version >= "3.6" and python_version < "4.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0") and sys_platform == "linux"
|
||||
cython==0.29.23; (python_version >= "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0")
|
||||
decorator==5.0.7
|
||||
decorator==5.0.9
|
||||
deprecated==1.2.12; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.4.0"
|
||||
distlib==0.3.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
distro==1.5.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
|
||||
@@ -52,8 +52,8 @@ docutils==0.15.2; (python_version >= "2.6" and python_full_version < "3.0.0") or
|
||||
execnet==1.8.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
fabric==2.6.0; python_version >= "3.6"
|
||||
filelock==3.0.12; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.6" and python_full_version >= "3.5.0" and python_version < "4.0"
|
||||
google-api-core==1.26.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
google-api-python-client==2.3.0; python_version >= "3.6"
|
||||
google-api-core==1.28.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
google-api-python-client==2.5.0; python_version >= "3.6"
|
||||
google-auth-httplib2==0.1.0; python_version >= "3.6"
|
||||
google-auth==1.30.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
googleapis-common-protos==1.53.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
@@ -62,28 +62,28 @@ httplib2==0.19.1; python_version >= "3.6"
|
||||
idna==2.10; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.5.0" and python_version >= "3.6" and python_version < "4.0"
|
||||
imagesize==1.2.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.4.0"
|
||||
importlib-metadata==1.7.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0") or python_version >= "3.6" and python_full_version >= "3.5.0" and python_version < "3.8" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0")
|
||||
importlib-resources==5.1.2; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.7" or python_version >= "3.6" and python_full_version >= "3.5.0" and python_version < "3.7"
|
||||
importlib-resources==5.1.4; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.7" or python_version >= "3.6" and python_full_version >= "3.5.0" and python_version < "3.7"
|
||||
invoke==1.5.0; python_version >= "3.6"
|
||||
ipdb==0.13.7; python_version >= "3.6"
|
||||
ipython-genutils==0.2.0; python_version == "3.6"
|
||||
ipython==7.16.1; python_version == "3.6"
|
||||
ipython==7.23.1; python_version >= "3.7"
|
||||
isodate==0.6.0; python_version >= "3.6"
|
||||
isort==4.3.21; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.4.0"
|
||||
isort==5.8.0; python_version >= "3.6" and python_version < "4.0"
|
||||
jedi==0.18.0
|
||||
jeepney==0.6.0; python_version >= "3.6" and python_version < "4.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0") and sys_platform == "linux"
|
||||
jinja2==2.11.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
jinja2==3.0.1; python_version >= "3.6"
|
||||
jmespath==0.10.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
josepy==1.8.0; python_version >= "3.6"
|
||||
jsonlines==2.0.0; python_version >= "3.6"
|
||||
jsonpickle==2.0.0; python_version >= "3.6"
|
||||
jsonschema==3.2.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
|
||||
keyring==21.8.0; python_version >= "3.6" and python_version < "4.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0")
|
||||
lazy-object-proxy==1.4.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.4.0"
|
||||
lazy-object-proxy==1.6.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.6" and python_version < "4.0" and python_full_version >= "3.6.0"
|
||||
lockfile==0.12.2
|
||||
markupsafe==1.1.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
markupsafe==2.0.1; python_version >= "3.6"
|
||||
matplotlib-inline==0.1.2; python_version >= "3.7"
|
||||
mccabe==0.6.1; python_version >= "3.6"
|
||||
mccabe==0.6.1; python_version >= "3.6" and python_version < "4.0"
|
||||
mock==4.0.3; python_version >= "3.6"
|
||||
msgpack==1.0.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
msrest==0.6.21; python_version >= "3.6"
|
||||
@@ -105,7 +105,7 @@ ply==3.11; python_version >= "3.6"
|
||||
poetry-core==1.0.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
poetry==1.1.6; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
prompt-toolkit==3.0.3
|
||||
protobuf==3.16.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
protobuf==3.17.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
ptyprocess==0.7.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
py==1.10.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
pyasn1-modules==0.2.8; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
|
||||
@@ -115,7 +115,7 @@ pygithub==1.55; python_version >= "3.6"
|
||||
pygments==2.9.0
|
||||
pyjwt==2.1.0; python_version >= "3.6"
|
||||
pylev==1.3.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
pylint==2.4.3; python_version >= "3.5"
|
||||
pylint==2.8.2; python_version >= "3.6" and python_version < "4.0"
|
||||
pynacl==1.4.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.4.0"
|
||||
pynsist==2.7; python_version >= "3.6"
|
||||
pyopenssl==20.0.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
@@ -160,8 +160,8 @@ sphinxcontrib-qthelp==1.0.3; python_version >= "3.6"
|
||||
sphinxcontrib-serializinghtml==1.1.4; python_version >= "3.6"
|
||||
texttable==1.6.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
|
||||
tldextract==3.1.0; python_version >= "3.6" and python_version < "4.0"
|
||||
toml==0.10.2; python_version == "3.6" and python_full_version < "3.0.0" or python_version > "3.6" and python_full_version < "3.0.0" or python_version == "3.6" and python_full_version >= "3.5.0" or python_version > "3.6" and python_full_version >= "3.5.0"
|
||||
tomlkit==0.7.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
toml==0.10.2; python_version == "3.6" and python_full_version < "3.0.0" or python_version > "3.6" and python_full_version < "3.0.0" and python_version < "4.0" or python_version == "3.6" and python_full_version >= "3.5.0" or python_version > "3.6" and python_full_version >= "3.5.0" and python_version < "4.0"
|
||||
tomlkit==0.7.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
tox==3.23.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
tqdm==4.60.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.4.0"
|
||||
traitlets==4.3.3
|
||||
@@ -174,7 +174,7 @@ virtualenv==20.4.6; python_version >= "3.6" and python_full_version < "3.0.0" or
|
||||
wcwidth==0.2.5; python_version == "3.6"
|
||||
webencodings==0.5.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.0"
|
||||
websocket-client==0.59.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
wrapt==1.11.2; python_version >= "3.6" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.4.0")
|
||||
wrapt==1.12.1; python_version >= "3.6" and python_version < "4.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.4.0")
|
||||
yarg==0.1.9; python_version >= "3.6"
|
||||
zipp==3.4.1; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.7" or python_version >= "3.6" and python_full_version >= "3.5.0" and python_version < "3.7"
|
||||
zope.component==5.0.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
|
||||
|
||||
Reference in New Issue
Block a user