mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-02-07 11:50:21 +00:00
Merge pull request #645 from tahoe-lafs/3239.python2-new-style-regression-test
Fix the new-style class regression test Fixes: ticket:3239
This commit is contained in:
commit
0723a2f4d2
0
newsfragments/3239.minor
Normal file
0
newsfragments/3239.minor
Normal file
@ -114,7 +114,7 @@ def check(options):
|
|||||||
class FakeTransport(object):
|
class FakeTransport(object):
|
||||||
disconnecting = False
|
disconnecting = False
|
||||||
|
|
||||||
class DeepCheckOutput(LineOnlyReceiver):
|
class DeepCheckOutput(LineOnlyReceiver, object):
|
||||||
delimiter = "\n"
|
delimiter = "\n"
|
||||||
def __init__(self, streamer, options):
|
def __init__(self, streamer, options):
|
||||||
self.streamer = streamer
|
self.streamer = streamer
|
||||||
@ -173,7 +173,7 @@ class DeepCheckOutput(LineOnlyReceiver):
|
|||||||
print("done: %d objects checked, %d healthy, %d unhealthy" \
|
print("done: %d objects checked, %d healthy, %d unhealthy" \
|
||||||
% (self.num_objects, self.files_healthy, self.files_unhealthy), file=stdout)
|
% (self.num_objects, self.files_healthy, self.files_unhealthy), file=stdout)
|
||||||
|
|
||||||
class DeepCheckAndRepairOutput(LineOnlyReceiver):
|
class DeepCheckAndRepairOutput(LineOnlyReceiver, object):
|
||||||
delimiter = "\n"
|
delimiter = "\n"
|
||||||
def __init__(self, streamer, options):
|
def __init__(self, streamer, options):
|
||||||
self.streamer = streamer
|
self.streamer = streamer
|
||||||
@ -271,7 +271,7 @@ class DeepCheckAndRepairOutput(LineOnlyReceiver):
|
|||||||
% (self.post_repair_files_healthy,
|
% (self.post_repair_files_healthy,
|
||||||
self.post_repair_files_unhealthy), file=stdout)
|
self.post_repair_files_unhealthy), file=stdout)
|
||||||
|
|
||||||
class DeepCheckStreamer(LineOnlyReceiver):
|
class DeepCheckStreamer(LineOnlyReceiver, object):
|
||||||
|
|
||||||
def deepcheck_location(self, options, where):
|
def deepcheck_location(self, options, where):
|
||||||
stdout = options.stdout
|
stdout = options.stdout
|
||||||
|
@ -12,7 +12,7 @@ from allmydata.util.encodingutil import quote_output, quote_path
|
|||||||
class FakeTransport(object):
|
class FakeTransport(object):
|
||||||
disconnecting = False
|
disconnecting = False
|
||||||
|
|
||||||
class ManifestStreamer(LineOnlyReceiver):
|
class ManifestStreamer(LineOnlyReceiver, object):
|
||||||
delimiter = "\n"
|
delimiter = "\n"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
from foolscap.logging.incident import IncidentQualifier
|
from foolscap.logging.incident import IncidentQualifier
|
||||||
class NonQualifier(IncidentQualifier):
|
class NonQualifier(IncidentQualifier, object):
|
||||||
def check_event(self, ev):
|
def check_event(self, ev):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ from io import BytesIO
|
|||||||
from twisted.internet import protocol, defer
|
from twisted.internet import protocol, defer
|
||||||
|
|
||||||
|
|
||||||
class _EverythingGetter(protocol.ProcessProtocol):
|
class _EverythingGetter(protocol.ProcessProtocol, object):
|
||||||
|
|
||||||
def __init__(self, deferred, stdinBytes=None):
|
def __init__(self, deferred, stdinBytes=None):
|
||||||
self.deferred = deferred
|
self.deferred = deferred
|
||||||
|
@ -270,4 +270,3 @@ while True:
|
|||||||
f.write("directories-written: %d\n" % directories_written)
|
f.write("directories-written: %d\n" % directories_written)
|
||||||
f.close()
|
f.close()
|
||||||
os.rename(stats_out+".tmp", stats_out)
|
os.rename(stats_out+".tmp", stats_out)
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ from allmydata.util.encodingutil import get_filesystem_encoding
|
|||||||
from foolscap.api import Tub, fireEventually, flushEventualQueue
|
from foolscap.api import Tub, fireEventually, flushEventualQueue
|
||||||
from twisted.python import log, procutils
|
from twisted.python import log, procutils
|
||||||
|
|
||||||
class StallableHTTPGetterDiscarder(tw_client.HTTPPageGetter):
|
class StallableHTTPGetterDiscarder(tw_client.HTTPPageGetter, object):
|
||||||
full_speed_ahead = False
|
full_speed_ahead = False
|
||||||
_bytes_so_far = 0
|
_bytes_so_far = 0
|
||||||
stalled = None
|
stalled = None
|
||||||
@ -41,7 +41,7 @@ class StallableHTTPGetterDiscarder(tw_client.HTTPPageGetter):
|
|||||||
self.stalled = None
|
self.stalled = None
|
||||||
return tw_client.HTTPPageGetter.handleResponseEnd(self)
|
return tw_client.HTTPPageGetter.handleResponseEnd(self)
|
||||||
|
|
||||||
class StallableDiscardingHTTPClientFactory(tw_client.HTTPClientFactory):
|
class StallableDiscardingHTTPClientFactory(tw_client.HTTPClientFactory, object):
|
||||||
protocol = StallableHTTPGetterDiscarder
|
protocol = StallableHTTPGetterDiscarder
|
||||||
|
|
||||||
def discardPage(url, stall=False, *args, **kwargs):
|
def discardPage(url, stall=False, *args, **kwargs):
|
||||||
@ -477,7 +477,7 @@ this file are ignored.
|
|||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
class ClientWatcher(protocol.ProcessProtocol):
|
class ClientWatcher(protocol.ProcessProtocol, object):
|
||||||
ended = False
|
ended = False
|
||||||
def outReceived(self, data):
|
def outReceived(self, data):
|
||||||
print("OUT:", data)
|
print("OUT:", data)
|
||||||
@ -504,4 +504,3 @@ if __name__ == '__main__':
|
|||||||
# removed each time we run.
|
# removed each time we run.
|
||||||
sf = SystemFramework("_test_memory", mode)
|
sf = SystemFramework("_test_memory", mode)
|
||||||
sf.run()
|
sf.run()
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ from ..util.eliotutil import (
|
|||||||
inline_callbacks,
|
inline_callbacks,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Expect(Protocol):
|
class Expect(Protocol, object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._expectations = []
|
self._expectations = []
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ class Expect(Protocol):
|
|||||||
d.errback(reason)
|
d.errback(reason)
|
||||||
|
|
||||||
|
|
||||||
class _ProcessProtocolAdapter(ProcessProtocol):
|
class _ProcessProtocolAdapter(ProcessProtocol, object):
|
||||||
def __init__(self, fds):
|
def __init__(self, fds):
|
||||||
self._fds = fds
|
self._fds = fds
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ class CLINodeAPI(object):
|
|||||||
return stopping
|
return stopping
|
||||||
|
|
||||||
|
|
||||||
class _WaitForEnd(ProcessProtocol):
|
class _WaitForEnd(ProcessProtocol, object):
|
||||||
def __init__(self, ended):
|
def __init__(self, ended):
|
||||||
self._ended = ended
|
self._ended = ended
|
||||||
|
|
||||||
|
@ -1,32 +1,71 @@
|
|||||||
"""
|
"""
|
||||||
Tests to check for Python2 regressions
|
Tests to check for Python2 regressions
|
||||||
"""
|
"""
|
||||||
from twisted.trial import unittest
|
|
||||||
|
from inspect import isclass
|
||||||
|
|
||||||
from twisted.python.modules import getModule
|
from twisted.python.modules import getModule
|
||||||
|
|
||||||
class PythonTwoRegressions(unittest.TestCase):
|
from testtools import (
|
||||||
"""
|
TestCase,
|
||||||
A test class to hold Python2 regression tests.
|
)
|
||||||
"""
|
from testtools.matchers import (
|
||||||
skip = "https://tahoe-lafs.org/trac/tahoe-lafs/ticket/3239"
|
Equals,
|
||||||
|
)
|
||||||
|
|
||||||
def is_new_style(self, cls):
|
BLACKLIST = {
|
||||||
"""check for being a new-style class"""
|
"allmydata.test.check_load",
|
||||||
# another test could be: issubclass(value, type)
|
"allmydata.watchdog._watchdog_541",
|
||||||
has_class_attr = hasattr(cls, '__class__')
|
"allmydata.watchdog.inotify",
|
||||||
dict_or_slots = '__dict__' in dir(cls) or hasattr(cls, '__slots__')
|
"allmydata.windows.inotify",
|
||||||
return has_class_attr and dict_or_slots
|
"allmydata.windows.registry",
|
||||||
|
"allmydata.windows.tahoesvc",
|
||||||
|
}
|
||||||
|
|
||||||
def test_old_style_class(self):
|
|
||||||
|
def is_new_style(cls):
|
||||||
"""
|
"""
|
||||||
Check if all classes are new-style classes
|
:return bool: ``True`` if and only if the given class is "new style".
|
||||||
"""
|
"""
|
||||||
|
# All new-style classes are instances of type. By definition.
|
||||||
|
return isinstance(cls, type)
|
||||||
|
|
||||||
|
def defined_here(cls, where):
|
||||||
|
"""
|
||||||
|
:return bool: ``True`` if and only if the given class was defined in a
|
||||||
|
module with the given name.
|
||||||
|
|
||||||
|
:note: Classes can lie about where they are defined. Try not to do that.
|
||||||
|
"""
|
||||||
|
return cls.__module__ == where
|
||||||
|
|
||||||
|
class PythonTwoRegressions(TestCase):
|
||||||
|
"""
|
||||||
|
Regression tests for Python 2 behaviors related to Python 3 porting.
|
||||||
|
"""
|
||||||
|
def test_new_style_classes(self):
|
||||||
|
"""
|
||||||
|
All classes in Tahoe-LAFS are new-style.
|
||||||
|
"""
|
||||||
|
newstyle = set()
|
||||||
|
classic = set()
|
||||||
for mod in getModule("allmydata").walkModules():
|
for mod in getModule("allmydata").walkModules():
|
||||||
|
if mod.name in BLACKLIST:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# iterAttributes will only work on loaded modules. So, load it.
|
||||||
|
mod.load()
|
||||||
|
|
||||||
for attr in mod.iterAttributes():
|
for attr in mod.iterAttributes():
|
||||||
value = attr.load()
|
value = attr.load()
|
||||||
if isinstance(value, str):
|
if isclass(value) and defined_here(value, mod.name):
|
||||||
# apparently strings are note a new-style class (in Python 2.7)
|
if is_new_style(value):
|
||||||
# so we skip testing them
|
newstyle.add(value)
|
||||||
return
|
else:
|
||||||
self.assertTrue(self.is_new_style(value),
|
classic.add(value)
|
||||||
"{} does not seem to be a new-style class".format(attr.name))
|
|
||||||
|
self.assertThat(
|
||||||
|
classic,
|
||||||
|
Equals(set()),
|
||||||
|
"Expected to find no classic classes.",
|
||||||
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import exceptions, os
|
import exceptions, os
|
||||||
from repr import Repr
|
from repr import Repr
|
||||||
|
|
||||||
class BetterRepr(Repr):
|
class BetterRepr(Repr, object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Repr.__init__(self)
|
Repr.__init__(self)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class SingleFileError(Exception):
|
|||||||
"""You are not permitted to add a job to a full pipeline."""
|
"""You are not permitted to add a job to a full pipeline."""
|
||||||
|
|
||||||
|
|
||||||
class ExpandableDeferredList(defer.Deferred):
|
class ExpandableDeferredList(defer.Deferred, object):
|
||||||
# like DeferredList(fireOnOneErrback=True) with a built-in
|
# like DeferredList(fireOnOneErrback=True) with a built-in
|
||||||
# gatherResults(), but you can add new Deferreds until you close it. This
|
# gatherResults(), but you can add new Deferreds until you close it. This
|
||||||
# gives you a chance to add don't-complain-about-unhandled-error errbacks
|
# gives you a chance to add don't-complain-about-unhandled-error errbacks
|
||||||
|
@ -322,7 +322,7 @@ def humanize_failure(f):
|
|||||||
return (f.getTraceback(), http.REQUEST_ENTITY_TOO_LARGE)
|
return (f.getTraceback(), http.REQUEST_ENTITY_TOO_LARGE)
|
||||||
return (str(f), None)
|
return (str(f), None)
|
||||||
|
|
||||||
class MyExceptionHandler(appserver.DefaultExceptionHandler):
|
class MyExceptionHandler(appserver.DefaultExceptionHandler, object):
|
||||||
def simple(self, ctx, text, code=http.BAD_REQUEST):
|
def simple(self, ctx, text, code=http.BAD_REQUEST):
|
||||||
req = IRequest(ctx)
|
req = IRequest(ctx)
|
||||||
req.setResponseCode(code)
|
req.setResponseCode(code)
|
||||||
@ -461,7 +461,7 @@ class MultiFormatPage(Page):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TokenOnlyWebApi(resource.Resource):
|
class TokenOnlyWebApi(resource.Resource, object):
|
||||||
"""
|
"""
|
||||||
I provide a rend.Page implementation that only accepts POST calls,
|
I provide a rend.Page implementation that only accepts POST calls,
|
||||||
and only if they have a 'token=' arg with the correct
|
and only if they have a 'token=' arg with the correct
|
||||||
|
@ -20,7 +20,7 @@ from allmydata.web.common import IOpHandleTable, MyExceptionHandler
|
|||||||
# surgery may induce a dependency upon a particular version of twisted.web
|
# surgery may induce a dependency upon a particular version of twisted.web
|
||||||
|
|
||||||
parse_qs = http.parse_qs
|
parse_qs = http.parse_qs
|
||||||
class MyRequest(appserver.NevowRequest):
|
class MyRequest(appserver.NevowRequest, object):
|
||||||
fields = None
|
fields = None
|
||||||
_tahoe_request_had_error = None
|
_tahoe_request_had_error = None
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user