Merge pull request #475 from hugovk/rm-3.4
Drop support for EOL Python 3.4
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
environment:
|
||||
matrix:
|
||||
- TOXENV: "py27-pytestlatest"
|
||||
- TOXENV: "py34-pytestlatest"
|
||||
- TOXENV: "py35-pytestlatest"
|
||||
- TOXENV: "py36-pytestlatest"
|
||||
- TOXENV: "py37-pytestlatest"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
repos:
|
||||
- repo: https://github.com/ambv/black
|
||||
rev: 18.6b4
|
||||
rev: 19.10b0
|
||||
hooks:
|
||||
- id: black
|
||||
args: [--safe, --quiet]
|
||||
language_version: python3.7
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v1.3.0
|
||||
rev: v2.4.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
|
||||
@@ -36,9 +36,7 @@ jobs:
|
||||
env: TOXENV=py27-pytestlatest
|
||||
|
||||
- stage: test
|
||||
python: "3.4"
|
||||
env: TOXENV=py34-pytestlatest
|
||||
- python: "3.5"
|
||||
python: "3.5"
|
||||
env: TOXENV=py35-pytestlatest
|
||||
- python: "3.6"
|
||||
env: TOXENV=py36-pytestlatest
|
||||
|
||||
1
changelog/475.removal
Normal file
1
changelog/475.removal
Normal file
@@ -0,0 +1 @@
|
||||
Drop support for EOL Python 3.4.
|
||||
3
setup.py
3
setup.py
@@ -24,7 +24,7 @@ setup(
|
||||
"pytest11": ["xdist = xdist.plugin", "xdist.looponfail = xdist.looponfail"]
|
||||
},
|
||||
zip_safe=False,
|
||||
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
|
||||
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
|
||||
install_requires=install_requires,
|
||||
setup_requires=["setuptools_scm"],
|
||||
classifiers=[
|
||||
@@ -42,7 +42,6 @@ setup(
|
||||
"Programming Language :: Python :: 2",
|
||||
"Programming Language :: Python :: 2.7",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.4",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
|
||||
@@ -169,7 +169,7 @@ class DSession(object):
|
||||
"""
|
||||
self.config.hook.pytest_testnodedown(node=node, error=None)
|
||||
if node.workeroutput["exitstatus"] == 2: # keyboard-interrupt
|
||||
self.shouldstop = "%s received keyboard-interrupt" % (node,)
|
||||
self.shouldstop = "{} received keyboard-interrupt".format(node)
|
||||
self.worker_errordown(node, "keyboard-interrupt")
|
||||
return
|
||||
if node in self.sched.nodes:
|
||||
@@ -321,7 +321,7 @@ class DSession(object):
|
||||
# XXX count no of failures and retry N times
|
||||
runner = self.config.pluginmanager.getplugin("runner")
|
||||
fspath = nodeid.split("::")[0]
|
||||
msg = "worker %r crashed while running %r" % (worker.gateway.id, nodeid)
|
||||
msg = "worker {!r} crashed while running {!r}".format(worker.gateway.id, nodeid)
|
||||
rep = runner.TestReport(
|
||||
nodeid, (fspath, None, fspath), (), "failed", msg, "???"
|
||||
)
|
||||
@@ -351,7 +351,9 @@ class TerminalDistReporter(object):
|
||||
|
||||
def getstatus(self):
|
||||
if self.config.option.verbose >= 0:
|
||||
parts = ["%s %s" % (spec.id, self._status[spec.id]) for spec in self._specs]
|
||||
parts = [
|
||||
"{} {}".format(spec.id, self._status[spec.id]) for spec in self._specs
|
||||
]
|
||||
return " / ".join(parts)
|
||||
else:
|
||||
return "bringing up nodes..."
|
||||
@@ -386,14 +388,16 @@ class TerminalDistReporter(object):
|
||||
def pytest_testnodeready(self, node):
|
||||
if self.config.option.verbose > 0:
|
||||
d = node.workerinfo
|
||||
infoline = "[%s] Python %s" % (d["id"], d["version"].replace("\n", " -- "))
|
||||
infoline = "[{}] Python {}".format(
|
||||
d["id"], d["version"].replace("\n", " -- ")
|
||||
)
|
||||
self.rewrite(infoline, newline=True)
|
||||
self.setstatus(node.gateway.spec, "ok")
|
||||
|
||||
def pytest_testnodedown(self, node, error):
|
||||
if not error:
|
||||
return
|
||||
self.write_line("[%s] node down: %s" % (node.gateway.id, error))
|
||||
self.write_line("[{}] node down: {}".format(node.gateway.id, error))
|
||||
|
||||
|
||||
def get_default_max_worker_restart(config):
|
||||
|
||||
@@ -136,7 +136,7 @@ def repr_pytest_looponfailinfo(failreports, rootdirs):
|
||||
tr.line(report, red=True)
|
||||
tr.sep("#", "waiting for changes", bold=True)
|
||||
for rootdir in rootdirs:
|
||||
tr.line("### Watching: %s" % (rootdir,), bold=True)
|
||||
tr.line("### Watching: {}".format(rootdir), bold=True)
|
||||
|
||||
|
||||
def init_worker_session(channel, args, option_dict):
|
||||
|
||||
@@ -358,12 +358,12 @@ class LoadScopeScheduling(object):
|
||||
extra_nodes = len(self.nodes) - len(self.workqueue)
|
||||
|
||||
if extra_nodes > 0:
|
||||
self.log("Shuting down {0} nodes".format(extra_nodes))
|
||||
self.log("Shuting down {} nodes".format(extra_nodes))
|
||||
|
||||
for _ in range(extra_nodes):
|
||||
unused_node, assigned = self.assigned_work.popitem(last=True)
|
||||
|
||||
self.log("Shuting down unused node {0}".format(unused_node))
|
||||
self.log("Shuting down unused node {}".format(unused_node))
|
||||
unused_node.shutdown()
|
||||
|
||||
# Assign initial workload
|
||||
|
||||
@@ -101,7 +101,7 @@ class NodeManager(object):
|
||||
for root in candidates:
|
||||
root = py.path.local(root).realpath()
|
||||
if not root.check():
|
||||
raise pytest.UsageError("rsyncdir doesn't exist: %r" % (root,))
|
||||
raise pytest.UsageError("rsyncdir doesn't exist: {!r}".format(root))
|
||||
if root not in roots:
|
||||
roots.append(root)
|
||||
return roots
|
||||
@@ -179,7 +179,7 @@ class HostRSync(execnet.RSync):
|
||||
if self._verbose:
|
||||
path = os.path.basename(self._sourcedir) + "/" + modified_rel_path
|
||||
remotepath = gateway.spec.chdir
|
||||
print("%s:%s <= %s" % (gateway.spec, remotepath, path))
|
||||
print("{}:{} <= {}".format(gateway.spec, remotepath, path))
|
||||
|
||||
|
||||
def make_reltoroot(roots, args):
|
||||
@@ -198,7 +198,7 @@ def make_reltoroot(roots, args):
|
||||
parts[0] = root.basename + "/" + x
|
||||
break
|
||||
else:
|
||||
raise ValueError("arg %s not relative to an rsync root" % (arg,))
|
||||
raise ValueError("arg {} not relative to an rsync root".format(arg))
|
||||
result.append(splitcode.join(parts))
|
||||
return result
|
||||
|
||||
@@ -233,7 +233,7 @@ class WorkerController(object):
|
||||
py.log.setconsumer(self.log._keywords, None)
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s %s>" % (self.__class__.__name__, self.gateway.id)
|
||||
return "<{} {}>".format(self.__class__.__name__, self.gateway.id)
|
||||
|
||||
@property
|
||||
def shutting_down(self):
|
||||
@@ -293,11 +293,11 @@ class WorkerController(object):
|
||||
|
||||
def sendcommand(self, name, **kwargs):
|
||||
""" send a named parametrized command to the other side. """
|
||||
self.log("sending command %s(**%s)" % (name, kwargs))
|
||||
self.log("sending command {}(**{})".format(name, kwargs))
|
||||
self.channel.send((name, kwargs))
|
||||
|
||||
def notify_inproc(self, eventname, **kwargs):
|
||||
self.log("queuing %s(**%s)" % (eventname, kwargs))
|
||||
self.log("queuing {}(**{})".format(eventname, kwargs))
|
||||
self.putevent((eventname, kwargs))
|
||||
|
||||
def process_from_remote(self, eventcall): # noqa too complex
|
||||
@@ -319,7 +319,7 @@ class WorkerController(object):
|
||||
return
|
||||
eventname, kwargs = eventcall
|
||||
if eventname in ("collectionstart",):
|
||||
self.log("ignoring %s(%s)" % (eventname, kwargs))
|
||||
self.log("ignoring {}({})".format(eventname, kwargs))
|
||||
elif eventname == "workerready":
|
||||
self.notify_inproc(eventname, node=self, **kwargs)
|
||||
elif eventname == "workerfinished":
|
||||
@@ -359,7 +359,7 @@ class WorkerController(object):
|
||||
item=kwargs["item"],
|
||||
)
|
||||
else:
|
||||
raise ValueError("unknown event: %s" % (eventname,))
|
||||
raise ValueError("unknown event: {}".format(eventname))
|
||||
except KeyboardInterrupt:
|
||||
# should not land in receiver-thread
|
||||
raise
|
||||
|
||||
@@ -25,7 +25,7 @@ class EventCall:
|
||||
self.name, self.kwargs = eventcall
|
||||
|
||||
def __str__(self):
|
||||
return "<EventCall %s(**%s)>" % (self.name, self.kwargs)
|
||||
return "<EventCall {}(**{})>".format(self.name, self.kwargs)
|
||||
|
||||
|
||||
class WorkerSetup:
|
||||
@@ -59,7 +59,7 @@ class WorkerSetup:
|
||||
ev = EventCall(data)
|
||||
if name is None or ev.name == name:
|
||||
return ev
|
||||
print("skipping %s" % (ev,))
|
||||
print("skipping {}".format(ev))
|
||||
|
||||
def sendcommand(self, name, **kwargs):
|
||||
self.slp.sendcommand(name, **kwargs)
|
||||
|
||||
@@ -168,7 +168,7 @@ class TestNodeManager:
|
||||
# assert nodemanager.config.topdir == source == config.topdir
|
||||
nodemanager.makegateways()
|
||||
nodemanager.rsync_roots()
|
||||
p, = nodemanager.gwmanager.multi_exec(
|
||||
(p,) = nodemanager.gwmanager.multi_exec(
|
||||
"import os ; channel.send(os.getcwd())"
|
||||
).receive_each()
|
||||
p = py.path.local(p)
|
||||
@@ -269,5 +269,5 @@ class TestNodeManager:
|
||||
reprec = testdir.inline_run(
|
||||
"-d", "--rsyncdir=%s" % testdir.tmpdir, "--tx", specssh, testdir.tmpdir
|
||||
)
|
||||
rep, = reprec.getreports("pytest_runtest_logreport")
|
||||
(rep,) = reprec.getreports("pytest_runtest_logreport")
|
||||
assert rep.passed
|
||||
|
||||
Reference in New Issue
Block a user