--- application/configuration/__init__.py.orig 2019-08-02 13:55:47 UTC +++ application/configuration/__init__.py @@ -3,7 +3,7 @@ import os -from ConfigParser import SafeConfigParser, NoSectionError +from configparser import SafeConfigParser, NoSectionError from inspect import isclass from itertools import chain from types import BuiltinFunctionType @@ -106,7 +106,7 @@ class SaveState(object): return self.__state__[item] def __iter__(self): - return self.__state__.iteritems() + return iter(self.__state__.items()) def __len__(self): return len(self.__state__) @@ -143,10 +143,10 @@ class ConfigSectionType(type): def __new__(mcls, name, bases, dictionary): settings = {} # copy all settings defined by parents unless also defined in the class being constructed - for name, setting in chain(*(cls.__settings__.iteritems() for cls in bases if isinstance(cls, ConfigSectionType))): + for name, setting in chain(*(iter(cls.__settings__.items()) for cls in bases if isinstance(cls, ConfigSectionType))): if name not in dictionary and name not in settings: settings[name] = ConfigSetting(type=setting.type, value=setting.value) - for attr, value in dictionary.iteritems(): + for attr, value in dictionary.items(): if isinstance(value, ConfigSetting): settings[attr] = value elif attr.startswith('__') or isdescriptor(value) or type(value) is BuiltinFunctionType: @@ -174,7 +174,7 @@ class ConfigSectionType(type): return '%s:\n%s' % (cls.__name__, '\n'.join(' %s = %r' % (name, value) for name, value in cls) or ' pass') def __iter__(cls): - return ((name, descriptor.__get__(cls, cls.__class__)) for name, descriptor in cls.__settings__.iteritems()) + return ((name, descriptor.__get__(cls, cls.__class__)) for name, descriptor in cls.__settings__.items()) def __setattr__(cls, name, value): if name == '__settings__' or name not in cls.__settings__: # need to check for __settings__ as it is set first and the second part of the test depends on it being available @@ -198,7 +198,7 @@ class ConfigSectionType(type): config_file = cfgfile else: config_file = cls.__cfgtype__(cfgfile) - if isinstance(section, basestring): + if isinstance(section, str): section_list = (section,) else: section_list = section @@ -214,7 +214,7 @@ class ConfigSectionType(type): if not set(kw).issubset(cls.__settings__): raise TypeError('Got unexpected keyword argument %r' % set(kw).difference(cls.__settings__).pop()) with AtomicUpdate(cls): - for name, value in kw.iteritems(): + for name, value in kw.items(): setattr(cls, name, value) def reset(cls, state=None): @@ -224,11 +224,11 @@ class ConfigSectionType(type): raise TypeError('state should be a SaveState instance') if state.__owner__ is not cls: raise ValueError('save state does not belong to this config section') - for name, descriptor in cls.__settings__.iteritems(): + for name, descriptor in cls.__settings__.items(): descriptor.__set__(cls, state[name], convert=False) -class ConfigSection(object): +class ConfigSection(object, metaclass=ConfigSectionType): """ Defines a section in the configuration file @@ -245,8 +245,6 @@ class ConfigSection(object): for reading multiple sections (they will be read in the order the iterable returns them) """ - - __metaclass__ = ConfigSectionType __cfgtype__ = ConfigFile __cfgfile__ = None --- application/configuration/datatypes.py.orig 2019-07-30 19:01:31 UTC +++ application/configuration/datatypes.py @@ -19,7 +19,7 @@ class Boolean(object): '0': False, 'no': False, 'false': False, 'off': False} def __new__(cls, value): - if isinstance(value, (int, long, float)): + if isinstance(value, (int, float)): return bool(value) elif not hasattr(value, 'lower'): raise TypeError('value must be a string, number or boolean') @@ -33,9 +33,9 @@ class LogLevel(object): """A log level indicated by a non-negative integer or one of the named attributes of log.level""" def __new__(cls, value): - if isinstance(value, basestring): + if isinstance(value, str): value = value.upper() - elif not isinstance(value, (int, long)): + elif not isinstance(value, int): raise TypeError('value must be a string or number') named_levels = {level.name: level for level in log.level.named_levels} if value in named_levels: @@ -52,7 +52,7 @@ class StringList(object): def __new__(cls, value): if isinstance(value, (tuple, list)): return [str(x) for x in value] - elif isinstance(value, basestring): + elif isinstance(value, str): if value.lower() in ('none', ''): return [] return re.split(r'\s*,\s*', value) @@ -77,7 +77,7 @@ class Hostname(str): """A Hostname or an IP address. The keyword `any' stands for '0.0.0.0'""" def __new__(cls, value): - if not isinstance(value, basestring): + if not isinstance(value, str): raise TypeError('value must be a string') if value.lower() == 'any': return '0.0.0.0' @@ -90,7 +90,7 @@ class HostnameList(object): def __new__(cls, description): if isinstance(description, (list, tuple)): return [Hostname(x) for x in description] - elif not isinstance(description, basestring): + elif not isinstance(description, str): raise TypeError('value must be a string, list or tuple') if description.lower() == 'none': return [] @@ -130,14 +130,14 @@ class NetworkRange(object): """ def __new__(cls, description): - if isinstance(description, tuple) and len(description) == 2 and all(isinstance(item, (int, long)) and 0 <= item < 2**32 for item in description): + if isinstance(description, tuple) and len(description) == 2 and all(isinstance(item, int) and 0 <= item < 2**32 for item in description): return description - elif not isinstance(description, basestring): + elif not isinstance(description, str): raise TypeError('value must be a string, or a tuple with 2 32-bit unsigned integers') if not description or description.lower() == 'none': - return 0L, 0xFFFFFFFFL + return 0, 0xFFFFFFFF if description.lower() == 'any': - return 0L, 0L # This is the any address 0.0.0.0 + return 0, 0 # This is the any address 0.0.0.0 match = re.search(r'^(?P
.+?)/(?P\d+)$', description) if match: ip_address = match.group('address') @@ -154,7 +154,7 @@ class NetworkRange(object): network_address = socket.inet_aton(ip_address) except Exception: raise ValueError('invalid IP address: %r' % ip_address) - network_mask = (0xFFFFFFFFL << 32-mask_bits) & 0xFFFFFFFFL + network_mask = (0xFFFFFFFF << 32-mask_bits) & 0xFFFFFFFF base_address = struct.unpack('!L', network_address)[0] & network_mask return base_address, network_mask @@ -167,7 +167,7 @@ class NetworkRangeList(object): return description elif isinstance(description, (list, tuple)): return [NetworkRange(x) for x in description] or None - elif not isinstance(description, basestring): + elif not isinstance(description, str): raise TypeError('value must be a string, list, tuple or None') if description.lower() == 'none': return None @@ -206,9 +206,9 @@ class NetworkAddress(object): def __new__(cls, value): if value is None: return value - elif isinstance(value, tuple) and len(value) == 2 and isinstance(value[1], (int, long)): + elif isinstance(value, tuple) and len(value) == 2 and isinstance(value[1], int): return Hostname(value[0]), value[1] - elif not isinstance(value, basestring): + elif not isinstance(value, str): raise TypeError('value must be a string, a (host, port) tuple or None') if value.lower() == 'none': return None --- application/debug/memory.py.orig 2019-07-30 18:59:31 UTC +++ application/debug/memory.py @@ -67,7 +67,7 @@ class Cycle(tuple): priority = 2 elif type(obj).__module__ in ('__builtin__', 'builtins'): priority = 1 - elif isinstance(obj, (tuple, list, dict, set, frozenset, str, unicode)): + elif isinstance(obj, (tuple, list, dict, set, frozenset, str)): priority = 3 else: priority = 4 @@ -84,9 +84,9 @@ class Cycle(tuple): d = cycle.popleft() try: if cycle: - string += ' .%s' % (key for key, value in d.iteritems() if value is cycle[0]).next() + string += ' .%s' % next((key for key, value in d.items() if value is cycle[0])) else: - string += ' .%s' % (key for key, value in d.iteritems() if value is first_obj).next() + string += ' .%s' % next((key for key, value in d.items() if value is first_obj)) except StopIteration: string += ' .__dict__ -> %s' % repr(d) string += ' -> ' @@ -96,7 +96,7 @@ class Cycle(tuple): def memory_dump(show_cycles=True, show_objects=False): - print '\nGARBAGE:' + print('\nGARBAGE:') gc.collect() garbage = gc.garbage[:] @@ -109,7 +109,7 @@ def memory_dump(show_cycles=True, show_objects=False): cycles = set() remaining_nodes = nodes.copy() while remaining_nodes: - path = [next(remaining_nodes.itervalues())] + path = [next(iter(remaining_nodes.values()))] while path: node = path[-1] remaining_nodes.pop(id(node.object), None) @@ -123,16 +123,16 @@ def memory_dump(show_cycles=True, show_objects=False): node.visitable_successors = deque(node.successors) path.pop(-1) - for node in nodes.itervalues(): + for node in nodes.values(): node.successors = node.visitable_successors = None - print '\nCOLLECTABLE CYCLES:' + print('\nCOLLECTABLE CYCLES:') for cycle in (c for c in cycles if c.collectable): - print cycle + print(cycle) - print '\nUNCOLLECTABLE CYCLES:' + print('\nUNCOLLECTABLE CYCLES:') for cycle in (c for c in cycles if not c.collectable): - print cycle + print(cycle) if show_objects: try: @@ -141,12 +141,12 @@ def memory_dump(show_cycles=True, show_objects=False): except Exception: console_width = 80 - print '\nGARBAGE OBJECTS:' + print('\nGARBAGE OBJECTS:') for x in garbage: s = str(x) if len(s) > console_width-2: s = s[:console_width-5] + '...' - print '%s\n %s' % (type(x), s) + print('%s\n %s' % (type(x), s)) gc.enable() --- application/debug/timing.py.orig 2019-07-30 18:55:18 UTC +++ application/debug/timing.py @@ -27,7 +27,7 @@ import struct import sys from collections import deque -from itertools import chain, izip, takewhile +from itertools import chain, takewhile from time import clock, time from application.python.decorator import decorator, preserve_signature @@ -37,8 +37,8 @@ from application.python.types import MarkerType __all__ = 'Timer', 'TimeProbe', 'timer', 'time_probe', 'measure_time' -class Automatic(object): - __metaclass__ = MarkerType +class Automatic(object, metaclass=MarkerType): + pass class Autodetect(int): @@ -121,11 +121,11 @@ class Timer(object): normalized_time, time_unit = normalize_time(statement_time) if self.description is not None: - format_string = u'{} loops, best of {}: {:.{precision}g} {} per loop ({:.{rate_precision}f} operations/sec); {description}' + format_string = '{} loops, best of {}: {:.{precision}g} {} per loop ({:.{rate_precision}f} operations/sec); {description}' else: - format_string = u'{} loops, best of {}: {:.{precision}g} {} per loop ({:.{rate_precision}f} operations/sec)' + format_string = '{} loops, best of {}: {:.{precision}g} {} per loop ({:.{rate_precision}f} operations/sec)' rate_precision = 2 if statement_rate < 10 else 1 if statement_rate < 100 else 0 - print format_string.format(loops, self.repeat, normalized_time, time_unit, statement_rate, description=self.description, precision=3, rate_precision=rate_precision) + print(format_string.format(loops, self.repeat, normalized_time, time_unit, statement_rate, description=self.description, precision=3, rate_precision=rate_precision)) finally: del parent finally: @@ -245,7 +245,7 @@ class Timer(object): byte_increments.appendleft(len(loop_header)) line_increments.appendleft(1) - line_numbers_table = bytes(bytearray(chain.from_iterable(takewhile(WithinCodeRange(len(loop_header + code_bytes)), izip(byte_increments, line_increments))))) + line_numbers_table = bytes(bytearray(chain.from_iterable(takewhile(WithinCodeRange(len(loop_header + code_bytes)), zip(byte_increments, line_increments))))) return code(o_code.co_argcount, o_code.co_nlocals, o_code.co_stacksize, o_code.co_flags, new_code_bytes, code_constants, names, o_code.co_varnames, o_code.co_filename, o_code.co_name, o_code.co_firstlineno + line_offset - 1, line_numbers_table, o_code.co_freevars, o_code.co_cellvars) @@ -312,10 +312,10 @@ class TimeProbe(object): error_string = '' if self.description is not None: # format_string = u'{:.{precision}g} {}{}; {description}' - format_string = u'{description}: {:.{precision}g} {}{}' + format_string = '{description}: {:.{precision}g} {}{}' else: - format_string = u'{:.{precision}g} {}{}' - print format_string.format(normalized_time, time_unit, error_string, description=self.description, precision=3) + format_string = '{:.{precision}g} {}{}' + print(format_string.format(normalized_time, time_unit, error_string, description=self.description, precision=3)) del self._start_time time_probe = TimeProbe @@ -357,7 +357,7 @@ class _MeasurementProbe(object): gc_enabled = gc.isenabled() gc.disable() try: - return _MeasurementSamples(self.get_sample() for _ in xrange(iterations)) + return _MeasurementSamples(self.get_sample() for _ in range(iterations)) finally: if gc_enabled: gc.enable() --- application/log/__init__.py.orig 2020-03-02 11:53:05 UTC +++ application/log/__init__.py @@ -145,9 +145,7 @@ logging.Logger.exception = Logger.exception.__func__ logging.exception = exception -class ContextualLogger(object): - __metaclass__ = abc.ABCMeta - +class ContextualLogger(object, metaclass=abc.ABCMeta): def __init__(self, logger, **context): self.logger = logger self.__dict__.update(context) @@ -239,7 +237,7 @@ class LevelHandler(object): @property def named_levels(self): - return {self.NOTSET, self.DEBUG, self.INFO, self.WARNING, self.ERROR, self.CRITICAL} | {item for item in self.__dict__.values() if isinstance(item, NamedLevel)} + return {self.NOTSET, self.DEBUG, self.INFO, self.WARNING, self.ERROR, self.CRITICAL} | {item for item in list(self.__dict__.values()) if isinstance(item, NamedLevel)} def __setattr__(self, name, value): if isinstance(value, NamedLevel) and value not in self.named_levels: @@ -273,7 +271,7 @@ class SyslogHandler(logging.Handler): try: priority = self.priority_map.get(record.levelno, syslog.LOG_INFO) message = self.format(record) - if isinstance(message, unicode): + if isinstance(message, str): message = message.encode('UTF-8') for line in message.rstrip().replace('\0', '#000').split('\n'): # syslog.syslog() raises TypeError if null bytes are present in the message syslog.syslog(priority, line) @@ -322,7 +320,7 @@ class StandardIOLogger(io.IOBase): def write(self, string): self._checkClosed() - if isinstance(string, unicode): + if isinstance(string, str): string = string.encode(self._encoding) lines = (self._buffer + string).split('\n') self._buffer = lines[-1] @@ -332,7 +330,7 @@ class StandardIOLogger(io.IOBase): def writelines(self, lines): self._checkClosed() for line in lines: - if isinstance(line, unicode): + if isinstance(line, str): line = line.encode(self._encoding) self._logger(line) @@ -340,7 +338,7 @@ class StandardIOLogger(io.IOBase): class WhenNotInteractive(object): """True when running under a non-interactive interpreter and False otherwise""" - def __nonzero__(self): + def __bool__(self): return hasattr(__main__, '__file__') or getattr(sys, 'frozen', False) def __repr__(self): --- application/log/extensions/twisted/__init__.py.orig 2017-06-25 16:08:39 UTC +++ application/log/extensions/twisted/__init__.py @@ -1,5 +1,5 @@ -from __future__ import absolute_import + import os import sys --- application/log/extensions/twisted/twisted.py.orig 2017-06-24 11:41:15 UTC +++ application/log/extensions/twisted/twisted.py @@ -1,5 +1,5 @@ -from __future__ import absolute_import + import os import sys --- application/notification.py.orig 2019-07-30 18:57:40 UTC +++ application/notification.py @@ -17,14 +17,12 @@ from application.python.weakref import weakobjectmap __all__ = 'Any', 'UnknownSender', 'IObserver', 'NotificationData', 'Notification', 'NotificationCenter', 'ObserverWeakrefProxy' -class Any(object): +class Any(object, metaclass=MarkerType): """Any sender or notification name""" - __metaclass__ = MarkerType -class UnknownSender(object): +class UnknownSender(object, metaclass=MarkerType): """A special sender used for anonymous notifications""" - __metaclass__ = MarkerType class IObserver(Interface): @@ -61,7 +59,7 @@ class ObserverWeakrefProxy(object): # noinspection PyUnusedLocal def cleanup(self, ref): # remove all observer's remaining registrations (the ones that the observer didn't remove itself) - for notification_center in NotificationCenter.__instances__.itervalues(): + for notification_center in NotificationCenter.__instances__.values(): notification_center.purge_observer(self) def handle_notification(self, notification): @@ -77,7 +75,7 @@ class NotificationData(object): self.__dict__.update(kwargs) def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join('%s=%r' % (name, value) for name, value in self.__dict__.iteritems())) + return '%s(%s)' % (self.__class__.__name__, ', '.join('%s=%r' % (name, value) for name, value in self.__dict__.items())) class Notification(object): @@ -103,15 +101,13 @@ class Notification(object): return '%s(%r, %r, %r)' % (self.__class__.__name__, self.name, self.sender, self.data) -class NotificationCenter(object): +class NotificationCenter(object, metaclass=Singleton): """ A NotificationCenter allows observers to subscribe to receive notifications identified by name and sender and will distribute the posted notifications according to those subscriptions. """ - __metaclass__ = Singleton - queue = ThreadLocal(deque) def __init__(self, name='default'): @@ -178,7 +174,7 @@ class NotificationCenter(object): def purge_observer(self, observer): """Remove all the observer's subscriptions.""" with self.lock: - subscriptions = [(key, observer_set) for key, observer_set in self.observers.iteritems() if observer in observer_set] + subscriptions = [(key, observer_set) for key, observer_set in self.observers.items() if observer in observer_set] for key, observer_set in subscriptions: observer_set.remove(observer) if not observer_set: --- application/process.py.orig 2019-08-20 09:13:31 UTC +++ application/process.py @@ -126,11 +126,9 @@ class RuntimeSettings(object): raise ProcessError('lacking permissions to access the runtime directory at %s' % directory) -class Process(object): +class Process(object, metaclass=Singleton): """Control how the current process runs and interacts with the operating system""" - __metaclass__ = Singleton - def __init__(self): self._daemon = False self._pidfile = None @@ -290,10 +288,8 @@ class Process(object): raise RuntimeError('Network is not available after waiting for {} seconds'.format(wait_time)) -class Signals(object): +class Signals(object, metaclass=Singleton): """Interface to the system signals""" - - __metaclass__ = Singleton def __init__(self): self._handlers = {} --- application/python/__init__.py.orig 2019-06-03 16:59:08 UTC +++ application/python/__init__.py @@ -1,7 +1,7 @@ """Python language extensions""" -from __builtin__ import min as minimum, max as maximum +from builtins import min as minimum, max as maximum from application.python.types import NullType --- application/python/decorator.py.orig 2020-03-12 00:03:13 UTC +++ application/python/decorator.py @@ -20,7 +20,7 @@ def preserve_signature(func): def fix_signature(wrapper): exec_scope = {} parameters = formatargspec(*getargspec(func), formatvalue=lambda value: '') - exec 'def {0}{1}: return wrapper{1}'.format(func.__name__, parameters) in {'wrapper': wrapper}, exec_scope # can't use tuple form here (see https://bugs.python.org/issue21591) + exec('def {0}{1}: return wrapper{1}'.format(func.__name__, parameters), {'wrapper': wrapper}, exec_scope) # can't use tuple form here (see https://bugs.python.org/issue21591) new_wrapper = exec_scope.pop(func.__name__) new_wrapper.__name__ = func.__name__ new_wrapper.__doc__ = func.__doc__ @@ -50,12 +50,12 @@ def execute_once(func): def __call__(self, *args, **kw): with self.im_func_wrapper.lock: method = self.__method__ - check_arguments.__get__(method.im_self, method.im_class)(*args, **kw) - instance = method.im_self if method.im_self is not None else args[0] + check_arguments.__get__(method.__self__, method.__self__.__class__)(*args, **kw) + instance = method.__self__ if method.__self__ is not None else args[0] if self.im_func_wrapper.__callmap__.get(instance, False): return self.im_func_wrapper.__callmap__[instance] = True - self.im_func_wrapper.__callmap__[method.im_class] = True + self.im_func_wrapper.__callmap__[method.__self__.__class__] = True return method.__call__(*args, **kw) def __dir__(self): @@ -85,7 +85,7 @@ def execute_once(func): @property def called(self): - return self.im_func_wrapper.__callmap__.get(self.__method__.im_self if self.__method__.im_self is not None else self.__method__.im_class, False) + return self.im_func_wrapper.__callmap__.get(self.__method__.__self__ if self.__method__.__self__ is not None else self.__method__.__self__.__class__, False) @property def lock(self): --- application/python/queue.py.orig 2019-07-30 10:38:20 UTC +++ application/python/queue.py @@ -1,7 +1,7 @@ """Event processing queues, that process the events in a distinct thread""" -import Queue +import queue from threading import Thread, Event, Lock from application import log @@ -13,9 +13,9 @@ __all__ = 'EventQueue', 'CumulativeEventQueue' # Special events that control the queue operation (for internal use) -class StopProcessing: __metaclass__ = MarkerType -class ProcessEvents: __metaclass__ = MarkerType -class DiscardEvents: __metaclass__ = MarkerType +class StopProcessing(metaclass=MarkerType): pass +class ProcessEvents(metaclass=MarkerType): pass +class DiscardEvents(metaclass=MarkerType): pass class EventQueue(Thread): @@ -31,7 +31,7 @@ class EventQueue(Thread): self._pause_counter = 0 self._pause_lock = Lock() self._accepting_events = True - self.queue = Queue.Queue() + self.queue = queue.Queue() self.handle = handler self.load(preload) self._active.set() @@ -106,7 +106,7 @@ class EventQueue(Thread): try: while True: self.queue.get_nowait() - except Queue.Empty: + except queue.Empty: pass self.unpause() @@ -120,7 +120,7 @@ class EventQueue(Thread): event = self.queue.get_nowait() if event is not StopProcessing: unhandled.append(event) - except Queue.Empty: + except queue.Empty: pass return unhandled --- application/python/threadpool.py.orig 2019-07-30 10:28:55 UTC +++ application/python/threadpool.py @@ -1,7 +1,7 @@ """A generic, resizable thread pool""" -from Queue import Queue +from queue import Queue from itertools import count from threading import Lock, Thread, current_thread --- application/python/types.py.orig 2017-06-27 15:56:11 UTC +++ application/python/types.py @@ -1,8 +1,8 @@ """Types and meta classes""" -from __future__ import absolute_import + from types import FunctionType, UnboundMethodType from application.python.decorator import preserve_signature @@ -26,7 +26,7 @@ class Singleton(type): # noinspection PyShadowingNames @preserve_signature(initializer) def instance_creator(cls, *args, **kw): - key = (args, tuple(sorted(kw.iteritems()))) + key = (args, tuple(sorted(kw.items()))) try: hash(key) except TypeError: @@ -53,10 +53,8 @@ class NullTypeMeta(type): return cls.__instance__ -class NullType(object): +class NullType(object, metaclass=NullTypeMeta): """Instances of this class always and reliably "do nothing".""" - - __metaclass__ = NullTypeMeta __name__ = 'Null' def __init__(self, *args, **kw): @@ -77,7 +75,7 @@ class NullType(object): def __len__(self): return 0 - def __nonzero__(self): + def __bool__(self): return False def __eq__(self, other): @@ -125,7 +123,7 @@ class NullType(object): def __iter__(self): return self - def next(self): + def __next__(self): raise StopIteration @@ -140,5 +138,5 @@ class MarkerType(type): def __repr__(cls): return cls.__name__ - def __nonzero__(cls): + def __bool__(cls): return cls.__boolean__ --- application/python/weakref.py.orig 2017-06-27 16:26:38 UTC +++ application/python/weakref.py @@ -1,6 +1,6 @@ -from __future__ import absolute_import + import weakref from collections import MutableMapping, deque @@ -21,7 +21,7 @@ class objectref(weakref.ref): class weakobjectid(long): def __new__(cls, object, discard_callback): - instance = long.__new__(cls, id(object)) + instance = int.__new__(cls, id(object)) instance.ref = objectref(object, discard_callback) return instance @@ -72,7 +72,7 @@ class weakobjectmap(MutableMapping): return id(key) in self.__data__ def __iter__(self): - return self.iterkeys() + return iter(self.keys()) def __len__(self): return len(self.__data__) @@ -84,14 +84,14 @@ class weakobjectmap(MutableMapping): return self.__class__(self) def __deepcopy__(self, memo): - return self.__class__((key, deepcopy(value, memo)) for key, value in self.iteritems()) + return self.__class__((key, deepcopy(value, memo)) for key, value in self.items()) def __repr__(self): with _ReprGuard(self) as guard: if guard.successive_run: return '%s({...})' % self.__class__.__name__ else: - return '%s({%s})' % (self.__class__.__name__, ', '.join(('%r: %r' % (key, value) for key, value in self.iteritems()))) + return '%s({%s})' % (self.__class__.__name__, ', '.join(('%r: %r' % (key, value) for key, value in self.items()))) @classmethod def fromkeys(cls, iterable, value=None): @@ -107,22 +107,22 @@ class weakobjectmap(MutableMapping): return self.__class__(self) def iterkeys(self): - return (key for key in (key.ref() for key in self.__data__.keys()) if key is not None) + return (key for key in (key.ref() for key in list(self.__data__.keys())) if key is not None) def itervalues(self): - return (value for key, value in ((key.ref(), value) for key, value in self.__data__.items()) if key is not None) + return (value for key, value in ((key.ref(), value) for key, value in list(self.__data__.items())) if key is not None) def iteritems(self): - return ((key, value) for key, value in ((key.ref(), value) for key, value in self.__data__.items()) if key is not None) + return ((key, value) for key, value in ((key.ref(), value) for key, value in list(self.__data__.items())) if key is not None) def keys(self): - return [key for key in (key.ref() for key in self.__data__.keys()) if key is not None] + return [key for key in (key.ref() for key in list(self.__data__.keys())) if key is not None] def values(self): - return [value for key, value in ((key.ref(), value) for key, value in self.__data__.items()) if key is not None] + return [value for key, value in ((key.ref(), value) for key, value in list(self.__data__.items())) if key is not None] def items(self): - return [(key, value) for key, value in ((key.ref(), value) for key, value in self.__data__.items()) if key is not None] + return [(key, value) for key, value in ((key.ref(), value) for key, value in list(self.__data__.items())) if key is not None] def has_key(self, key): return key in self --- application/system.py.orig 2019-08-14 12:54:53 UTC +++ application/system.py @@ -13,11 +13,9 @@ __all__ = 'host', 'makedirs', 'openfile', 'unlink', 'F # System properties and attributes -class HostProperties(object): +class HostProperties(object, metaclass=Singleton): """Host specific properties""" - __metaclass__ = Singleton - @staticmethod def outgoing_ip_for(destination): try: @@ -67,7 +65,7 @@ def makedirs(path, mode=0o777): """Create a directory recursively and ignore error if it already exists""" try: os.makedirs(path, mode) - except OSError, e: + except OSError as e: if e.errno == errno.EEXIST and os.path.isdir(path) and os.access(path, os.R_OK | os.W_OK | os.X_OK): return raise --- application/version.py.orig 2019-07-30 18:58:01 UTC +++ application/version.py @@ -23,10 +23,10 @@ class Version(str): if extraversion is None: instance = str.__new__(cls, '%d.%d.%d' % (major, minor, micro)) weight = 0 - elif isinstance(extraversion, (int, long)): + elif isinstance(extraversion, int): instance = str.__new__(cls, '%d.%d.%d-%d' % (major, minor, micro, extraversion)) weight = 0 - elif isinstance(extraversion, basestring): + elif isinstance(extraversion, str): instance = str.__new__(cls, '%d.%d.%d%s' % (major, minor, micro, extraversion)) match = re.match(r'^[-.]?(?P(pre|rc|alpha|beta|))(?P\d+)$', extraversion) if match: @@ -48,7 +48,7 @@ class Version(str): def parse(cls, value): if isinstance(value, Version): return value - elif not isinstance(value, basestring): + elif not isinstance(value, str): raise TypeError('value should be a string') if value == 'undefined': return cls(None, None, None) @@ -83,7 +83,7 @@ class Version(str): def __cmp__(self, other): if isinstance(other, Version): return cmp(self._version_info, other._version_info) - elif isinstance(other, basestring): + elif isinstance(other, str): return cmp(str(self), other) else: return NotImplemented --- examples/config.py.orig 2020-02-07 16:34:27 UTC +++ examples/config.py @@ -10,9 +10,9 @@ from application.system import host class Priority(int): """A numeric priority level. The keywords High, Normal and Low map to certain numeric values.""" def __new__(cls, value): - if isinstance(value, (int, long)): + if isinstance(value, int): return int(value) - elif isinstance(value, basestring): + elif isinstance(value, str): priority_map = {'high': 10, 'normal': 50, 'low': 100} try: return priority_map.get(value.lower()) or int(value) @@ -49,11 +49,11 @@ class StorageConfig(ConfigSection): # Dump the default hardcoded values of the options defined above -print "Settings before reading the configuration file (default hardcoded values)\n" -print NetworkConfig -print -print StorageConfig -print +print("Settings before reading the configuration file (default hardcoded values)\n") +print(NetworkConfig) +print() +print(StorageConfig) +print() # Read the settings from the configuration file into the attributes of our # configuration classes. The read function takes a configuration file name @@ -86,11 +86,11 @@ NetworkConfig.read('config.ini', 'Network') StorageConfig.read('config.ini', 'Storage') # Dump the values of the options after they were loaded from the config file -print "\nSettings after reading the configuration file(s)\n" -print NetworkConfig -print -print StorageConfig -print +print("\nSettings after reading the configuration file(s)\n") +print(NetworkConfig) +print() +print(StorageConfig) +print() # Configuration options can be accessed as class attributes ip = NetworkConfig.ip @@ -102,8 +102,8 @@ ip = NetworkConfig.ip # Here is an example of such a class that will be automatically loaded -print "\n------------------------------------\n" -print "Using __cfgfile__ and __section__ to automatically load sections\n" +print("\n------------------------------------\n") +print("Using __cfgfile__ and __section__ to automatically load sections\n") class AutoNetworkConfig(ConfigSection): @@ -126,12 +126,12 @@ class AutoStorageConfig(ConfigSection): # Dump the values of the options after they were loaded from the config file -print "Settings in the automatically loaded sections\n" -print -print AutoNetworkConfig -print -print AutoStorageConfig -print +print("Settings in the automatically loaded sections\n") +print() +print(AutoNetworkConfig) +print() +print(AutoStorageConfig) +print() # We can also get individual settings from a given section. # @@ -141,10 +141,10 @@ print # above with the ConfigSection.read() method) apply here as well. # -print "\n------------------------------------\n" -print "Reading individual settings from sections without using ConfigSection" +print("\n------------------------------------\n") +print("Reading individual settings from sections without using ConfigSection") configuration = ConfigFile('config.ini') dburi = configuration.get_setting('Storage', 'dburi', type=str, default='undefined') -print "\nGot dburi directly from Storage section as `%s'\n" % dburi +print("\nGot dburi directly from Storage section as `%s'\n" % dburi) --- examples/debug.py.orig 2020-02-07 16:34:01 UTC +++ examples/debug.py @@ -10,10 +10,10 @@ s1 = 'abcdef' s2 = 'ghijkl' s3 = 'mnopqr' -print "" -print "Timing different methods of adding strings" -print "------------------------------------------" -print "" +print("") +print("Timing different methods of adding strings") +print("------------------------------------------") +print("") # the loop count can be explicitly specified, but it's easier to let the # timer automatically detect the loop count that will keep the total runtime @@ -44,15 +44,15 @@ class C2(object): from application.debug.memory import * -print "" -print "Debugging memory leaks" -print "----------------------" -print "" +print("") +print("Debugging memory leaks") +print("----------------------") +print("") a = C1() del a -print "This will reveal no memory references" +print("This will reveal no memory references") memory_dump() a = C1() @@ -61,7 +61,7 @@ a.b = b b.a = a del a, b -print "\n\nThis will reveal a collectable circular reference" +print("\n\nThis will reveal a collectable circular reference") memory_dump() a = C2() @@ -70,5 +70,5 @@ a.b = b b.a = a del a, b -print "\n\nThis will reveal an uncollectable circular reference (mem leak)" +print("\n\nThis will reveal an uncollectable circular reference (mem leak)") memory_dump() --- examples/notification.py.orig 2020-02-07 16:34:21 UTC +++ examples/notification.py @@ -8,11 +8,11 @@ from application.notification import IObserver, Notifi class Sender(object): def publish(self): center = NotificationCenter() - print "Sending notification with name 'simple':" - print "Expecting CatchAllObserver, SimpleObserver, ObjectObserver and VolatileAllObserver to receive notifications" + print("Sending notification with name 'simple':") + print("Expecting CatchAllObserver, SimpleObserver, ObjectObserver and VolatileAllObserver to receive notifications") center.post_notification(name='simple', sender=self) - print "\nSending notification with name 'complex':" - print "Expecting CatchAllObserver, ObjectObserver and VolatileAllObserver to receive notifications" + print("\nSending notification with name 'complex':") + print("Expecting CatchAllObserver, ObjectObserver and VolatileAllObserver to receive notifications") center.post_notification(name='complex', sender=self, data=NotificationData(timestamp=time(), complex_attribute='complex_value')) def __repr__(self): @@ -22,11 +22,11 @@ class Sender(object): class AnonymousSender(Sender): def publish(self): center = NotificationCenter() - print "Sending notification with name 'simple':" - print "Expecting SimpleObserver to receive notifications (CatchAllObserver and VolatileAllObserver have been unregistered)" + print("Sending notification with name 'simple':") + print("Expecting SimpleObserver to receive notifications (CatchAllObserver and VolatileAllObserver have been unregistered)") center.post_notification(name='simple') - print "\nSending notification with name 'empty':" - print "Expecting no observer to receive notifications (CatchAllObserver and VolatileAllObserver have been unregistered)" + print("\nSending notification with name 'empty':") + print("Expecting no observer to receive notifications (CatchAllObserver and VolatileAllObserver have been unregistered)") center.post_notification(name='empty', data=None) @@ -35,15 +35,15 @@ class CatchAllObserver(object): implements(IObserver) def register(self): - print "Registering CatchAllObserver to receive all notifications" + print("Registering CatchAllObserver to receive all notifications") NotificationCenter().add_observer(self) def unregister(self): - print "Unregistering CatchAllObserver from receiving all notifications" + print("Unregistering CatchAllObserver from receiving all notifications") NotificationCenter().remove_observer(self) def handle_notification(self, notification): - print "In CatchAllObserver got %r" % (notification,) + print("In CatchAllObserver got %r" % (notification,)) class SimpleObserver(object): @@ -51,15 +51,15 @@ class SimpleObserver(object): implements(IObserver) def register(self): - print "Registering SimpleObserver to receive notifications with name 'simple' from any sender" + print("Registering SimpleObserver to receive notifications with name 'simple' from any sender") NotificationCenter().add_observer(self, name='simple') def unregister(self): - print "Unregistering SimpleObserver from receiving notifications with name 'simple' from any sender" + print("Unregistering SimpleObserver from receiving notifications with name 'simple' from any sender") NotificationCenter().remove_observer(self, name='simple') def handle_notification(self, notification): - print "In SimpleObserver got %r" % (notification,) + print("In SimpleObserver got %r" % (notification,)) class ObjectObserver(object): @@ -70,15 +70,15 @@ class ObjectObserver(object): self.sender = sender def register(self): - print "Registering ObjectObserver to receive notifications with any name from sender %r" % (self.sender,) + print("Registering ObjectObserver to receive notifications with any name from sender %r" % (self.sender,)) NotificationCenter().add_observer(self, sender=self.sender) def unregister(self): - print "Unregistering ObjectObserver from receiving notifications with any name from sender %r" % (self.sender,) + print("Unregistering ObjectObserver from receiving notifications with any name from sender %r" % (self.sender,)) NotificationCenter().remove_observer(self, sender=self.sender) def handle_notification(self, notification): - print "In ObjectObserver got %r" % (notification,) + print("In ObjectObserver got %r" % (notification,)) class VolatileAllObserver(object): @@ -86,11 +86,11 @@ class VolatileAllObserver(object): implements(IObserver) def __init__(self): - print "Registering VolatileAllObserver to receive all notifications" + print("Registering VolatileAllObserver to receive all notifications") NotificationCenter().add_observer(ObserverWeakrefProxy(self)) def handle_notification(self, notification): - print "In VolatileAllObserver got %r" % (notification,) + print("In VolatileAllObserver got %r" % (notification,)) # instantiate senders @@ -98,7 +98,7 @@ sender = Sender() anonymous = AnonymousSender() # instantiate the observers and register them -print "Creating and registering observers:" +print("Creating and registering observers:") catchall_observer = CatchAllObserver() catchall_observer.register() simple_observer = SimpleObserver() @@ -108,15 +108,15 @@ object_observer.register() volatile_observer = VolatileAllObserver() # send notifications -print "\nSending notifications from Sender:" -print "----------------------------------" +print("\nSending notifications from Sender:") +print("----------------------------------") sender.publish() -print "\nUnregistering some observers:" +print("\nUnregistering some observers:") catchall_observer.unregister() -print "Deleting VolatileAllObserver which will automatically unregister it from receiving all notifications" +print("Deleting VolatileAllObserver which will automatically unregister it from receiving all notifications") del volatile_observer -print "\nSending notifications from AnonymousSender:" -print "-------------------------------------------" +print("\nSending notifications from AnonymousSender:") +print("-------------------------------------------") anonymous.publish() --- examples/singleton.py.orig 2020-02-07 16:34:14 UTC +++ examples/singleton.py @@ -3,14 +3,12 @@ from application.python.types import Singleton -class Unique(object): +class Unique(object, metaclass=Singleton): """This class has only one instance""" - __metaclass__ = Singleton -class CustomUnique(object): +class CustomUnique(object, metaclass=Singleton): """This class has one instance per __init__ arguments combination""" - __metaclass__ = Singleton def __init__(self, name='default', value=1): self.name = name @@ -20,7 +18,7 @@ class CustomUnique(object): o1 = Unique() o2 = Unique() -print "o1 is o2 (expect True):", o1 is o2 +print("o1 is o2 (expect True):", o1 is o2) co1 = CustomUnique() co2 = CustomUnique() @@ -29,8 +27,8 @@ co4 = CustomUnique(name='my name') co5 = CustomUnique(name='my name', value=2) co6 = CustomUnique(name='my other name') -print "co1 is co2 (expect True):", co1 is co2 -print "co3 is co4 (expect True):", co3 is co4 -print "co1 is co3 (expect False):", co1 is co3 -print "co4 is co5 (expect False):", co4 is co5 -print "co4 is co6 (expect False):", co4 is co6 +print("co1 is co2 (expect True):", co1 is co2) +print("co3 is co4 (expect True):", co3 is co4) +print("co1 is co3 (expect False):", co1 is co3) +print("co4 is co5 (expect False):", co4 is co5) +print("co4 is co6 (expect False):", co4 is co6)