Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require Python 3.6 or newer, use f-strings and variable type annotation syntax #329

Merged
merged 7 commits into from
Aug 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ dist: xenial
language: python
conditions: v1
python:
- 3.5
- 3.6
- 3.7
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you try if there's 3.8 available already?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's available, while a test fails due to the fix for https://pagure.io/python-daemon/issue/34 not being released. Should I add 3.8 and xfail the affected tests on that version?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or the xfail indeed with failing test while it starts passing.

- 3.8-dev
- pypy3
# blocklist branches
branches:
Expand Down
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
[pytest]
testpaths = tests/
filterwarnings = error
xfail_strict = True
4 changes: 1 addition & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
tests_require = (
'pytest==5.0.1', # tests framework used
'pytest-cov==2.7.1', # coverage reports to verify tests quality
'mock==3.0.5', # tests mocking tool
'python-daemon==2.2.3', # used in test for easy creation of daemons
)
extras_require = {
Expand Down Expand Up @@ -64,7 +63,7 @@ def read(fname):
author='Clearcode - The A Room',
author_email='thearoom@clearcode.cc',
license='LGPL',
python_requires='>=3.5',
python_requires='>=3.6',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
Expand All @@ -75,7 +74,6 @@ def read(fname):
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3 :: Only',
Expand Down
28 changes: 11 additions & 17 deletions src/mirakuru/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,11 @@ def __init__( # pylint:disable=too-many-arguments
self._stdout = stdout
self._stderr = stderr

self._endtime = None # type: Optional[float]
self.process = None # type: Optional[subprocess.Popen]
self._endtime: Optional[float] = None
self.process: Optional[subprocess.Popen] = None
"""A :class:`subprocess.Popen` instance once process is started."""

self._uuid = '{0}:{1}'.format(os.getpid(), uuid.uuid4())
self._uuid = f'{os.getpid()}:{uuid.uuid4()}'

def __enter__(self: SimpleExecutorType) -> SimpleExecutorType:
"""
Expand Down Expand Up @@ -196,7 +196,7 @@ def _popen_kwargs(self) -> Dict[str, Any]:

:return:
"""
kwargs = {} # type: Dict[str, Any]
kwargs: Dict[str, Any] = {}

if self._stdin:
kwargs['stdin'] = self._stdin
Expand Down Expand Up @@ -239,8 +239,7 @@ def start(self: SimpleExecutorType) -> SimpleExecutorType:
:rtype: SimpleExecutor
"""
if self.process is None:
command = \
self.command # type: Union[str, List[str], Tuple[str, ...]]
command: Union[str, List[str], Tuple[str, ...]] = self.command
if not self._shell:
command = self.command_parts

Expand Down Expand Up @@ -446,20 +445,15 @@ def __repr__(self) -> str:
command = self.command
if len(command) > 10:
command = command[:10] + '...'
return '<{module}.{executor}: "{command}" {id}>'.format(
module=self.__class__.__module__,
executor=self.__class__.__name__,
command=command,
id=hex(id(self))
)
module = self.__class__.__module__
executor = self.__class__.__name__
return f'<{module}.{executor}: "{command}" {hex(id(self))}>'

def __str__(self) -> str:
"""Return readable executor representation."""
return '<{module}.{executor}: "{command}">'.format(
module=self.__class__.__module__,
executor=self.__class__.__name__,
command=self.command
)
module = self.__class__.__module__
executor = self.__class__.__name__
return f'<{module}.{executor}: "{self.command}" {hex(id(self))}>'


class Executor(SimpleExecutor):
Expand Down
4 changes: 2 additions & 2 deletions src/mirakuru/base_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def processes_with_env_ps(env_name: str, env_value: str) -> Set[int]:
environment variable equal certain value
:rtype: set
"""
pids = set() # type: Set[int]
pids: Set[int] = set()
ps_xe = ''
try:
cmd = 'ps', 'xe', '-o', 'pid,cmd'
Expand All @@ -93,7 +93,7 @@ def processes_with_env_ps(env_name: str, env_value: str) -> Set[int]:
except subprocess.CalledProcessError:
log.error("`$ ps xe -o pid,cmd` command exited with non-zero code.")

env = '{0}={1}'.format(env_name, env_value)
env = f'{env_name}={env_value}'

for line in ps_xe:
line = str(line)
Expand Down
21 changes: 11 additions & 10 deletions src/mirakuru/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ def __str__(self) -> str:
:returns: string representation
:rtype: str
"""
return 'Executor {0} timed out after {1} seconds'.format(
self.executor, self.timeout
return (
f'Executor {self.executor} timed out after {self.timeout} seconds'
)


Expand All @@ -63,11 +63,13 @@ def __str__(self) -> str:
:returns: string representation
:rtype: str
"""
return ("Executor {exc.executor} seems to be already running. "
"It looks like the previous executor process hasn't been "
"terminated or killed. Also there might be some completely "
"different service listening on {exc.executor.port} port."
.format(exc=self))
port = getattr(self.executor, 'port')
return (f"Executor {self.executor} seems to be already running. "
f"It looks like the previous executor process hasn't been "
f"terminated or killed."
+ ("" if port is None else
f" Also there might be some completely "
f"different service listening on {port} port."))


class ProcessExitedWithError(ExecutorError):
Expand Down Expand Up @@ -97,6 +99,5 @@ def __str__(self) -> str:
:returns: string representation
:rtype: str
"""
return ("The process invoked by the {exc.executor} executor has "
"exited with a non-zero code: {exc.exit_code}."
.format(exc=self))
return (f"The process invoked by the {self.executor} executor has "
f"exited with a non-zero code: {self.exit_code}.")
2 changes: 1 addition & 1 deletion src/mirakuru/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def start(self: OutputExecutorType) -> OutputExecutorType:
"""
super(OutputExecutor, self).start()

polls = [] # type: List[Tuple[select.poll, IO[Any]]]
polls: List[Tuple[select.poll, IO[Any]]] = []

for output_handle, output_method in (
(self._stdout, self.output),
Expand Down
4 changes: 1 addition & 3 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
TEST_SOCKET_SERVER_PATH = path.join(TEST_PATH, 'unixsocketserver_for_tests.py')
SAMPLE_DAEMON_PATH = path.join(TEST_PATH, "sample_daemon.py")

HTTP_SERVER_CMD = (
"{python} -m http.server"
).format(python=sys.executable)
HTTP_SERVER_CMD = f"{sys.executable} -m http.server"


def ps_aux():
Expand Down
31 changes: 0 additions & 31 deletions tests/conftest.py

This file was deleted.

15 changes: 8 additions & 7 deletions tests/executors/test_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import signal
from subprocess import check_output
import uuid
from unittest import mock

import pytest
import mock

from mirakuru import Executor
from mirakuru.base import SimpleExecutor
Expand Down Expand Up @@ -148,7 +148,7 @@ def test_forgotten_stop():
# get substituted with 'sleep 300' and the marked commandline would be
# overwritten.
# Injecting some flow control (`&&`) forces bash to fork properly.
marked_command = 'sleep 300 && true #{0!s}'.format(mark)
marked_command = f'sleep 300 && true #{mark!s}'
executor = SimpleExecutor(marked_command, shell=True)
executor.start()
assert executor.running() is True
Expand All @@ -168,7 +168,7 @@ def test_executor_raises_if_process_exits_with_error():
"""
error_code = 12
failing_executor = Executor(
['bash', '-c', 'exit {0!s}'.format(error_code)],
['bash', '-c', f'exit {error_code!s}'],
timeout=5
)
failing_executor.pre_start_check = mock.Mock( # type: ignore
Expand All @@ -181,7 +181,7 @@ def test_executor_raises_if_process_exits_with_error():
failing_executor.start()

assert exc.value.exit_code == 12
error_msg = 'exited with a non-zero code: {0!s}'.format(error_code)
error_msg = f'exited with a non-zero code: {error_code!s}'
assert error_msg in str(exc.value)

# Pre-start check should have been called - after-start check might or
Expand Down Expand Up @@ -228,14 +228,15 @@ def test_executor_methods_returning_self():

def test_mirakuru_cleanup():
"""Test if cleanup_subprocesses is fired correctly on python exit."""
cmd = '''
cmd = f'''
python -c 'from mirakuru import SimpleExecutor;
from time import sleep;
import gc;
gc.disable();
ex = SimpleExecutor(("python", "{0}")).start();
ex = SimpleExecutor(
("python", "{SAMPLE_DAEMON_PATH}")).start();
sleep(1);
'
'''.format(SAMPLE_DAEMON_PATH)
'''
check_output(shlex.split(cmd.replace('\n', '')))
assert SAMPLE_DAEMON_PATH not in ps_aux()
12 changes: 9 additions & 3 deletions tests/executors/test_executor_kill.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import errno

import os
from mock import patch
from unittest.mock import patch
import pytest

from mirakuru import SimpleExecutor, HTTPExecutor
from mirakuru.compat import SIGKILL
Expand Down Expand Up @@ -49,6 +50,11 @@ def process_stopped():
assert not executor.process


@pytest.mark.xfail(
condition=sys.version_info >= (3, 8),
reason='python-daemon 2.2.3 fails with '
'<https://pagure.io/python-daemon/issue/34>; '
'unxfail when a newer version is used')
def test_daemons_killing():
"""
Test if all subprocesses of SimpleExecutor can be killed.
Expand Down Expand Up @@ -76,8 +82,8 @@ def test_stopping_brutally():
by executor with SIGKILL automatically.
"""
host_port = "127.0.0.1:8000"
cmd = '{0} {1} {2} True'.format(sys.executable, TEST_SERVER_PATH, host_port)
executor = HTTPExecutor(cmd, 'http://{0!s}/'.format(host_port), timeout=20)
cmd = f'{sys.executable} {TEST_SERVER_PATH} {host_port} True'
executor = HTTPExecutor(cmd, f'http://{host_port!s}/', timeout=20)
executor.start()
assert executor.running() is True

Expand Down