def visit_If(self, node): self.check_type(node.test, Bool()) test_value = static_evaluate(node.test, self.context()) if not isinstance(test_value, UnknownValue): self.warn('constant-if-condition', node) ext_ctx = self.context() if_inferences, else_inferences = maybe_inferences(node.test, ext_ctx) # don't visit unreachable code if test_value is True: self._visit_branch(node.body, if_inferences) return if test_value is False: self._visit_branch(node.orelse, else_inferences) return if_scope = self._visit_branch(node.body, if_inferences) else_scope = self._visit_branch(node.orelse, else_inferences) diffs = set(if_scope.names()) ^ set(else_scope.names()) for diff in diffs: if diff not in self._context: self.warn('conditionally-assigned', node, diff) common = set(if_scope.names()) & set(else_scope.names()) for name in common: types = [if_scope.get_type(name), else_scope.get_type(name)] unified_type = unify_types(types) self._context.add(Symbol(name, unified_type)) if isinstance(unified_type, Unknown): if not any(isinstance(x, Unknown) for x in types): self.warn('conditional-type', node, name)
def evaluate(self, node): return static_evaluate(node, self.context())