Skip to content

Commit d3b52f5

Browse files
committed
OWFeatureConstructor: PyLint
1 parent b93909a commit d3b52f5

File tree

1 file changed

+28
-20
lines changed

1 file changed

+28
-20
lines changed

Orange/widgets/data/owfeatureconstructor.py

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
QHBoxLayout, QVBoxLayout, QStackedWidget, QStyledItemDelegate,
2929
QPushButton, QMenu, QListView, QFrame
3030
)
31-
from AnyQt.QtGui import QIcon, QKeySequence
31+
from AnyQt.QtGui import QKeySequence
3232
from AnyQt.QtCore import Qt, pyqtSignal as Signal, pyqtProperty as Property
3333

3434
import Orange
@@ -160,7 +160,7 @@ def __init__(self, *args, **kwargs):
160160
self._modified = False
161161

162162
def setModified(self, modified):
163-
if not type(modified) is bool:
163+
if not isinstance(modified, bool):
164164
raise TypeError
165165

166166
if self._modified != modified:
@@ -280,14 +280,12 @@ def editorData(self):
280280
@functools.lru_cache(20)
281281
def variable_icon(dtype):
282282
vtype = _VarMap.get(dtype, dtype)
283-
try:
284-
return gui.attributeIconDict[vtype]
285-
except Exception:
286-
return QIcon()
283+
return gui.attributeIconDict[vtype]
287284

288285

289286
class FeatureItemDelegate(QStyledItemDelegate):
290-
def displayText(self, value, locale):
287+
@staticmethod
288+
def displayText(value, _):
291289
return value.name + " := " + value.expression
292290

293291

@@ -303,18 +301,20 @@ def data(self, index, role=Qt.DisplayRole):
303301
class FeatureConstructorHandler(DomainContextHandler):
304302
"""Context handler that filters descriptors"""
305303

306-
def is_valid_item(self, setting, descriptor, attrs, metas):
307-
"""Check if descriptor can be used with given domain.
304+
def is_valid_item(self, setting, item, attrs, metas):
305+
"""Check if descriptor `item` can be used with given domain.
308306
309307
Return True if descriptor's expression contains only
310308
available variables and descriptors name does not clash with
311309
existing variables.
312310
"""
313-
if descriptor.name in attrs or descriptor.name in metas:
311+
if item.name in attrs or item.name in metas:
314312
return False
315313

316314
try:
317-
exp_ast = ast.parse(descriptor.expression, mode="eval")
315+
exp_ast = ast.parse(item.expression, mode="eval")
316+
# ast.parse can return arbitrary errors, not only SyntaxError
317+
# pylint: disable=broad-except
318318
except Exception:
319319
return False
320320

@@ -550,9 +550,9 @@ def removeFeature(self, index):
550550
index = selected_row(self.featureview)
551551
if index is not None:
552552
self.setCurrentIndex(index)
553-
elif index is None and len(self.featuremodel) > 0:
553+
elif index is None and self.featuremodel.rowCount():
554554
# Deleting the last item clears selection
555-
self.setCurrentIndex(len(self.featuremodel) - 1)
555+
self.setCurrentIndex(self.featuremodel.rowCount() - 1)
556556

557557
def removeSelectedFeature(self):
558558
if self.currentIndex >= 0:
@@ -562,7 +562,8 @@ def duplicateFeature(self):
562562
desc = self.featuremodel[self.currentIndex]
563563
self.addFeature(copy.deepcopy(desc))
564564

565-
def check_attrs_values(self, attr, data):
565+
@staticmethod
566+
def check_attrs_values(attr, data):
566567
for i in range(len(data)):
567568
for var in attr:
568569
if not math.isnan(data[i, var]) \
@@ -575,6 +576,8 @@ def _validate_descriptors(self, desc):
575576
def validate(source):
576577
try:
577578
return validate_exp(ast.parse(source, mode="eval"))
579+
# ast.parse can return arbitrary errors, not only SyntaxError
580+
# pylint: disable=broad-except
578581
except Exception:
579582
return False
580583

@@ -613,6 +616,8 @@ def apply(self):
613616

614617
try:
615618
data = self.data.transform(new_domain)
619+
# user's expression can contain arbitrary errors
620+
# pylint: disable=broad-except
616621
except Exception as err:
617622
log = logging.getLogger(__name__)
618623
log.error("", exc_info=True)
@@ -661,6 +666,7 @@ def freevars(exp, env):
661666
ast
662667
663668
"""
669+
# pylint: disable=too-many-return-statements,too-many-branches
664670
etype = type(exp)
665671
if etype in [ast.Expr, ast.Expression]:
666672
return freevars(exp.body, env)
@@ -765,6 +771,7 @@ def validate_exp(exp):
765771
A parsed abstract syntax tree
766772
767773
"""
774+
# pylint: disable=too-many-branches
768775
if not isinstance(exp, ast.AST):
769776
raise TypeError("exp is not a 'ast.AST' instance")
770777

@@ -859,7 +866,7 @@ def bind_variable(descriptor, env):
859866
return descriptor, FeatureFunc(descriptor.expression, source_vars, values)
860867

861868

862-
def make_lambda(expression, args, env={}):
869+
def make_lambda(expression, args, env=None):
863870
# type: (ast.Expression, List[str], Dict[str, Any]) -> types.FunctionType
864871
"""
865872
Create an lambda function from a expression AST.
@@ -870,7 +877,7 @@ def make_lambda(expression, args, env={}):
870877
The body of the lambda.
871878
args : List[str]
872879
A list of positional argument names
873-
env : Dict[str, Any]
880+
env : Optional[Dict[str, Any]]
874881
Extra environment to capture in the lambda's closure.
875882
876883
Returns
@@ -894,7 +901,7 @@ def make_lambda(expression, args, env={}):
894901
# lambda **{env}** : lambda *{args}*: EXPRESSION
895902
outer = ast.Lambda(
896903
args=ast.arguments(
897-
args=[ast.arg(arg=name, annotation=None) for name in env],
904+
args=[ast.arg(arg=name, annotation=None) for name in (env or {})],
898905
varargs=None,
899906
varargannotation=None,
900907
kwonlyargs=[],
@@ -909,6 +916,7 @@ def make_lambda(expression, args, env={}):
909916
ast.fix_missing_locations(exp)
910917
GLOBALS = __GLOBALS.copy()
911918
GLOBALS["__builtins__"] = {}
919+
# pylint: disable=eval-used
912920
fouter = eval(compile(exp, "<lambda>", "eval"), GLOBALS)
913921
assert isinstance(fouter, types.FunctionType)
914922
finner = fouter(**env)
@@ -980,14 +988,14 @@ class FeatureFunc:
980988
a variable as used in `expression`, and `variable` is the variable
981989
instance used to extract the corresponding column/value from a
982990
Table/Instance.
983-
extra_env : Dict[str, Any]
991+
extra_env : Optional[Dict[str, Any]]
984992
Extra environment specifying constant values to be made available
985993
in expression. It must not shadow names in `args`
986994
"""
987-
def __init__(self, expression, args, extra_env={}):
995+
def __init__(self, expression, args, extra_env=None):
988996
self.expression = expression
989997
self.args = args
990-
self.extra_env = dict(extra_env)
998+
self.extra_env = dict(extra_env or {})
991999
self.func = make_lambda(ast.parse(expression, mode="eval"),
9921000
[name for name, _ in args], self.extra_env)
9931001

0 commit comments

Comments
 (0)