mirror of
https://github.com/certbot/certbot.git
synced 2026-08-03 00:22:04 +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.
|
# See https://github.com/PyCQA/pylint/issues/1498.
|
||||||
# 3) Same as point 2 for no-value-for-parameter.
|
# 3) Same as point 2 for no-value-for-parameter.
|
||||||
# See https://github.com/PyCQA/pylint/issues/2820.
|
# 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]
|
[REPORTS]
|
||||||
|
|
||||||
|
|||||||
@@ -220,13 +220,14 @@ def _get_runtime_cfg(command):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.run(
|
||||||
command,
|
command,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
universal_newlines=True,
|
universal_newlines=True,
|
||||||
|
check=False,
|
||||||
env=util.env_no_snap_for_external_calls())
|
env=util.env_no_snap_for_external_calls())
|
||||||
stdout, stderr = proc.communicate()
|
stdout, stderr = proc.stdout, proc.stderr
|
||||||
|
|
||||||
except (OSError, ValueError):
|
except (OSError, ValueError):
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|||||||
@@ -136,6 +136,6 @@ def assertEqualPathsList(first, second): # pragma: no cover
|
|||||||
if any(isPass(path) for path in second):
|
if any(isPass(path) for path in second):
|
||||||
return
|
return
|
||||||
for fpath in first:
|
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:
|
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
|
vhost.enabled = True
|
||||||
return
|
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.
|
"""Enables module in Apache.
|
||||||
|
|
||||||
Both enables and reloads Apache so module is active.
|
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.run_script")
|
||||||
@mock.patch("certbot.util.exe_exists")
|
@mock.patch("certbot.util.exe_exists")
|
||||||
@mock.patch("certbot_apache._internal.apache_util.subprocess.Popen")
|
@mock.patch("certbot_apache._internal.apache_util.subprocess.run")
|
||||||
def test_enable_mod(self, mock_popen, mock_exe_exists, mock_run_script):
|
def test_enable_mod(self, mock_run, mock_exe_exists, mock_run_script):
|
||||||
mock_popen().communicate.return_value = ("Define: DUMP_RUN_CFG", "")
|
mock_run.return_value.stdout = "Define: DUMP_RUN_CFG"
|
||||||
mock_popen().returncode = 0
|
mock_run.return_value.stderr = ""
|
||||||
|
mock_run.return_value.returncode = 0
|
||||||
mock_exe_exists.return_value = True
|
mock_exe_exists.return_value = True
|
||||||
|
|
||||||
self.config.enable_mod("ssl")
|
self.config.enable_mod("ssl")
|
||||||
|
|||||||
@@ -305,17 +305,19 @@ class BasicParserTest(util.ParserTest):
|
|||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
errors.PluginError, self.parser.update_runtime_variables)
|
errors.PluginError, self.parser.update_runtime_variables)
|
||||||
|
|
||||||
@mock.patch("certbot_apache._internal.apache_util.subprocess.Popen")
|
@mock.patch("certbot_apache._internal.apache_util.subprocess.run")
|
||||||
def test_update_runtime_vars_bad_ctl(self, mock_popen):
|
def test_update_runtime_vars_bad_ctl(self, mock_run):
|
||||||
mock_popen.side_effect = OSError
|
mock_run.side_effect = OSError
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
errors.MisconfigurationError,
|
errors.MisconfigurationError,
|
||||||
self.parser.update_runtime_variables)
|
self.parser.update_runtime_variables)
|
||||||
|
|
||||||
@mock.patch("certbot_apache._internal.apache_util.subprocess.Popen")
|
@mock.patch("certbot_apache._internal.apache_util.subprocess.run")
|
||||||
def test_update_runtime_vars_bad_exit(self, mock_popen):
|
def test_update_runtime_vars_bad_exit(self, mock_run):
|
||||||
mock_popen().communicate.return_value = ("", "")
|
mock_proc = mock_run.return_value
|
||||||
mock_popen.returncode = -1
|
mock_proc.stdout = ""
|
||||||
|
mock_proc.stderr = ""
|
||||||
|
mock_proc.returncode = -1
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
errors.MisconfigurationError,
|
errors.MisconfigurationError,
|
||||||
self.parser.update_runtime_variables)
|
self.parser.update_runtime_variables)
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class IntegrationTestsContext(certbot_context.IntegrationTestsContext):
|
|||||||
with open(self.nginx_config_path, 'w') as file:
|
with open(self.nginx_config_path, 'w') as file:
|
||||||
file.write(self.nginx_config)
|
file.write(self.nginx_config)
|
||||||
|
|
||||||
|
# pylint: disable=consider-using-with
|
||||||
process = subprocess.Popen(['nginx', '-c', self.nginx_config_path, '-g', 'daemon off;'])
|
process = subprocess.Popen(['nginx', '-c', self.nginx_config_path, '-g', 'daemon off;'])
|
||||||
|
|
||||||
assert process.poll() is None
|
assert process.poll() is None
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ class ACMEServer:
|
|||||||
if not env:
|
if not env:
|
||||||
env = os.environ
|
env = os.environ
|
||||||
stdout = sys.stderr if force_stderr else self._stdout
|
stdout = sys.stderr if force_stderr else self._stdout
|
||||||
|
# pylint: disable=consider-using-with
|
||||||
process = subprocess.Popen(
|
process = subprocess.Popen(
|
||||||
command, stdout=stdout, stderr=subprocess.STDOUT, cwd=cwd, env=env
|
command, stdout=stdout, stderr=subprocess.STDOUT, cwd=cwd, env=env
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ class DNSServer:
|
|||||||
def _start_bind(self):
|
def _start_bind(self):
|
||||||
"""Launch the BIND9 server as a Docker container"""
|
"""Launch the BIND9 server as a Docker container"""
|
||||||
addr_str = "{}:{}".format(BIND_BIND_ADDRESS[0], BIND_BIND_ADDRESS[1])
|
addr_str = "{}:{}".format(BIND_BIND_ADDRESS[0], BIND_BIND_ADDRESS[1])
|
||||||
|
# pylint: disable=consider-using-with
|
||||||
self.process = subprocess.Popen(
|
self.process = subprocess.Popen(
|
||||||
[
|
[
|
||||||
"docker",
|
"docker",
|
||||||
|
|||||||
@@ -985,13 +985,14 @@ class NginxConfigurator(common.Installer):
|
|||||||
Unable to run Nginx version command
|
Unable to run Nginx version command
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.run(
|
||||||
[self.conf('ctl'), "-c", self.nginx_conf, "-V"],
|
[self.conf('ctl'), "-c", self.nginx_conf, "-V"],
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
universal_newlines=True,
|
universal_newlines=True,
|
||||||
|
check=False,
|
||||||
env=util.env_no_snap_for_external_calls())
|
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:
|
except (OSError, ValueError) as error:
|
||||||
logger.debug(str(error), exc_info=True)
|
logger.debug(str(error), exc_info=True)
|
||||||
raise errors.PluginError(
|
raise errors.PluginError(
|
||||||
@@ -1224,10 +1225,9 @@ def nginx_restart(nginx_ctl, nginx_conf, sleep_duration):
|
|||||||
try:
|
try:
|
||||||
reload_output: Text = u""
|
reload_output: Text = u""
|
||||||
with tempfile.TemporaryFile() as out:
|
with tempfile.TemporaryFile() as out:
|
||||||
proc = subprocess.Popen([nginx_ctl, "-c", nginx_conf, "-s", "reload"],
|
proc = subprocess.run([nginx_ctl, "-c", nginx_conf, "-s", "reload"],
|
||||||
env=util.env_no_snap_for_external_calls(),
|
env=util.env_no_snap_for_external_calls(),
|
||||||
stdout=out, stderr=out)
|
stdout=out, stderr=out, check=False)
|
||||||
proc.communicate()
|
|
||||||
out.seek(0)
|
out.seek(0)
|
||||||
reload_output = out.read().decode("utf-8")
|
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
|
# Write to temporary files instead of piping because of communication issues on Arch
|
||||||
# https://github.com/certbot/certbot/issues/4324
|
# https://github.com/certbot/certbot/issues/4324
|
||||||
with tempfile.TemporaryFile() as out:
|
with tempfile.TemporaryFile() as out:
|
||||||
nginx_proc = subprocess.Popen([nginx_ctl, "-c", nginx_conf],
|
nginx_proc = subprocess.run([nginx_ctl, "-c", nginx_conf],
|
||||||
stdout=out, stderr=out, env=util.env_no_snap_for_external_calls())
|
stdout=out, stderr=out, env=util.env_no_snap_for_external_calls(), check=False)
|
||||||
nginx_proc.communicate()
|
|
||||||
if nginx_proc.returncode != 0:
|
if nginx_proc.returncode != 0:
|
||||||
out.seek(0)
|
out.seek(0)
|
||||||
# Enter recovery routine...
|
# Enter recovery routine...
|
||||||
|
|||||||
@@ -42,15 +42,16 @@ class NginxConfiguratorTest(util.NginxTest):
|
|||||||
self.assertEqual(13, len(self.config.parser.parsed))
|
self.assertEqual(13, len(self.config.parser.parsed))
|
||||||
|
|
||||||
@mock.patch("certbot_nginx._internal.configurator.util.exe_exists")
|
@mock.patch("certbot_nginx._internal.configurator.util.exe_exists")
|
||||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.Popen")
|
@mock.patch("certbot_nginx._internal.configurator.subprocess.run")
|
||||||
def test_prepare_initializes_version(self, mock_popen, mock_exe_exists):
|
def test_prepare_initializes_version(self, mock_run, mock_exe_exists):
|
||||||
mock_popen().communicate.return_value = (
|
mock_run.return_value.stdout = ""
|
||||||
"", "\n".join(["nginx version: nginx/1.6.2",
|
mock_run.return_value.stderr = "\n".join(
|
||||||
|
["nginx version: nginx/1.6.2",
|
||||||
"built by clang 6.0 (clang-600.0.56)"
|
"built by clang 6.0 (clang-600.0.56)"
|
||||||
" (based on LLVM 3.5svn)",
|
" (based on LLVM 3.5svn)",
|
||||||
"TLS SNI support enabled",
|
"TLS SNI support enabled",
|
||||||
"configure arguments: --prefix=/usr/local/Cellar/"
|
"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
|
mock_exe_exists.return_value = True
|
||||||
|
|
||||||
@@ -347,141 +348,149 @@ class NginxConfiguratorTest(util.NginxTest):
|
|||||||
self.assertEqual(mock_revert.call_count, 1)
|
self.assertEqual(mock_revert.call_count, 1)
|
||||||
self.assertEqual(mock_restart.call_count, 2)
|
self.assertEqual(mock_restart.call_count, 2)
|
||||||
|
|
||||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.Popen")
|
@mock.patch("certbot_nginx._internal.configurator.subprocess.run")
|
||||||
def test_get_version(self, mock_popen):
|
def test_get_version(self, mock_run):
|
||||||
mock_popen().communicate.return_value = (
|
mock_run.return_value.stdout = ""
|
||||||
"", "\n".join(["nginx version: nginx/1.4.2",
|
mock_run.return_value.stderr = "\n".join(
|
||||||
|
["nginx version: nginx/1.4.2",
|
||||||
"built by clang 6.0 (clang-600.0.56)"
|
"built by clang 6.0 (clang-600.0.56)"
|
||||||
" (based on LLVM 3.5svn)",
|
" (based on LLVM 3.5svn)",
|
||||||
"TLS SNI support enabled",
|
"TLS SNI support enabled",
|
||||||
"configure arguments: --prefix=/usr/local/Cellar/"
|
"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))
|
self.assertEqual(self.config.get_version(), (1, 4, 2))
|
||||||
|
|
||||||
mock_popen().communicate.return_value = (
|
mock_run.return_value.stdout = ""
|
||||||
"", "\n".join(["nginx version: nginx/0.9",
|
mock_run.return_value.stderr = "\n".join(
|
||||||
|
["nginx version: nginx/0.9",
|
||||||
"built by clang 6.0 (clang-600.0.56)"
|
"built by clang 6.0 (clang-600.0.56)"
|
||||||
" (based on LLVM 3.5svn)",
|
" (based on LLVM 3.5svn)",
|
||||||
"TLS SNI support enabled",
|
"TLS SNI support enabled",
|
||||||
"configure arguments: --with-http_ssl_module"]))
|
"configure arguments: --with-http_ssl_module"])
|
||||||
self.assertEqual(self.config.get_version(), (0, 9))
|
self.assertEqual(self.config.get_version(), (0, 9))
|
||||||
|
|
||||||
mock_popen().communicate.return_value = (
|
mock_run.return_value.stdout = ""
|
||||||
"", "\n".join(["blah 0.0.1",
|
mock_run.return_value.stderr = "\n".join(
|
||||||
|
["blah 0.0.1",
|
||||||
"built by clang 6.0 (clang-600.0.56)"
|
"built by clang 6.0 (clang-600.0.56)"
|
||||||
" (based on LLVM 3.5svn)",
|
" (based on LLVM 3.5svn)",
|
||||||
"TLS SNI support enabled",
|
"TLS SNI support enabled",
|
||||||
"configure arguments: --with-http_ssl_module"]))
|
"configure arguments: --with-http_ssl_module"])
|
||||||
self.assertRaises(errors.PluginError, self.config.get_version)
|
self.assertRaises(errors.PluginError, self.config.get_version)
|
||||||
|
|
||||||
mock_popen().communicate.return_value = (
|
mock_run.return_value.stdout = ""
|
||||||
"", "\n".join(["nginx version: nginx/1.4.2",
|
mock_run.return_value.stderr = "\n".join(
|
||||||
"TLS SNI support enabled"]))
|
["nginx version: nginx/1.4.2",
|
||||||
|
"TLS SNI support enabled"])
|
||||||
self.assertRaises(errors.PluginError, self.config.get_version)
|
self.assertRaises(errors.PluginError, self.config.get_version)
|
||||||
|
|
||||||
mock_popen().communicate.return_value = (
|
mock_run.return_value.stdout = ""
|
||||||
"", "\n".join(["nginx version: nginx/1.4.2",
|
mock_run.return_value.stderr = "\n".join(
|
||||||
|
["nginx version: nginx/1.4.2",
|
||||||
"built by clang 6.0 (clang-600.0.56)"
|
"built by clang 6.0 (clang-600.0.56)"
|
||||||
" (based on LLVM 3.5svn)",
|
" (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)
|
self.assertRaises(errors.PluginError, self.config.get_version)
|
||||||
|
|
||||||
mock_popen().communicate.return_value = (
|
mock_run.return_value.stdout = ""
|
||||||
"", "\n".join(["nginx version: nginx/0.8.1",
|
mock_run.return_value.stderr = "\n".join(
|
||||||
|
["nginx version: nginx/0.8.1",
|
||||||
"built by clang 6.0 (clang-600.0.56)"
|
"built by clang 6.0 (clang-600.0.56)"
|
||||||
" (based on LLVM 3.5svn)",
|
" (based on LLVM 3.5svn)",
|
||||||
"TLS SNI support enabled",
|
"TLS SNI support enabled",
|
||||||
"configure arguments: --with-http_ssl_module"]))
|
"configure arguments: --with-http_ssl_module"])
|
||||||
self.assertRaises(errors.NotSupportedError, self.config.get_version)
|
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)
|
self.assertRaises(errors.PluginError, self.config.get_version)
|
||||||
|
|
||||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.Popen")
|
@mock.patch("certbot_nginx._internal.configurator.subprocess.run")
|
||||||
def test_get_openssl_version(self, mock_popen):
|
def test_get_openssl_version(self, mock_run):
|
||||||
# pylint: disable=protected-access
|
# 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
|
nginx version: nginx/1.15.5
|
||||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||||
built with OpenSSL 1.0.2g 1 Mar 2016
|
built with OpenSSL 1.0.2g 1 Mar 2016
|
||||||
TLS SNI support enabled
|
TLS SNI support enabled
|
||||||
configure arguments:
|
configure arguments:
|
||||||
""")
|
"""
|
||||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2g")
|
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
|
nginx version: nginx/1.15.5
|
||||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
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
|
built with OpenSSL 1.0.2-beta1 1 Mar 2016
|
||||||
TLS SNI support enabled
|
TLS SNI support enabled
|
||||||
configure arguments:
|
configure arguments:
|
||||||
""")
|
"""
|
||||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2-beta1")
|
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
|
nginx version: nginx/1.15.5
|
||||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||||
built with OpenSSL 1.0.2 1 Mar 2016
|
built with OpenSSL 1.0.2 1 Mar 2016
|
||||||
TLS SNI support enabled
|
TLS SNI support enabled
|
||||||
configure arguments:
|
configure arguments:
|
||||||
""")
|
"""
|
||||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2")
|
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
|
nginx version: nginx/1.15.5
|
||||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
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)
|
built with OpenSSL 1.0.2g 1 Mar 2016 (running with OpenSSL 1.0.2a 1 Mar 2016)
|
||||||
TLS SNI support enabled
|
TLS SNI support enabled
|
||||||
configure arguments:
|
configure arguments:
|
||||||
""")
|
"""
|
||||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2a")
|
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
|
nginx version: nginx/1.15.5
|
||||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||||
built with LibreSSL 2.2.2
|
built with LibreSSL 2.2.2
|
||||||
TLS SNI support enabled
|
TLS SNI support enabled
|
||||||
configure arguments:
|
configure arguments:
|
||||||
""")
|
"""
|
||||||
self.assertEqual(self.config._get_openssl_version(), "")
|
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
|
nginx version: nginx/1.15.5
|
||||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||||
TLS SNI support enabled
|
TLS SNI support enabled
|
||||||
configure arguments:
|
configure arguments:
|
||||||
""")
|
"""
|
||||||
self.assertEqual(self.config._get_openssl_version(), "")
|
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")
|
@mock.patch("certbot_nginx._internal.configurator.time")
|
||||||
def test_nginx_restart(self, mock_time, mock_popen):
|
def test_nginx_restart(self, mock_time, mock_run):
|
||||||
mocked = mock_popen()
|
mocked = mock_run.return_value
|
||||||
mocked.communicate.return_value = ('', '')
|
mocked.stdout = ''
|
||||||
|
mocked.stderr = ''
|
||||||
mocked.returncode = 0
|
mocked.returncode = 0
|
||||||
self.config.restart()
|
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_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")
|
@mock.patch("certbot_nginx._internal.configurator.logger.debug")
|
||||||
def test_nginx_restart_fail(self, mock_log_debug, mock_popen):
|
def test_nginx_restart_fail(self, mock_log_debug, mock_run):
|
||||||
mocked = mock_popen()
|
mocked = mock_run.return_value
|
||||||
mocked.communicate.return_value = ('', '')
|
mocked.stdout = ''
|
||||||
|
mocked.stderr = ''
|
||||||
mocked.returncode = 1
|
mocked.returncode = 1
|
||||||
self.assertRaises(errors.MisconfigurationError, self.config.restart)
|
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_log_debug.assert_called_once_with("nginx reload failed:\n%s", "")
|
||||||
|
|
||||||
@mock.patch("certbot_nginx._internal.configurator.subprocess.Popen")
|
@mock.patch("certbot_nginx._internal.configurator.subprocess.run")
|
||||||
def test_no_nginx_start(self, mock_popen):
|
def test_no_nginx_start(self, mock_run):
|
||||||
mock_popen.side_effect = OSError("Can't find program")
|
mock_run.side_effect = OSError("Can't find program")
|
||||||
self.assertRaises(errors.MisconfigurationError, self.config.restart)
|
self.assertRaises(errors.MisconfigurationError, self.config.restart)
|
||||||
|
|
||||||
@mock.patch("certbot.util.run_script")
|
@mock.patch("certbot.util.run_script")
|
||||||
|
|||||||
@@ -1361,7 +1361,7 @@ def make_displayer(config: configuration.NamespaceConfig
|
|||||||
|
|
||||||
if config.quiet:
|
if config.quiet:
|
||||||
config.noninteractive_mode = True
|
config.noninteractive_mode = True
|
||||||
devnull = open(os.devnull, "w")
|
devnull = open(os.devnull, "w") # pylint: disable=consider-using-with
|
||||||
displayer = display_util.NoninteractiveDisplay(devnull)
|
displayer = display_util.NoninteractiveDisplay(devnull)
|
||||||
elif config.noninteractive_mode:
|
elif config.noninteractive_mode:
|
||||||
displayer = display_util.NoninteractiveDisplay(sys.stdout)
|
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.")
|
"webroot when using the webroot plugin.")
|
||||||
return None if index == 0 else known_webroots[index - 1] # code == display_util.OK
|
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(
|
code, webroot = ops.validated_directory(
|
||||||
_validate_webroot,
|
_validate_webroot,
|
||||||
"Input the webroot for {0}:".format(domain),
|
"Input the webroot for {0}:".format(domain),
|
||||||
@@ -192,7 +192,7 @@ to serve all files under specified web root ({0})."""
|
|||||||
finally:
|
finally:
|
||||||
filesystem.umask(old_umask)
|
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"))
|
return os.path.join(root_path, achall.chall.encode("token"))
|
||||||
|
|
||||||
def _perform_single(self, achall):
|
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 ec
|
||||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||||
import OpenSSL
|
|
||||||
import zope.component
|
import zope.component
|
||||||
|
|
||||||
from certbot import crypto_util
|
from certbot import crypto_util
|
||||||
@@ -306,13 +305,6 @@ def should_renew(config, lineage):
|
|||||||
|
|
||||||
def _avoid_invalidating_lineage(config, lineage, original_server):
|
def _avoid_invalidating_lineage(config, lineage, original_server):
|
||||||
"""Do not renew a valid cert with one from a staging 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 util.is_staging(config.server):
|
||||||
if not util.is_staging(original_server):
|
if not util.is_staging(original_server):
|
||||||
if not config.break_my_certs:
|
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]:
|
def execute_command(cmd_name: str, shell_cmd: str, env: Optional[dict] = None) -> Tuple[str, str]:
|
||||||
"""
|
"""
|
||||||
Run a command:
|
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
|
- 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 cmd_name: the user facing name of the hook being run
|
||||||
:param str shell_cmd: shell command to execute
|
: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)
|
:returns: `tuple` (`str` stderr, `str` stdout)
|
||||||
"""
|
"""
|
||||||
logger.info("Running %s command: %s", cmd_name, shell_cmd)
|
logger.info("Running %s command: %s", cmd_name, shell_cmd)
|
||||||
|
|
||||||
if POSIX_MODE:
|
if POSIX_MODE:
|
||||||
cmd = subprocess.Popen(shell_cmd, shell=True, stdout=subprocess.PIPE,
|
proc = subprocess.run(shell_cmd, shell=True, stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE, universal_newlines=True,
|
stderr=subprocess.PIPE, universal_newlines=True,
|
||||||
env=env)
|
check=False, env=env)
|
||||||
else:
|
else:
|
||||||
line = ['powershell.exe', '-Command', shell_cmd]
|
line = ['powershell.exe', '-Command', shell_cmd]
|
||||||
cmd = subprocess.Popen(line, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
proc = subprocess.run(line, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
universal_newlines=True, env=env)
|
universal_newlines=True, check=False, env=env)
|
||||||
|
|
||||||
# universal_newlines causes Popen.communicate()
|
# universal_newlines causes stdout and stderr to be str objects instead of
|
||||||
# to return str objects instead of bytes in Python 3
|
# bytes in Python 3
|
||||||
out, err = cmd.communicate()
|
out, err = proc.stdout, proc.stderr
|
||||||
base_cmd = os.path.basename(shell_cmd.split(None, 1)[0])
|
base_cmd = os.path.basename(shell_cmd.split(None, 1)[0])
|
||||||
if out:
|
if out:
|
||||||
logger.info('Output from %s command %s:\n%s', cmd_name, base_cmd, 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',
|
logger.error('%s command "%s" returned error code %d',
|
||||||
cmd_name, shell_cmd, cmd.returncode)
|
cmd_name, shell_cmd, proc.returncode)
|
||||||
if err:
|
if err:
|
||||||
logger.error('Error output from %s command %s:\n%s', cmd_name, base_cmd, err)
|
logger.error('Error output from %s command %s:\n%s', cmd_name, base_cmd, err)
|
||||||
return err, out
|
return err, out
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ from datetime import datetime
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
from subprocess import PIPE
|
from subprocess import PIPE
|
||||||
from subprocess import Popen
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
@@ -50,11 +50,10 @@ class RevocationChecker:
|
|||||||
return
|
return
|
||||||
|
|
||||||
# New versions of openssl want -header var=val, old ones want -header var val
|
# 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,
|
stdout=PIPE, stderr=PIPE, universal_newlines=True,
|
||||||
env=util.env_no_snap_for_external_calls())
|
check=False, env=util.env_no_snap_for_external_calls())
|
||||||
_out, err = test_host_format.communicate()
|
if "Missing =" in test_host_format.stderr:
|
||||||
if "Missing =" in err:
|
|
||||||
self.host_args = lambda host: ["Host=" + host]
|
self.host_args = lambda host: ["Host=" + host]
|
||||||
else:
|
else:
|
||||||
self.host_args = lambda host: ["Host", host]
|
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.
|
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
|
# Open up filepath differently depending on if it already exists
|
||||||
if os.path.isfile(filepath):
|
if os.path.isfile(filepath):
|
||||||
op_fd = open(filepath, "r+")
|
op_fd = open(filepath, "r+")
|
||||||
@@ -348,26 +349,18 @@ class Reverter:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
commands_fp = os.path.join(self._get_cp_dir(temporary), "COMMANDS")
|
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,
|
# It is strongly advised to set newline = '' on Python 3 with CSV,
|
||||||
# and it fixes problems on Windows.
|
# and it fixes problems on Windows.
|
||||||
kwargs = {'newline': ''}
|
kwargs = {'newline': ''}
|
||||||
try:
|
try:
|
||||||
if os.path.isfile(commands_fp):
|
mode = "a" if os.path.isfile(commands_fp) else "w"
|
||||||
command_file = open(commands_fp, "a", **kwargs) # type: ignore
|
with open(commands_fp, mode, **kwargs) as f: # type: ignore
|
||||||
else:
|
csvwriter = csv.writer(f)
|
||||||
command_file = open(commands_fp, "w", **kwargs) # type: ignore
|
csvwriter.writerow(command)
|
||||||
|
|
||||||
csvwriter = csv.writer(command_file)
|
|
||||||
csvwriter.writerow(command)
|
|
||||||
|
|
||||||
except (IOError, OSError):
|
except (IOError, OSError):
|
||||||
logger.error("Unable to register undo command")
|
logger.error("Unable to register undo command")
|
||||||
raise errors.ReverterError(
|
raise errors.ReverterError(
|
||||||
"Unable to register undo command.")
|
"Unable to register undo command.")
|
||||||
finally:
|
|
||||||
if command_file is not None:
|
|
||||||
command_file.close()
|
|
||||||
|
|
||||||
def _get_cp_dir(self, temporary):
|
def _get_cp_dir(self, temporary):
|
||||||
"""Return the proper reverter directory."""
|
"""Return the proper reverter directory."""
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ class FreezableMock:
|
|||||||
def _create_get_utility_mock():
|
def _create_get_utility_mock():
|
||||||
display = FreezableMock()
|
display = FreezableMock()
|
||||||
# Use pylint code for disable to keep on single line under line length limit
|
# 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':
|
if name != 'notification':
|
||||||
frozen_mock = FreezableMock(frozen=True, func=_assert_valid_call)
|
frozen_mock = FreezableMock(frozen=True, func=_assert_valid_call)
|
||||||
setattr(display, name, frozen_mock)
|
setattr(display, name, frozen_mock)
|
||||||
@@ -284,7 +284,7 @@ def _create_get_utility_mock_with_stdout(stdout):
|
|||||||
|
|
||||||
display = FreezableMock()
|
display = FreezableMock()
|
||||||
# Use pylint code for disable to keep on single line under line length limit
|
# 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':
|
if name == 'notification':
|
||||||
frozen_mock = FreezableMock(frozen=True,
|
frozen_mock = FreezableMock(frozen=True,
|
||||||
func=_write_msg)
|
func=_write_msg)
|
||||||
|
|||||||
+14
-15
@@ -89,32 +89,31 @@ def env_no_snap_for_external_calls():
|
|||||||
def run_script(params, log=logger.error):
|
def run_script(params, log=logger.error):
|
||||||
"""Run the script with the given params.
|
"""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
|
:param callable log: Logger method to use for errors
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
proc = subprocess.Popen(params,
|
proc = subprocess.run(params,
|
||||||
stdout=subprocess.PIPE,
|
check=False,
|
||||||
stderr=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
universal_newlines=True,
|
stderr=subprocess.PIPE,
|
||||||
env=env_no_snap_for_external_calls())
|
universal_newlines=True,
|
||||||
|
env=env_no_snap_for_external_calls())
|
||||||
|
|
||||||
except (OSError, ValueError):
|
except (OSError, ValueError):
|
||||||
msg = "Unable to run the command: %s" % " ".join(params)
|
msg = "Unable to run the command: %s" % " ".join(params)
|
||||||
log(msg)
|
log(msg)
|
||||||
raise errors.SubprocessError(msg)
|
raise errors.SubprocessError(msg)
|
||||||
|
|
||||||
stdout, stderr = proc.communicate()
|
|
||||||
|
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
msg = "Error while running %s.\n%s\n%s" % (
|
msg = "Error while running %s.\n%s\n%s" % (
|
||||||
" ".join(params), stdout, stderr)
|
" ".join(params), proc.stdout, proc.stderr)
|
||||||
# Enter recovery routine...
|
# Enter recovery routine...
|
||||||
log(msg)
|
log(msg)
|
||||||
raise errors.SubprocessError(msg)
|
raise errors.SubprocessError(msg)
|
||||||
|
|
||||||
return stdout, stderr
|
return proc.stdout, proc.stderr
|
||||||
|
|
||||||
|
|
||||||
def exe_exists(exe):
|
def exe_exists(exe):
|
||||||
@@ -399,20 +398,20 @@ def get_python_os_info(pretty=False):
|
|||||||
os_ver = info[1]
|
os_ver = info[1]
|
||||||
elif os_type.startswith('darwin'):
|
elif os_type.startswith('darwin'):
|
||||||
try:
|
try:
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.run(
|
||||||
["/usr/bin/sw_vers", "-productVersion"],
|
["/usr/bin/sw_vers", "-productVersion"],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
universal_newlines=True,
|
check=False, universal_newlines=True,
|
||||||
env=env_no_snap_for_external_calls(),
|
env=env_no_snap_for_external_calls(),
|
||||||
)
|
)
|
||||||
except OSError:
|
except OSError:
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.run(
|
||||||
["sw_vers", "-productVersion"],
|
["sw_vers", "-productVersion"],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
universal_newlines=True,
|
check=False, universal_newlines=True,
|
||||||
env=env_no_snap_for_external_calls(),
|
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'):
|
elif os_type.startswith('freebsd'):
|
||||||
# eg "9.3-RC3-p1"
|
# eg "9.3-RC3-p1"
|
||||||
os_ver = os_ver.partition("-")[0]
|
os_ver = os_ver.partition("-")[0]
|
||||||
|
|||||||
@@ -25,14 +25,15 @@ class ExecuteTest(unittest.TestCase):
|
|||||||
def _test_common(self, returncode, stdout, stderr):
|
def _test_common(self, returncode, stdout, stderr):
|
||||||
given_command = "foo"
|
given_command = "foo"
|
||||||
given_name = "foo-hook"
|
given_name = "foo-hook"
|
||||||
with mock.patch("certbot.compat.misc.subprocess.Popen") as mock_popen:
|
with mock.patch("certbot.compat.misc.subprocess.run") as mock_run:
|
||||||
mock_popen.return_value.communicate.return_value = (stdout, stderr)
|
mock_run.return_value.stdout = stdout
|
||||||
mock_popen.return_value.returncode = returncode
|
mock_run.return_value.stderr = stderr
|
||||||
|
mock_run.return_value.returncode = returncode
|
||||||
with mock.patch("certbot.compat.misc.logger") as mock_logger:
|
with mock.patch("certbot.compat.misc.logger") as mock_logger:
|
||||||
self.assertEqual(self._call(given_name, given_command), (stderr, stdout))
|
self.assertEqual(self._call(given_name, given_command), (stderr, stdout))
|
||||||
|
|
||||||
executed_command = mock_popen.call_args[1].get(
|
executed_command = mock_run.call_args[1].get(
|
||||||
"args", mock_popen.call_args[0][0])
|
"args", mock_run.call_args[0][0])
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
expected_command = ['powershell.exe', '-Command', given_command]
|
expected_command = ['powershell.exe', '-Command', given_command]
|
||||||
else:
|
else:
|
||||||
|
|||||||
+19
-23
@@ -1078,29 +1078,25 @@ class MainTest(test_util.ConfigTestCase):
|
|||||||
with test_util.patch_get_utility() as mock_get_utility:
|
with test_util.patch_get_utility() as mock_get_utility:
|
||||||
if not quiet_mode:
|
if not quiet_mode:
|
||||||
mock_get_utility().notification.side_effect = write_msg
|
mock_get_utility().notification.side_effect = write_msg
|
||||||
with mock.patch('certbot._internal.main.renewal.OpenSSL') as mock_ssl:
|
with mock.patch('certbot._internal.main.renewal.crypto_util') \
|
||||||
mock_latest = mock.MagicMock()
|
as mock_crypto_util:
|
||||||
mock_latest.get_issuer.return_value = "Artificial pretend"
|
mock_crypto_util.notAfter.return_value = expiry_date
|
||||||
mock_ssl.crypto.load_certificate.return_value = mock_latest
|
with mock.patch('certbot._internal.eff.handle_subscription'):
|
||||||
with mock.patch('certbot._internal.main.renewal.crypto_util') \
|
if not args:
|
||||||
as mock_crypto_util:
|
args = ['-d', 'isnot.org', '-a', 'standalone', 'certonly']
|
||||||
mock_crypto_util.notAfter.return_value = expiry_date
|
if extra_args:
|
||||||
with mock.patch('certbot._internal.eff.handle_subscription'):
|
args += extra_args
|
||||||
if not args:
|
try:
|
||||||
args = ['-d', 'isnot.org', '-a', 'standalone', 'certonly']
|
ret, stdout, _, _ = self._call(args, stdout)
|
||||||
if extra_args:
|
if ret:
|
||||||
args += extra_args
|
print("Returned", ret)
|
||||||
try:
|
raise AssertionError(ret)
|
||||||
ret, stdout, _, _ = self._call(args, stdout)
|
assert not error_expected, "renewal should have errored"
|
||||||
if ret:
|
except: # pylint: disable=bare-except
|
||||||
print("Returned", ret)
|
if not error_expected:
|
||||||
raise AssertionError(ret)
|
raise AssertionError(
|
||||||
assert not error_expected, "renewal should have errored"
|
"Unexpected renewal error:\n" +
|
||||||
except: # pylint: disable=bare-except
|
traceback.format_exc())
|
||||||
if not error_expected:
|
|
||||||
raise AssertionError(
|
|
||||||
"Unexpected renewal error:\n" +
|
|
||||||
traceback.format_exc())
|
|
||||||
|
|
||||||
if should_renew:
|
if should_renew:
|
||||||
if reuse_key:
|
if reuse_key:
|
||||||
|
|||||||
@@ -40,11 +40,9 @@ class OCSPTestOpenSSL(unittest.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
from certbot import ocsp
|
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:
|
with mock.patch('certbot.util.exe_exists') as mock_exists:
|
||||||
mock_communicate = mock.MagicMock()
|
mock_run.stderr = out
|
||||||
mock_communicate.communicate.return_value = (None, out)
|
|
||||||
mock_popen.return_value = mock_communicate
|
|
||||||
mock_exists.return_value = True
|
mock_exists.return_value = True
|
||||||
self.checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True)
|
self.checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True)
|
||||||
|
|
||||||
@@ -52,28 +50,26 @@ class OCSPTestOpenSSL(unittest.TestCase):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@mock.patch('certbot.ocsp.logger.info')
|
@mock.patch('certbot.ocsp.logger.info')
|
||||||
@mock.patch('certbot.ocsp.Popen')
|
@mock.patch('certbot.ocsp.subprocess.run')
|
||||||
@mock.patch('certbot.util.exe_exists')
|
@mock.patch('certbot.util.exe_exists')
|
||||||
def test_init(self, mock_exists, mock_popen, mock_log):
|
def test_init(self, mock_exists, mock_run, mock_log):
|
||||||
mock_communicate = mock.MagicMock()
|
mock_run.return_value.stderr = out
|
||||||
mock_communicate.communicate.return_value = (None, out)
|
|
||||||
mock_popen.return_value = mock_communicate
|
|
||||||
mock_exists.return_value = True
|
mock_exists.return_value = True
|
||||||
|
|
||||||
from certbot import ocsp
|
from certbot import ocsp
|
||||||
checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True)
|
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"])
|
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)
|
checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True)
|
||||||
self.assertEqual(checker.host_args("x"), ["Host", "x"])
|
self.assertEqual(checker.host_args("x"), ["Host", "x"])
|
||||||
self.assertIs(checker.broken, False)
|
self.assertIs(checker.broken, False)
|
||||||
|
|
||||||
mock_exists.return_value = False
|
mock_exists.return_value = False
|
||||||
mock_popen.call_count = 0
|
mock_run.call_count = 0
|
||||||
checker = ocsp.RevocationChecker(enforce_openssl_binary_usage=True)
|
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.assertEqual(mock_log.call_count, 1)
|
||||||
self.assertIs(checker.broken, True)
|
self.assertIs(checker.broken, True)
|
||||||
|
|
||||||
|
|||||||
+13
-17
@@ -59,26 +59,26 @@ class RunScriptTest(unittest.TestCase):
|
|||||||
from certbot.util import run_script
|
from certbot.util import run_script
|
||||||
return run_script(params)
|
return run_script(params)
|
||||||
|
|
||||||
@mock.patch("certbot.util.subprocess.Popen")
|
@mock.patch("certbot.util.subprocess.run")
|
||||||
def test_default(self, mock_popen):
|
def test_default(self, mock_run):
|
||||||
"""These will be changed soon enough with reload."""
|
"""These will be changed soon enough with reload."""
|
||||||
mock_popen().returncode = 0
|
mock_run().returncode = 0
|
||||||
mock_popen().communicate.return_value = ("stdout", "stderr")
|
mock_run().stdout = "stdout"
|
||||||
|
mock_run().stderr = "stderr"
|
||||||
|
|
||||||
out, err = self._call(["test"])
|
out, err = self._call(["test"])
|
||||||
self.assertEqual(out, "stdout")
|
self.assertEqual(out, "stdout")
|
||||||
self.assertEqual(err, "stderr")
|
self.assertEqual(err, "stderr")
|
||||||
|
|
||||||
@mock.patch("certbot.util.subprocess.Popen")
|
@mock.patch("certbot.util.subprocess.run")
|
||||||
def test_bad_process(self, mock_popen):
|
def test_bad_process(self, mock_run):
|
||||||
mock_popen.side_effect = OSError
|
mock_run.side_effect = OSError
|
||||||
|
|
||||||
self.assertRaises(errors.SubprocessError, self._call, ["test"])
|
self.assertRaises(errors.SubprocessError, self._call, ["test"])
|
||||||
|
|
||||||
@mock.patch("certbot.util.subprocess.Popen")
|
@mock.patch("certbot.util.subprocess.run")
|
||||||
def test_failure(self, mock_popen):
|
def test_failure(self, mock_run):
|
||||||
mock_popen().communicate.return_value = ("", "")
|
mock_run().returncode = 1
|
||||||
mock_popen().returncode = 1
|
|
||||||
|
|
||||||
self.assertRaises(errors.SubprocessError, self._call, ["test"])
|
self.assertRaises(errors.SubprocessError, self._call, ["test"])
|
||||||
|
|
||||||
@@ -557,12 +557,8 @@ class OsInfoTest(unittest.TestCase):
|
|||||||
|
|
||||||
with mock.patch('platform.system_alias',
|
with mock.patch('platform.system_alias',
|
||||||
return_value=('darwin', '', '')):
|
return_value=('darwin', '', '')):
|
||||||
with mock.patch("subprocess.Popen") as popen_mock:
|
with mock.patch("subprocess.run") as run_mock:
|
||||||
comm_mock = mock.Mock()
|
run_mock().stdout = '42.42.42'
|
||||||
comm_attrs = {'communicate.return_value':
|
|
||||||
('42.42.42', 'error')}
|
|
||||||
comm_mock.configure_mock(**comm_attrs)
|
|
||||||
popen_mock.return_value = comm_mock
|
|
||||||
self.assertEqual(cbutil.get_python_os_info()[0], 'darwin')
|
self.assertEqual(cbutil.get_python_os_info()[0], 'darwin')
|
||||||
self.assertEqual(cbutil.get_python_os_info()[1], '42.42.42')
|
self.assertEqual(cbutil.get_python_os_info()[1], '42.42.42')
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -264,9 +264,9 @@ def subprocess_call(args):
|
|||||||
:rtype: tuple
|
:rtype: tuple
|
||||||
|
|
||||||
"""
|
"""
|
||||||
process = subprocess.Popen(args, stdout=subprocess.PIPE,
|
process = subprocess.run(args, stdout=subprocess.PIPE, check=False,
|
||||||
stderr=subprocess.PIPE, universal_newlines=True)
|
stderr=subprocess.PIPE, universal_newlines=True)
|
||||||
out, err = process.communicate()
|
out, err = process.stdout, process.stderr
|
||||||
logger.debug('Return code was %d', process.returncode)
|
logger.debug('Return code was %d', process.returncode)
|
||||||
log_output(logging.DEBUG, out, err)
|
log_output(logging.DEBUG, out, err)
|
||||||
return process.returncode, 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
|
# needed. This dependency can be removed here once Certbot's support for the
|
||||||
# 3rd party mock library has been dropped.
|
# 3rd party mock library has been dropped.
|
||||||
mock = "*"
|
mock = "*"
|
||||||
# Upgrading coverage, pylint, pytest, and some of pytest's plugins causes many
|
# Upgrading coverage, pytest, and some of pytest's plugins causes many test
|
||||||
# test failures so let's pin these packages back for now.
|
# failures so let's pin these packages back for now.
|
||||||
coverage = "4.5.4"
|
coverage = "4.5.4"
|
||||||
pylint = "2.4.3"
|
|
||||||
pytest = "3.2.5"
|
pytest = "3.2.5"
|
||||||
pytest-forked = "0.2"
|
pytest-forked = "0.2"
|
||||||
# We were originally pinning back python-augeas for certbot-auto because we
|
# 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"
|
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"
|
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
|
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"
|
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"
|
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"
|
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
|
backcall==0.2.0
|
||||||
bcrypt==3.2.0; python_version >= "3.6"
|
bcrypt==3.2.0; python_version >= "3.6"
|
||||||
beautifulsoup4==4.9.3; python_version >= "3.6" and python_version < "4.0"
|
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"
|
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"
|
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.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.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"
|
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"
|
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")
|
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"
|
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"
|
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")
|
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"
|
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")
|
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")
|
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"
|
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")
|
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"
|
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"
|
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"
|
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"
|
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"
|
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"
|
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-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.3.0; 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-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"
|
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"
|
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"
|
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"
|
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-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"
|
invoke==1.5.0; python_version >= "3.6"
|
||||||
ipdb==0.13.7; python_version >= "3.6"
|
ipdb==0.13.7; python_version >= "3.6"
|
||||||
ipython-genutils==0.2.0; python_version == "3.6"
|
ipython-genutils==0.2.0; python_version == "3.6"
|
||||||
ipython==7.16.1; python_version == "3.6"
|
ipython==7.16.1; python_version == "3.6"
|
||||||
ipython==7.23.1; python_version >= "3.7"
|
ipython==7.23.1; python_version >= "3.7"
|
||||||
isodate==0.6.0; python_version >= "3.6"
|
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
|
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"
|
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"
|
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"
|
josepy==1.8.0; python_version >= "3.6"
|
||||||
jsonlines==2.0.0; python_version >= "3.6"
|
jsonlines==2.0.0; python_version >= "3.6"
|
||||||
jsonpickle==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"
|
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")
|
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
|
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"
|
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"
|
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"
|
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"
|
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-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"
|
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
|
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"
|
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"
|
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"
|
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
|
pygments==2.9.0
|
||||||
pyjwt==2.1.0; python_version >= "3.6"
|
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"
|
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"
|
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"
|
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"
|
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"
|
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"
|
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"
|
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"
|
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.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_version >= "3.6" and python_full_version >= "3.5.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"
|
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"
|
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
|
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"
|
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"
|
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"
|
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"
|
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"
|
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"
|
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