diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2015-08-26 22:09:27 +0300 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2015-08-26 22:09:27 +0300 |
commit | 596acc38bc6187dd7c3e05dffa0164f7d9b87dc8 (patch) | |
tree | 88256ac8aa8c38a3b6a36d2da9e3b9b154ffb3fe | |
parent | 90755257e2a2c1a9b45b1a7e5470eef760fe6a90 (diff) | |
download | pylint-596acc38bc6187dd7c3e05dffa0164f7d9b87dc8.tar.gz |
Use the new node names for the visit and leave methods
Also, emit a PendingDeprecationWarning if the old names are still
used, this support being removed in pylint 2.0.
25 files changed, 182 insertions, 141 deletions
diff --git a/pylint/checkers/base.py b/pylint/checkers/base.py index f365dab..0c3f67a 100644 --- a/pylint/checkers/base.py +++ b/pylint/checkers/base.py @@ -332,7 +332,7 @@ class BasicErrorChecker(_BasicChecker): } @check_messages('function-redefined') - def visit_class(self, node): + def visit_classdef(self, node): self._check_redefinition('class', node) @check_messages('too-many-star-expressions', @@ -359,7 +359,7 @@ class BasicErrorChecker(_BasicChecker): @check_messages('init-is-generator', 'return-in-init', 'function-redefined', 'return-arg-in-generator', 'duplicate-argument-name', 'nonlocal-and-global') - def visit_function(self, node): + def visit_functiondef(self, node): self._check_nonlocal_and_global(node) if not redefined_by_decorator(node): self._check_redefinition(node.is_method() and 'method' or 'function', node) @@ -449,7 +449,7 @@ class BasicErrorChecker(_BasicChecker): self.add_message('nonexistent-operator', node=node, args=node.op*2) @check_messages('abstract-class-instantiated') - def visit_callfunc(self, node): + def visit_call(self, node): """ Check instantiating abstract class with abc.ABCMeta as metaclass. """ @@ -684,7 +684,7 @@ functions, methods """ self.stats['module'] += 1 - def visit_class(self, node): # pylint: disable=unused-argument + def visit_classdef(self, node): # pylint: disable=unused-argument """check module name, docstring and redefinition increment branch counter """ @@ -793,7 +793,7 @@ functions, methods self.add_message('unnecessary-lambda', line=node.fromlineno, node=node) @check_messages('dangerous-default-value') - def visit_function(self, node): + def visit_functiondef(self, node): """check function name, docstring, arguments, redefinition, variable names, max locals """ @@ -882,7 +882,7 @@ functions, methods @check_messages('bad-builtin', 'eval-used', 'exec-used', 'bad-reversed-sequence') - def visit_callfunc(self, node): + def visit_call(self, node): """visit a CallFunc node -> check if this is not a blacklisted builtin call and check for * or ** use """ @@ -1145,14 +1145,14 @@ class NameChecker(_BasicChecker): self._raise_name_warning(*args) @check_messages('blacklisted-name', 'invalid-name') - def visit_class(self, node): + def visit_classdef(self, node): self._check_name('class', node.name, node) for attr, anodes in six.iteritems(node.instance_attrs): if not list(node.instance_attr_ancestors(attr)): self._check_name('attr', attr, anodes[0]) @check_messages('blacklisted-name', 'invalid-name') - def visit_function(self, node): + def visit_functiondef(self, node): # Do not emit any warnings if the method is just an implementation # of a base class method. confidence = HIGH @@ -1175,7 +1175,7 @@ class NameChecker(_BasicChecker): self._check_name('const', name, node) @check_messages('blacklisted-name', 'invalid-name') - def visit_assname(self, node): + def visit_assignname(self, node): """check module level assigned names""" frame = node.frame() ass_type = node.assign_type() @@ -1284,12 +1284,12 @@ class DocStringChecker(_BasicChecker): self._check_docstring('module', node) @check_messages('missing-docstring', 'empty-docstring') - def visit_class(self, node): + def visit_classdef(self, node): if self.config.no_docstring_rgx.match(node.name) is None: self._check_docstring('class', node) @check_messages('missing-docstring', 'empty-docstring') - def visit_function(self, node): + def visit_functiondef(self, node): if self.config.no_docstring_rgx.match(node.name) is None: ftype = node.is_method() and 'method' or 'function' if isinstance(node.parent.frame(), astroid.ClassDef): @@ -1377,7 +1377,7 @@ class LambdaForComprehensionChecker(_BasicChecker): } @check_messages('deprecated-lambda') - def visit_callfunc(self, node): + def visit_call(self, node): """visit a CallFunc node, check if map or filter are called with a lambda """ diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py index e573153..71041ea 100644 --- a/pylint/checkers/classes.py +++ b/pylint/checkers/classes.py @@ -300,7 +300,7 @@ a metaclass class method.'} self._first_attrs = [] self._meth_could_be_func = None - def visit_class(self, node): + def visit_classdef(self, node): """init visit variable _accessed """ self._accessed.append(defaultdict(list)) @@ -349,7 +349,7 @@ a metaclass class method.'} @check_messages('access-member-before-definition', 'attribute-defined-outside-init') - def leave_class(self, cnode): + def leave_classdef(self, cnode): """close a class node: check that instance attributes are defined in __init__ and check access to existent members @@ -410,7 +410,7 @@ a metaclass class method.'} self.add_message('attribute-defined-outside-init', args=attr, node=node) - def visit_function(self, node): + def visit_functiondef(self, node): """check method arguments, overriding""" # ignore actual functions if not node.is_method(): @@ -510,7 +510,7 @@ a metaclass class method.'} args=infered.as_string(), node=elt) - def leave_function(self, node): + def leave_functiondef(self, node): """on method node, check if this method couldn't be a function ignore class, static and abstract methods, initializer, @@ -529,7 +529,7 @@ a metaclass class method.'} decorated_with_property(node))): self.add_message('no-self-use', node=node) - def visit_getattr(self, node): + def visit_attribute(self, node): """check if the getattr is an access to a class member if so, register it. Also check for access to protected class member from outside its class (but ignore __special__ @@ -545,7 +545,7 @@ a metaclass class method.'} self._check_protected_attribute_access(node) - def visit_assattr(self, node): + def visit_assignattr(self, node): if isinstance(node.assign_type(), astroid.AugAssign) and self.is_first_attr(node): self._accessed[-1][node.attrname].append(node) self._check_in_slots(node) @@ -921,7 +921,7 @@ class SpecialMethodsChecker(BaseChecker): @check_messages('unexpected-special-method-signature', 'non-iterator-returned') - def visit_function(self, node): + def visit_functiondef(self, node): if not node.is_method(): return if node.name == '__iter__': diff --git a/pylint/checkers/design_analysis.py b/pylint/checkers/design_analysis.py index 99d5b32..432c96a 100644 --- a/pylint/checkers/design_analysis.py +++ b/pylint/checkers/design_analysis.py @@ -153,7 +153,7 @@ class MisdesignChecker(BaseChecker): @check_messages('too-many-ancestors', 'too-many-instance-attributes', 'too-few-public-methods', 'too-many-public-methods') - def visit_class(self, node): + def visit_classdef(self, node): """check size of inheritance hierarchy and number of instance attributes """ # Is the total inheritance hierarchy is 7 or less? @@ -170,7 +170,7 @@ class MisdesignChecker(BaseChecker): self.config.max_attributes)) @check_messages('too-few-public-methods', 'too-many-public-methods') - def leave_class(self, node): + def leave_classdef(self, node): """check number of public methods""" my_methods = sum(1 for method in node.mymethods() if not method.name.startswith('_')) @@ -203,7 +203,7 @@ class MisdesignChecker(BaseChecker): @check_messages('too-many-return-statements', 'too-many-branches', 'too-many-arguments', 'too-many-locals', 'too-many-statements') - def visit_function(self, node): + def visit_functiondef(self, node): """check function name, docstring, arguments, redefinition, variable names, max locals """ @@ -232,7 +232,7 @@ class MisdesignChecker(BaseChecker): @check_messages('too-many-return-statements', 'too-many-branches', 'too-many-arguments', 'too-many-locals', 'too-many-statements') - def leave_function(self, node): + def leave_functiondef(self, node): """most of the work is done here on close: checks for max returns, branch, return in __init__ """ diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py index a70f7ce..c1688df 100644 --- a/pylint/checkers/imports.py +++ b/pylint/checkers/imports.py @@ -267,7 +267,7 @@ given file (report RP0402 must not be disabled)'} # TODO This appears to be the list of all messages of the checker... # @check_messages('W0410', 'W0401', 'W0403', 'W0402', 'W0404', 'W0406', 'E0401') @check_messages(*(MSGS.keys())) - def visit_from(self, node): + def visit_importfrom(self, node): """triggered when a from statement is seen""" basename = node.modname if basename == '__future__': diff --git a/pylint/checkers/logging.py b/pylint/checkers/logging.py index ddfdc29..9ef85dd 100644 --- a/pylint/checkers/logging.py +++ b/pylint/checkers/logging.py @@ -119,7 +119,7 @@ class LoggingChecker(checkers.BaseChecker): if len(parts) > 1: self._from_imports[parts[0]] = parts[1] - def visit_from(self, node): + def visit_importfrom(self, node): """Checks to see if a module uses a non-Python logging module.""" try: logging_name = self._from_imports[node.modname] @@ -136,7 +136,7 @@ class LoggingChecker(checkers.BaseChecker): self._logging_names.add(as_name or module) @check_messages(*(MSGS.keys())) - def visit_callfunc(self, node): + def visit_call(self, node): """Checks calls to logging methods.""" def is_logging_name(): return (isinstance(node.func, astroid.Attribute) and diff --git a/pylint/checkers/newstyle.py b/pylint/checkers/newstyle.py index 5e88a32..ee45f45 100644 --- a/pylint/checkers/newstyle.py +++ b/pylint/checkers/newstyle.py @@ -77,7 +77,7 @@ class NewStyleConflictChecker(BaseChecker): options = () @check_messages('slots-on-old-class', 'old-style-class') - def visit_class(self, node): + def visit_classdef(self, node): """ Check __slots__ in old style classes and old style class definition. """ @@ -95,7 +95,7 @@ class NewStyleConflictChecker(BaseChecker): self.add_message('old-style-class', node=node, confidence=HIGH) @check_messages('property-on-old-class') - def visit_callfunc(self, node): + def visit_call(self, node): """check property usage""" parent = node.parent.frame() if (isinstance(parent, astroid.ClassDef) and @@ -109,7 +109,7 @@ class NewStyleConflictChecker(BaseChecker): confidence=confidence) @check_messages('super-on-old-class', 'bad-super-call', 'missing-super-argument') - def visit_function(self, node): + def visit_functiondef(self, node): """check use of super""" # ignore actual functions or method within a new style class if not node.is_method(): diff --git a/pylint/checkers/python3.py b/pylint/checkers/python3.py index ead2f03..c640982 100644 --- a/pylint/checkers/python3.py +++ b/pylint/checkers/python3.py @@ -385,7 +385,7 @@ class Python3Checker(checkers.BaseChecker): self._future_division = False self._future_absolute_import = False - def visit_function(self, node): + def visit_functiondef(self, node): if node.is_method() and node.name in self._unused_magic_methods: method_name = node.name if node.name.startswith('__'): @@ -411,7 +411,7 @@ class Python3Checker(checkers.BaseChecker): self.add_message('print-statement', node=node) @utils.check_messages('no-absolute-import', 'import-star-module-level') - def visit_from(self, node): + def visit_importfrom(self, node): if node.modname == '__future__': for name, _ in node.names: if name == 'division': @@ -430,7 +430,7 @@ class Python3Checker(checkers.BaseChecker): self.add_message('no-absolute-import', node=node) @utils.check_messages('metaclass-assignment') - def visit_class(self, node): + def visit_classdef(self, node): if '__metaclass__' in node.locals: self.add_message('metaclass-assignment', node=node) @@ -472,7 +472,7 @@ class Python3Checker(checkers.BaseChecker): self.add_message('using-cmp-argument', node=node) return - def visit_callfunc(self, node): + def visit_call(self, node): self._check_cmp_argument(node) if isinstance(node.func, astroid.Attribute): @@ -514,7 +514,7 @@ class Python3Checker(checkers.BaseChecker): self.add_message('unpacking-in-except', node=node) @utils.check_messages('backtick') - def visit_backquote(self, node): + def visit_repr(self, node): self.add_message('backtick', node=node) @utils.check_messages('raising-string', 'old-raise-syntax') diff --git a/pylint/checkers/spelling.py b/pylint/checkers/spelling.py index 3fbec71..a5b7857 100644 --- a/pylint/checkers/spelling.py +++ b/pylint/checkers/spelling.py @@ -226,13 +226,13 @@ class SpellingChecker(BaseTokenChecker): self._check_docstring(node) @check_messages('wrong-spelling-in-docstring') - def visit_class(self, node): + def visit_classdef(self, node): if not self.initialized: return self._check_docstring(node) @check_messages('wrong-spelling-in-docstring') - def visit_function(self, node): + def visit_functiondef(self, node): if not self.initialized: return self._check_docstring(node) diff --git a/pylint/checkers/stdlib.py b/pylint/checkers/stdlib.py index af50a19..0bff8b0 100644 --- a/pylint/checkers/stdlib.py +++ b/pylint/checkers/stdlib.py @@ -121,7 +121,7 @@ class StdlibChecker(BaseChecker): } @utils.check_messages('bad-open-mode', 'redundant-unittest-assert') - def visit_callfunc(self, node): + def visit_call(self, node): """Visit a CallFunc node.""" if hasattr(node, 'func'): infer = helpers.safe_infer(node.func) diff --git a/pylint/checkers/strings.py b/pylint/checkers/strings.py index 90f760c..0bc65b8 100644 --- a/pylint/checkers/strings.py +++ b/pylint/checkers/strings.py @@ -332,7 +332,7 @@ class StringMethodsChecker(BaseChecker): } @check_messages(*(MSGS.keys())) - def visit_callfunc(self, node): + def visit_call(self, node): func = helpers.safe_infer(node.func) if (isinstance(func, astroid.BoundMethod) and isinstance(func.bound, astroid.Instance) diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index dd9e55a..9af8159 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -288,15 +288,15 @@ accessed. Python regular expressions are accepted.'} # do this in open since config not fully initialized in __init__ self.generated_members = list(self.config.generated_members) - def visit_assattr(self, node): + def visit_assignattr(self, node): if isinstance(node.assign_type(), astroid.AugAssign): - self.visit_getattr(node) + self.visit_attribute(node) def visit_delattr(self, node): - self.visit_getattr(node) + self.visit_attribute(node) @check_messages('no-member') - def visit_getattr(self, node): + def visit_attribute(self, node): """check that the accessed attribute exists to avoid too much false positives for now, we'll consider the code as @@ -449,7 +449,7 @@ accessed. Python regular expressions are accepted.'} break @check_messages(*(list(MSGS.keys()))) - def visit_callfunc(self, node): + def visit_call(self, node): """check that called functions/methods are inferred to callable objects, and that the arguments passed to the function match the parameters in the inferred function's definition diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 53559b4..2ce12e8 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -457,12 +457,12 @@ builtins. Remember that you should avoid to define new builtins when possible.' self.add_message('unused-import', args=msg, node=stmt) del self._to_consume - def visit_class(self, node): + def visit_classdef(self, node): """visit class: update consumption analysis variable """ self._to_consume.append((copy(node.locals), {}, 'class')) - def leave_class(self, _): + def leave_classdef(self, _): """leave class: update consumption analysis variable """ # do not check for not used locals here (no sense) @@ -479,12 +479,12 @@ builtins. Remember that you should avoid to define new builtins when possible.' # do not check for not used locals here self._to_consume.pop() - def visit_genexpr(self, node): + def visit_generatorexp(self, node): """visit genexpr: update consumption analysis variable """ self._to_consume.append((copy(node.locals), {}, 'comprehension')) - def leave_genexpr(self, _): + def leave_generatorexp(self, _): """leave genexpr: update consumption analysis variable """ # do not check for not used locals here @@ -512,7 +512,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' # do not check for not used locals here self._to_consume.pop() - def visit_function(self, node): + def visit_functiondef(self, node): """visit function: update consumption analysis variable and check locals """ self._to_consume.append((copy(node.locals), {}, 'function')) @@ -539,7 +539,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' # do not print Redefining builtin for additional builtins self.add_message('redefined-builtin', args=name, node=stmt) - def leave_function(self, node): + def leave_functiondef(self, node): """leave function: check function's locals are consumed""" not_consumed = self._to_consume.pop()[0] if not (self.linter.is_message_enabled('unused-variable') or @@ -736,7 +736,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' if clobbering: self.add_message('redefine-in-handler', args=args, node=name) - def visit_assname(self, node): + def visit_assignname(self, node): if isinstance(node.assign_type(), astroid.AugAssign): self.visit_name(node) @@ -1000,7 +1000,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' self._check_module_attrs(node, module, parts[1:]) @check_messages('no-name-in-module') - def visit_from(self, node): + def visit_importfrom(self, node): """check modules attribute accesses""" if node_ignores_exception(node, ImportError): # No need to verify this, since ImportError is already diff --git a/pylint/extensions/check_docs.py b/pylint/extensions/check_docs.py index 60eb81c..fc014f4 100644 --- a/pylint/extensions/check_docs.py +++ b/pylint/extensions/check_docs.py @@ -69,7 +69,7 @@ class ParamDocChecker(BaseChecker): constructor_names = set(["__init__", "__new__"]) - def visit_function(self, node): + def visit_functiondef(self, node): """Called for function and method definitions (def). :param node: Node for a function or method definition in the AST diff --git a/pylint/test/extensions/test_check_docs.py b/pylint/test/extensions/test_check_docs.py index 07afb3e..3a5455a 100644 --- a/pylint/test/extensions/test_check_docs.py +++ b/pylint/test/extensions/test_check_docs.py @@ -47,7 +47,7 @@ class ParamDocCheckerTest(CheckerTestCase): node=node, args=('x, y',)) ): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_missing_func_params_in_google_docstring(self): """Example of a function with missing Google style parameter @@ -75,7 +75,7 @@ class ParamDocCheckerTest(CheckerTestCase): node=node, args=('x, y',)) ): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_missing_func_params_in_numpy_docstring(self): """Example of a function with missing NumPy style parameter @@ -106,7 +106,7 @@ class ParamDocCheckerTest(CheckerTestCase): node=node, args=('x, y',)) ): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_tolerate_no_param_documentation_at_all(self): """Example of a function with no parameter documentation at all @@ -121,7 +121,7 @@ class ParamDocCheckerTest(CheckerTestCase): pass """) with self.assertNoMessages(): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) @set_config(accept_no_param_doc=False) def test_don_t_tolerate_no_param_documentation_at_all(self): @@ -146,7 +146,7 @@ class ParamDocCheckerTest(CheckerTestCase): node=node, args=('x, y',)) ): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def _visit_methods_of_class(self, node): """Visit all methods of a class node @@ -157,7 +157,7 @@ class ParamDocCheckerTest(CheckerTestCase): for body_item in node.body: if (isinstance(body_item, astroid.FunctionDef) and hasattr(body_item, 'name')): - self.checker.visit_function(body_item) + self.checker.visit_functiondef(body_item) def test_missing_method_params_in_sphinx_docstring(self): """Example of a class method with missing parameter documentation in @@ -269,7 +269,7 @@ class ParamDocCheckerTest(CheckerTestCase): return xarg + yarg """) with self.assertNoMessages(): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_existing_func_params_in_google_docstring(self): """Example of a function with correctly documented parameters and @@ -292,7 +292,7 @@ class ParamDocCheckerTest(CheckerTestCase): return xarg + yarg """) with self.assertNoMessages(): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_existing_func_params_in_numpy_docstring(self): """Example of a function with correctly documented parameters and @@ -320,7 +320,7 @@ class ParamDocCheckerTest(CheckerTestCase): return xarg + yarg """) with self.assertNoMessages(): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_wrong_name_of_func_params_in_sphinx_docstring(self): """Example of functions with inconsistent parameter names in the @@ -350,7 +350,7 @@ class ParamDocCheckerTest(CheckerTestCase): node=node, args=('yarg, yarg1, zarg, zarg1',)), ): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) node = test_utils.extract_node(""" def function_foo(xarg, yarg): @@ -373,7 +373,7 @@ class ParamDocCheckerTest(CheckerTestCase): node=node, args=('yarg1',)) ): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_wrong_name_of_func_params_in_google_docstring(self): """Example of functions with inconsistent parameter names in the @@ -401,7 +401,7 @@ class ParamDocCheckerTest(CheckerTestCase): node=node, args=('xarg, xarg1, zarg, zarg1',)), ): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) node = test_utils.extract_node(""" def function_foo(xarg, yarg): @@ -424,7 +424,7 @@ class ParamDocCheckerTest(CheckerTestCase): node=node, args=('yarg1',)) ): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_wrong_name_of_func_params_in_numpy_docstring(self): """Example of functions with inconsistent parameter names in the @@ -456,7 +456,7 @@ class ParamDocCheckerTest(CheckerTestCase): node=node, args=('xarg, xarg1, zarg, zarg1',)), ): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) node = test_utils.extract_node(""" def function_foo(xarg, yarg): @@ -481,7 +481,7 @@ class ParamDocCheckerTest(CheckerTestCase): node=node, args=('yarg1',)) ): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_see_sentence_for_func_params_in_sphinx_docstring(self): """Example for the usage of "For the other parameters, see" to avoid @@ -500,7 +500,7 @@ class ParamDocCheckerTest(CheckerTestCase): return xarg + yarg """) with self.assertNoMessages(): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_see_sentence_for_func_params_in_google_docstring(self): """Example for the usage of "For the other parameters, see" to avoid @@ -519,7 +519,7 @@ class ParamDocCheckerTest(CheckerTestCase): return xarg + yarg """) with self.assertNoMessages(): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_see_sentence_for_func_params_in_numpy_docstring(self): """Example for the usage of "For the other parameters, see" to avoid @@ -540,7 +540,7 @@ class ParamDocCheckerTest(CheckerTestCase): return xarg + yarg """) with self.assertNoMessages(): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_constr_params_in_class_sphinx(self): """Example of a class with missing constructor parameter documentation diff --git a/pylint/test/unittest_checker_base.py b/pylint/test/unittest_checker_base.py index 0d25d29..f19544f 100644 --- a/pylint/test/unittest_checker_base.py +++ b/pylint/test/unittest_checker_base.py @@ -36,7 +36,7 @@ class DocstringTest(CheckerTestCase): pass""") message = Message('missing-docstring', node=func, args=('function',)) with self.assertAddsMessages(message): - self.checker.visit_function(func) + self.checker.visit_functiondef(func) @set_config(docstring_min_length=2) def test_short_function_no_docstring(self): @@ -44,7 +44,7 @@ class DocstringTest(CheckerTestCase): def func(tion): pass""") with self.assertNoMessages(): - self.checker.visit_function(func) + self.checker.visit_functiondef(func) @set_config(docstring_min_length=2) def test_function_no_docstring_by_name(self): @@ -52,7 +52,7 @@ class DocstringTest(CheckerTestCase): def __fun__(tion): pass""") with self.assertNoMessages(): - self.checker.visit_function(func) + self.checker.visit_functiondef(func) def test_class_no_docstring(self): klass = test_utils.extract_node(""" @@ -60,7 +60,7 @@ class DocstringTest(CheckerTestCase): pass""") message = Message('missing-docstring', node=klass, args=('class',)) with self.assertAddsMessages(message): - self.checker.visit_class(klass) + self.checker.visit_classdef(klass) class NameCheckerTest(CheckerTestCase): @@ -79,7 +79,7 @@ class NameCheckerTest(CheckerTestCase): args=('constant', 'const', ' (hint: (([A-Z_][A-Z0-9_]*)|(__.*__))$)')) with self.assertAddsMessages(message): - self.checker.visit_assname(const.targets[0]) + self.checker.visit_assignname(const.targets[0]) @set_config(include_naming_hint=True, const_name_hint='CONSTANT') def test_naming_hint_configured_hint(self): @@ -89,7 +89,7 @@ class NameCheckerTest(CheckerTestCase): with self.assertAddsMessages( Message('invalid-name', node=const.targets[0], args=('constant', 'const', ' (hint: CONSTANT)'))): - self.checker.visit_assname(const.targets[0]) + self.checker.visit_assignname(const.targets[0]) @set_config(attr_rgx=re.compile('[A-Z]+')) def test_property_names(self): @@ -113,11 +113,11 @@ class NameCheckerTest(CheckerTestCase): pass """) with self.assertNoMessages(): - self.checker.visit_function(methods[0]) - self.checker.visit_function(methods[2]) + self.checker.visit_functiondef(methods[0]) + self.checker.visit_functiondef(methods[2]) with self.assertAddsMessages(Message('invalid-name', node=methods[1], args=('attribute', 'bar', ''))): - self.checker.visit_function(methods[1]) + self.checker.visit_functiondef(methods[1]) @set_config(attr_rgx=re.compile('[A-Z]+')) def test_property_setters(self): @@ -131,7 +131,7 @@ class NameCheckerTest(CheckerTestCase): pass """) with self.assertNoMessages(): - self.checker.visit_function(method) + self.checker.visit_functiondef(method) def test_module_level_names(self): assign = test_utils.extract_node(""" @@ -139,7 +139,7 @@ class NameCheckerTest(CheckerTestCase): Class = collections.namedtuple("a", ("b", "c")) #@ """) with self.assertNoMessages(): - self.checker.visit_assname(assign.targets[0]) + self.checker.visit_assignname(assign.targets[0]) assign = test_utils.extract_node(""" class ClassA(object): @@ -147,7 +147,7 @@ class NameCheckerTest(CheckerTestCase): ClassB = ClassA """) with self.assertNoMessages(): - self.checker.visit_assname(assign.targets[0]) + self.checker.visit_assignname(assign.targets[0]) module = astroid.parse(""" def A(): @@ -155,13 +155,13 @@ class NameCheckerTest(CheckerTestCase): CONSTA, CONSTB, CONSTC = A() CONSTD = A()""") with self.assertNoMessages(): - self.checker.visit_assname(module.body[1].targets[0].elts[0]) - self.checker.visit_assname(module.body[2].targets[0]) + self.checker.visit_assignname(module.body[1].targets[0].elts[0]) + self.checker.visit_assignname(module.body[2].targets[0]) assign = test_utils.extract_node(""" CONST = "12 34 ".rstrip().split()""") with self.assertNoMessages(): - self.checker.visit_assname(assign.targets[0]) + self.checker.visit_assignname(assign.targets[0]) class MultiNamingStyleTest(CheckerTestCase): @@ -184,7 +184,7 @@ class MultiNamingStyleTest(CheckerTestCase): args=('class', 'classb', '')) with self.assertAddsMessages(message): for cls in classes: - self.checker.visit_class(cls) + self.checker.visit_classdef(cls) self.checker.leave_module(cls.root) @set_config(class_rgx=MULTI_STYLE_RE) @@ -205,7 +205,7 @@ class MultiNamingStyleTest(CheckerTestCase): ] with self.assertAddsMessages(*messages): for cls in classes: - self.checker.visit_class(cls) + self.checker.visit_classdef(cls) self.checker.leave_module(cls.root) @set_config(method_rgx=MULTI_STYLE_RE, @@ -224,7 +224,7 @@ class MultiNamingStyleTest(CheckerTestCase): args=('function', 'FUNC', '')) with self.assertAddsMessages(message): for func in function_defs: - self.checker.visit_function(func) + self.checker.visit_functiondef(func) self.checker.leave_module(func.root) @set_config(function_rgx=re.compile('(?:(?P<ignore>FOO)|(?P<UP>[A-Z]+)|(?P<down>[a-z]+))$')) @@ -243,7 +243,7 @@ class MultiNamingStyleTest(CheckerTestCase): args=('function', 'UPPER', '')) with self.assertAddsMessages(message): for func in function_defs: - self.checker.visit_function(func) + self.checker.visit_functiondef(func) self.checker.leave_module(func.root) diff --git a/pylint/test/unittest_checker_classes.py b/pylint/test/unittest_checker_classes.py index 9f80cc9..ae1b919 100644 --- a/pylint/test/unittest_checker_classes.py +++ b/pylint/test/unittest_checker_classes.py @@ -61,7 +61,7 @@ class VariablesCheckerTC(CheckerTestCase): Sequence.__init__(self) """) with self.assertNoMessages(): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_super_init_not_called_regression(self): # This should not emit a super-init-not-called @@ -77,7 +77,7 @@ class VariablesCheckerTC(CheckerTestCase): ctypes.BigEndianStructure.__init__(self) """) with self.assertNoMessages(): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) if __name__ == '__main__': diff --git a/pylint/test/unittest_checker_imports.py b/pylint/test/unittest_checker_imports.py index 143d17c..be0bc48 100644 --- a/pylint/test/unittest_checker_imports.py +++ b/pylint/test/unittest_checker_imports.py @@ -18,13 +18,13 @@ class ImportsCheckerTC(CheckerTestCase): from external_module import anything """) with self.assertNoMessages(): - self.checker.visit_from(node) + self.checker.visit_importfrom(node) node = test_utils.extract_node(""" from external_module.another_module import anything """) with self.assertNoMessages(): - self.checker.visit_from(node) + self.checker.visit_importfrom(node) node = test_utils.extract_node(""" import external_module @@ -36,13 +36,13 @@ class ImportsCheckerTC(CheckerTestCase): from fake_module.submodule import anything """) with self.assertNoMessages(): - self.checker.visit_from(node) + self.checker.visit_importfrom(node) node = test_utils.extract_node(""" from fake_module.submodule.deeper import anything """) with self.assertNoMessages(): - self.checker.visit_from(node) + self.checker.visit_importfrom(node) if __name__ == '__main__': unittest.main() diff --git a/pylint/test/unittest_checker_logging.py b/pylint/test/unittest_checker_logging.py index e25daac..0f19a31 100644 --- a/pylint/test/unittest_checker_logging.py +++ b/pylint/test/unittest_checker_logging.py @@ -19,7 +19,7 @@ class LoggingModuleDetectionTest(CheckerTestCase): self.checker.visit_module(None) self.checker.visit_import(stmts[0]) with self.assertAddsMessages(Message('logging-not-lazy', node=stmts[1])): - self.checker.visit_callfunc(stmts[1]) + self.checker.visit_call(stmts[1]) def test_detects_renamed_standard_logging_module(self): stmts = test_utils.extract_node(""" @@ -29,7 +29,7 @@ class LoggingModuleDetectionTest(CheckerTestCase): self.checker.visit_module(None) self.checker.visit_import(stmts[0]) with self.assertAddsMessages(Message('logging-not-lazy', node=stmts[1])): - self.checker.visit_callfunc(stmts[1]) + self.checker.visit_call(stmts[1]) @set_config(logging_modules=['logging', 'my.logging']) def test_nonstandard_logging_module(self): @@ -40,7 +40,7 @@ class LoggingModuleDetectionTest(CheckerTestCase): self.checker.visit_module(None) self.checker.visit_import(stmts[0]) with self.assertAddsMessages(Message('logging-not-lazy', node=stmts[1])): - self.checker.visit_callfunc(stmts[1]) + self.checker.visit_call(stmts[1]) if __name__ == '__main__': diff --git a/pylint/test/unittest_checker_python3.py b/pylint/test/unittest_checker_python3.py index 1bdea1d..7f3b182 100644 --- a/pylint/test/unittest_checker_python3.py +++ b/pylint/test/unittest_checker_python3.py @@ -80,7 +80,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): """.format(fxn)) message = testutils.Message(checker, node=node) with self.assertAddsMessages(message): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def as_iterable_in_genexp_test(self, fxn): code = "x = (x for x in {}())".format(fxn) @@ -104,7 +104,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): """.format(fxn)) message = testutils.Message(checker, node=node) with self.assertAddsMessages(message): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def as_used_in_variant_in_listcomp_test(self, fxn): checker = '{}-builtin-not-iterating'.format(fxn) @@ -115,7 +115,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): """.format(fxn)) message = testutils.Message(checker, node=node) with self.assertAddsMessages(message): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def as_argument_to_callable_constructor_test(self, fxn, callable_fn): module = astroid.parse("x = {}({}())".format(callable_fn, fxn)) @@ -131,7 +131,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): """.format(fxn)) message = testutils.Message(checker, node=node) with self.assertAddsMessages(message): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def as_argument_to_str_join_test(self, fxn): code = "x = ''.join({}())".format(fxn) @@ -144,7 +144,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): a, b = __({}()) """.format(fxn)) with self.assertNoMessages(): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def as_assignment(self, fxn): checker = '{}-builtin-not-iterating'.format(fxn) @@ -153,7 +153,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): """.format(fxn)) message = testutils.Message(checker, node=node) with self.assertAddsMessages(message): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def iterating_context_tests(self, fxn): """Helper for verifying a function isn't used as an iterator.""" @@ -197,7 +197,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): pass""".format(method)) message = testutils.Message(warning, node=node) with self.assertAddsMessages(message): - self.checker.visit_function(node) + self.checker.visit_functiondef(node) def test_delslice_method(self): self.defined_method_test('delslice', 'delslice-method') @@ -235,7 +235,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): node = test_utils.extract_node('`test`') message = testutils.Message('backtick', node=node) with self.assertAddsMessages(message): - self.checker.visit_backquote(node) + self.checker.visit_repr(node) def test_relative_import(self): node = test_utils.extract_node('import string #@') @@ -266,7 +266,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): absolute = testutils.Message('no-absolute-import', node=node) star = testutils.Message('import-star-module-level', node=node) with self.assertAddsMessages(absolute, star): - self.checker.visit_from(node) + self.checker.visit_importfrom(node) def test_division(self): node = test_utils.extract_node('3 / 2 #@') @@ -296,13 +296,13 @@ class Python3CheckerTest(testutils.CheckerTestCase): node = test_utils.extract_node('x.iter%s() #@' % meth) message = testutils.Message('dict-iter-method', node=node) with self.assertAddsMessages(message): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def test_dict_iter_method_on_dict(self): node = test_utils.extract_node('{}.iterkeys()') message = testutils.Message('dict-iter-method', node=node) with self.assertAddsMessages(message): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def test_dict_not_iter_method(self): arg_node = test_utils.extract_node('x.iterkeys(x) #@') @@ -311,20 +311,20 @@ class Python3CheckerTest(testutils.CheckerTestCase): non_dict_node = test_utils.extract_node('x=[]\nx.iterkeys() #@') with self.assertNoMessages(): for node in (arg_node, stararg_node, kwarg_node, non_dict_node): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def test_dict_view_method(self): for meth in ('keys', 'values', 'items'): node = test_utils.extract_node('x.view%s() #@' % meth) message = testutils.Message('dict-view-method', node=node) with self.assertAddsMessages(message): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def test_dict_view_method_on_dict(self): node = test_utils.extract_node('{}.viewkeys()') message = testutils.Message('dict-view-method', node=node) with self.assertAddsMessages(message): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def test_dict_not_view_method(self): arg_node = test_utils.extract_node('x.viewkeys(x) #@') @@ -333,13 +333,13 @@ class Python3CheckerTest(testutils.CheckerTestCase): non_dict_node = test_utils.extract_node('x=[]\nx.viewkeys() #@') with self.assertNoMessages(): for node in (arg_node, stararg_node, kwarg_node, non_dict_node): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def test_next_method(self): node = test_utils.extract_node('x.next() #@') message = testutils.Message('next-method-called', node=node) with self.assertAddsMessages(message): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def test_not_next_method(self): arg_node = test_utils.extract_node('x.next(x) #@') @@ -347,7 +347,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): kwarg_node = test_utils.extract_node('x.next(y=x) #@') with self.assertNoMessages(): for node in (arg_node, stararg_node, kwarg_node): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) def test_metaclass_assignment(self): node = test_utils.extract_node(""" @@ -355,7 +355,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): __metaclass__ = type""") message = testutils.Message('metaclass-assignment', node=node) with self.assertAddsMessages(message): - self.checker.visit_class(node) + self.checker.visit_classdef(node) def test_metaclass_global_assignment(self): module = astroid.parse('__metaclass__ = type') @@ -405,7 +405,7 @@ class Python3CheckerTest(testutils.CheckerTestCase): for node in nodes: message = testutils.Message('using-cmp-argument', node=node) with self.assertAddsMessages(message): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) @python2_only diff --git a/pylint/test/unittest_checker_spelling.py b/pylint/test/unittest_checker_spelling.py index c630eb2..3c43474 100644 --- a/pylint/test/unittest_checker_spelling.py +++ b/pylint/test/unittest_checker_spelling.py @@ -65,7 +65,7 @@ class SpellingCheckerTest(CheckerTestCase): args=('coment', 'bad coment', ' ^^^^^^', "comet' or 'comment' or 'moment' or 'foment"))): - self.checker.visit_function(stmt) + self.checker.visit_functiondef(stmt) stmt = test_utils.extract_node( 'class Abc(object):\n """bad coment"""\n pass') @@ -74,7 +74,7 @@ class SpellingCheckerTest(CheckerTestCase): args=('coment', 'bad coment', ' ^^^^^^', "comet' or 'comment' or 'moment' or 'foment"))): - self.checker.visit_class(stmt) + self.checker.visit_classdef(stmt) @unittest.skipIf(spell_dict is None, "missing python-enchant package or missing " @@ -86,7 +86,7 @@ class SpellingCheckerTest(CheckerTestCase): with self.assertAddsMessages( Message('invalid-characters-in-docstring', line=2, args=('test\x00',))): - self.checker.visit_function(stmt) + self.checker.visit_functiondef(stmt) if __name__ == '__main__': diff --git a/pylint/test/unittest_checker_strings.py b/pylint/test/unittest_checker_strings.py index eaf7663..9c6d769 100644 --- a/pylint/test/unittest_checker_strings.py +++ b/pylint/test/unittest_checker_strings.py @@ -34,7 +34,7 @@ class StringCheckerTest(CheckerTestCase): code = "b'test'.format(1, 2)" node = test_utils.extract_node(code) with self.assertNoMessages(): - self.checker.visit_callfunc(node) + self.checker.visit_call(node) if __name__ == '__main__': diff --git a/pylint/test/unittest_checker_typecheck.py b/pylint/test/unittest_checker_typecheck.py index aa60a7b..b7135ea 100644 --- a/pylint/test/unittest_checker_typecheck.py +++ b/pylint/test/unittest_checker_typecheck.py @@ -22,7 +22,7 @@ class TypeCheckerTest(CheckerTestCase): 'no-member', node=node, args=('Module', 'optparse', 'THIS_does_not_EXIST'))): - self.checker.visit_getattr(node) + self.checker.visit_attribute(node) @set_config(ignored_modules=('argparse',)) def test_no_member_in_getattr_ignored(self): @@ -35,7 +35,7 @@ class TypeCheckerTest(CheckerTestCase): argparse.THIS_does_not_EXIST """) with self.assertNoMessages(): - self.checker.visit_getattr(node) + self.checker.visit_attribute(node) @set_config(ignored_classes=('xml.etree.', )) def test_ignored_modules_invalid_pattern(self): @@ -46,7 +46,7 @@ class TypeCheckerTest(CheckerTestCase): message = Message('no-member', node=node, args=('Module', 'xml.etree', 'Lala')) with self.assertAddsMessages(message): - self.checker.visit_getattr(node) + self.checker.visit_attribute(node) @set_config(ignored_modules=('xml.etree*', )) def test_ignored_modules_patterns(self): @@ -55,7 +55,7 @@ class TypeCheckerTest(CheckerTestCase): xml.etree.portocola #@ ''') with self.assertNoMessages(): - self.checker.visit_getattr(node) + self.checker.visit_attribute(node) @set_config(ignored_classes=('xml.*', )) def test_ignored_classes_no_recursive_pattern(self): @@ -66,7 +66,7 @@ class TypeCheckerTest(CheckerTestCase): message = Message('no-member', node=node, args=('Module', 'xml.etree.ElementTree', 'Test')) with self.assertAddsMessages(message): - self.checker.visit_getattr(node) + self.checker.visit_attribute(node) @set_config(ignored_classes=('optparse.Values', )) def test_ignored_classes_qualified_name(self): @@ -76,7 +76,7 @@ class TypeCheckerTest(CheckerTestCase): optparse.Values.lala ''') with self.assertNoMessages(): - self.checker.visit_getattr(node) + self.checker.visit_attribute(node) @set_config(ignored_classes=('Values', )) def test_ignored_classes_only_name(self): @@ -86,7 +86,7 @@ class TypeCheckerTest(CheckerTestCase): optparse.Values.lala ''') with self.assertNoMessages(): - self.checker.visit_getattr(node) + self.checker.visit_attribute(node) if __name__ == '__main__': diff --git a/pylint/test/unittest_checker_variables.py b/pylint/test/unittest_checker_variables.py index a176a90..0a235d4 100644 --- a/pylint/test/unittest_checker_variables.py +++ b/pylint/test/unittest_checker_variables.py @@ -36,7 +36,7 @@ class VariablesCheckerTC(CheckerTestCase): from argparse import THIS_does_not_EXIST """) with self.assertNoMessages(): - self.checker.visit_from(node) + self.checker.visit_importfrom(node) @set_config(callbacks=('callback_', '_callback')) def test_custom_callback_string(self): @@ -52,16 +52,16 @@ class VariablesCheckerTC(CheckerTestCase): ''' should not emit unused-argument. ''' """) with self.assertNoMessages(): - self.checker.visit_function(node) - self.checker.leave_function(node) + self.checker.visit_functiondef(node) + self.checker.leave_functiondef(node) node = test_utils.extract_node(""" def two_callback(abc, defg): ''' should not emit unused-argument. ''' """) with self.assertNoMessages(): - self.checker.visit_function(node) - self.checker.leave_function(node) + self.checker.visit_functiondef(node) + self.checker.leave_functiondef(node) node = test_utils.extract_node(""" def normal_func(abc): @@ -69,8 +69,8 @@ class VariablesCheckerTC(CheckerTestCase): """) with self.assertAddsMessages( Message('unused-argument', node=node['abc'], args='abc')): - self.checker.visit_function(node) - self.checker.leave_function(node) + self.checker.visit_functiondef(node) + self.checker.leave_functiondef(node) node = test_utils.extract_node(""" def cb_func(abc): @@ -78,8 +78,8 @@ class VariablesCheckerTC(CheckerTestCase): """) with self.assertAddsMessages( Message('unused-argument', node=node['abc'], args='abc')): - self.checker.visit_function(node) - self.checker.leave_function(node) + self.checker.visit_functiondef(node) + self.checker.leave_functiondef(node) class MissingSubmoduleTest(CheckerTestCase): diff --git a/pylint/test/unittest_utils.py b/pylint/test/unittest_utils.py index 193e452..8fff282 100644 --- a/pylint/test/unittest_utils.py +++ b/pylint/test/unittest_utils.py @@ -12,9 +12,11 @@ # this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import unittest +import warnings import astroid +from pylint import __pkginfo__ from pylint import utils from pylint import interfaces from pylint.checkers.utils import check_messages @@ -37,18 +39,18 @@ class PyLintASTWalkerTest(unittest.TestCase): self.called.add('module') @check_messages('second-message') - def visit_callfunc(self, module): + def visit_call(self, module): raise NotImplementedError @check_messages('second-message', 'third-message') - def visit_assname(self, module): + def visit_assignname(self, module): self.called.add('assname') @check_messages('second-message') - def leave_assname(self, module): + def leave_assignname(self, module): raise NotImplementedError - def testCheckMessages(self): + def test_check_messages(self): linter = self.MockLinter({'first-message': True, 'second-message': False, 'third-message': True}) @@ -58,6 +60,35 @@ class PyLintASTWalkerTest(unittest.TestCase): walker.walk(astroid.parse("x = func()")) self.assertEqual(set(['module', 'assname']), checker.called) + def test_deprecated_methods(self): + class Checker(object): + def __init__(self): + self.called = False + + @check_messages('first-message') + def visit_assname(self, node): + self.called = True + + linter = self.MockLinter({'first-message': True}) + walker = utils.PyLintASTWalker(linter) + checker = Checker() + walker.add_checker(checker) + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + walker.walk(astroid.parse("x = 1")) + + if __pkginfo__.numversion < (2, 0): + expected = ('Implemented method visit_assname instead of ' + 'visit_assignname. This will be supported until ' + 'Pylint 2.0.') + self.assertEqual(len(w), 1) + self.assertIsInstance(w[0].message, PendingDeprecationWarning) + self.assertEqual(str(w[0].message), expected) + self.assertTrue(checker.called) + else: + self.assertNotEqual(len(w), 1) + self.assertFalse(checker.called) + if __name__ == '__main__': unittest.main() diff --git a/pylint/utils.py b/pylint/utils.py index 42f21d1..c918783 100644 --- a/pylint/utils.py +++ b/pylint/utils.py @@ -905,6 +905,16 @@ class PyLintASTWalker(object): if old_cid: visit_events = self.visit_events.get(old_cid) leave_events = self.leave_events.get(old_cid) + if visit_events or leave_events: + msg = ("Implemented method {meth}_{old} instead of {meth}_{new}. " + "This will be supported until Pylint 2.0.") + if visit_events: + warnings.warn(msg.format(meth="visit", old=old_cid, new=cid), + PendingDeprecationWarning) + if leave_events: + warnings.warn(msg.format(meth="leave", old=old_cid, new=cid), + PendingDeprecationWarning) + if not visit_events: visit_events = self.visit_events.get(cid) if not leave_events: |