mirror of
https://github.com/codex-storage/deluge.git
synced 2025-01-12 04:24:27 +00:00
d642fa3989
Some new flake8 checkers were added so fix these new warnings and any issues uncovered. Use add-trailing-comma to fix missing trailing commas. It does not format it as well as I would like however it was fast to change and helps with git changes in future. Removed pylint from tox due to large number of warnings.
140 lines
4.6 KiB
Python
140 lines
4.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
#
|
|
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
|
|
#
|
|
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
|
|
# the additional special exception to link portions of this program with the OpenSSL library.
|
|
# See LICENSE for more details.
|
|
#
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
import inspect
|
|
import re
|
|
import warnings
|
|
from functools import wraps
|
|
|
|
|
|
def proxy(proxy_func):
|
|
"""
|
|
Factory class which returns a decorator that passes
|
|
the decorated function to a proxy function
|
|
|
|
:param proxy_func: the proxy function
|
|
:type proxy_func: function
|
|
"""
|
|
def decorator(func):
|
|
@wraps(func)
|
|
def wrapper(*args, **kwargs):
|
|
return proxy_func(func, *args, **kwargs)
|
|
return wrapper
|
|
return decorator
|
|
|
|
|
|
def overrides(*args):
|
|
"""
|
|
Decorater function to specify when class methods override
|
|
super class methods.
|
|
|
|
When used as
|
|
@overrides
|
|
def funcname
|
|
|
|
the argument will be the funcname function.
|
|
|
|
When used as
|
|
@overrides(BaseClass)
|
|
def funcname
|
|
|
|
the argument will be the BaseClass
|
|
|
|
"""
|
|
stack = inspect.stack()
|
|
if inspect.isfunction(args[0]):
|
|
return _overrides(stack, args[0])
|
|
else:
|
|
# One or more classes are specifed, so return a function that will be
|
|
# called with the real function as argument
|
|
def ret_func(func, **kwargs):
|
|
return _overrides(stack, func, explicit_base_classes=args)
|
|
return ret_func
|
|
|
|
|
|
def _overrides(stack, method, explicit_base_classes=None):
|
|
# stack[0]=overrides, stack[1]=inside class def'n, stack[2]=outside class def'n
|
|
classes = {}
|
|
derived_class_locals = stack[2][0].f_locals
|
|
|
|
# Find all super classes
|
|
m = re.search(r'class\s(.+)\((.+)\)\s*\:', stack[2][4][0])
|
|
class_name = m.group(1)
|
|
base_classes = m.group(2)
|
|
|
|
# Handle multiple inheritance
|
|
base_classes = [s.strip() for s in base_classes.split(',')]
|
|
check_classes = base_classes
|
|
|
|
if not base_classes:
|
|
raise ValueError('overrides decorator: unable to determine base class of class "%s"' % class_name)
|
|
|
|
def get_class(cls_name):
|
|
if '.' not in cls_name:
|
|
return derived_class_locals[cls_name]
|
|
else:
|
|
components = cls_name.split('.')
|
|
# obj is either a module or a class
|
|
obj = derived_class_locals[components[0]]
|
|
for c in components[1:]:
|
|
assert inspect.ismodule(obj) or inspect.isclass(obj)
|
|
obj = getattr(obj, c)
|
|
return obj
|
|
|
|
if explicit_base_classes:
|
|
# One or more base classes are explicitly given, check only those classes
|
|
override_classes = re.search(r'\s*@overrides\((.+)\)\s*', stack[1][4][0]).group(1)
|
|
override_classes = [c.strip() for c in override_classes.split(',')]
|
|
check_classes = override_classes
|
|
|
|
for c in base_classes + check_classes:
|
|
classes[c] = get_class(c)
|
|
|
|
# Verify that the excplicit override class is one of base classes
|
|
if explicit_base_classes:
|
|
from itertools import product
|
|
for bc, cc in product(base_classes, check_classes):
|
|
if issubclass(classes[bc], classes[cc]):
|
|
break
|
|
else:
|
|
raise Exception('Excplicit override class "%s" is not a super class of: %s'
|
|
% (explicit_base_classes, class_name))
|
|
if not all(hasattr(classes[cls], method.__name__) for cls in check_classes):
|
|
for cls in check_classes:
|
|
if not hasattr(classes[cls], method.__name__):
|
|
raise Exception('Function override "%s" not found in superclass: %s\n%s'
|
|
% (method.__name__, cls, 'File: %s:%s' % (stack[1][1], stack[1][2])))
|
|
|
|
if not any(hasattr(classes[cls], method.__name__) for cls in check_classes):
|
|
raise Exception('Function override "%s" not found in any superclass: %s\n%s'
|
|
% (method.__name__, check_classes, 'File: %s:%s' % (stack[1][1], stack[1][2])))
|
|
return method
|
|
|
|
|
|
def deprecated(func):
|
|
"""This is a decorator which can be used to mark function as deprecated.
|
|
|
|
It will result in a warning being emmitted when the function is used.
|
|
|
|
"""
|
|
|
|
@wraps(func)
|
|
def depr_func(*args, **kwargs):
|
|
warnings.simplefilter('always', DeprecationWarning) # Turn off filter
|
|
warnings.warn(
|
|
'Call to deprecated function {}.'.format(func.__name__),
|
|
category=DeprecationWarning, stacklevel=2,
|
|
)
|
|
warnings.simplefilter('default', DeprecationWarning) # Reset filter
|
|
return func(*args, **kwargs)
|
|
|
|
return depr_func
|