2828 QHBoxLayout , QVBoxLayout , QStackedWidget , QStyledItemDelegate ,
2929 QPushButton , QMenu , QListView , QFrame
3030)
31- from AnyQt .QtGui import QIcon , QKeySequence
31+ from AnyQt .QtGui import QKeySequence
3232from AnyQt .QtCore import Qt , pyqtSignal as Signal , pyqtProperty as Property
3333
3434import 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 )
281281def 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
289286class 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):
303301class 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