Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RecursionError: maximum recursion depth exceeded #293

Closed
cyw3 opened this issue Jul 10, 2020 · 7 comments
Closed

RecursionError: maximum recursion depth exceeded #293

cyw3 opened this issue Jul 10, 2020 · 7 comments

Comments

@cyw3
Copy link
Contributor

cyw3 commented Jul 10, 2020

Lizard 1.17.5
Python 3.7.0

When I want to update lizard 1.16.3 to lizard 1.17.5, I get a error:

$ python3 lizard.py --csv --sort cyclomatic_complexity --CCN 5 -l javascript test/ 

Traceback (most recent call last):
  File "lizard.py", line 1059, in <module>
    main()
  File "lizard.py", line 1042, in main
    warning_count = printer(result, options, schema, AllResult)
  File "/tools/lizard-1.17.5/lizard_ext/__init__.py", line 17, in print_csv
    csv_output(total_factory(list(results)), options.verbose)
  File "lizard.py", line 545, in __call__
    filename, auto_read(filename))
  File "lizard.py", line 564, in analyze_source_code
    for _ in reader(tokens, reader):
  File "/tools/lizard-1.17.5/lizard_languages/code_reader.py", line 161, in __call__
    state(token)
  File "/tools/lizard-1.17.5/lizard_languages/code_reader.py", line 45, in __call__
    if self._state(token):
  File "/tools/lizard-1.17.5/lizard_languages/code_reader.py", line 45, in __call__
    if self._state(token):
  File "/tools/lizard-1.17.5/lizard_languages/code_reader.py", line 45, in __call__
    if self._state(token):
  [Previous line repeated 490 more times]
  File "/tools/lizard-1.17.5/lizard_languages/js_style_language_states.py", line 77, in _expecting_statement_or_block
    self.next(self._state_global, token)
  File "/tools/lizard-1.17.5/lizard_languages/code_reader.py", line 28, in next
    return self(token)
  File "/tools/lizard-1.17.5/lizard_languages/code_reader.py", line 45, in __call__
    if self._state(token):
RecursionError: maximum recursion depth exceeded
$ python3 lizard.py --csv --sort cyclomatic_complexity --CCN 5 --working_threads 8 -l javascript test/ 

multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
  File "/tools/Python-v3.7.0/lib/python3.7/multiprocessing/pool.py", line 121, in worker
    result = (True, func(*args, **kwds))
  File "lizard.py", line 538, in __call__
    filename, auto_read(filename))
  File "lizard.py", line 557, in analyze_source_code
    for _ in reader(tokens, reader):
  File "/tools/lizard-1.17.3/lizard_languages/code_reader.py", line 161, in __call__
    state(token)
  File "/tools/lizard-1.17.3/lizard_languages/code_reader.py", line 45, in __call__
    if self._state(token):
  File "/tools/lizard-1.17.3/lizard_languages/code_reader.py", line 45, in __call__
    if self._state(token):
  File "/tools/lizard-1.17.3/lizard_languages/code_reader.py", line 45, in __call__
    if self._state(token):
  [Previous line repeated 483 more times]
  File "/tools/lizard-1.17.3/lizard_languages/js_style_language_states.py", line 129, in _state_global
    super(ES6ObjectStates, self)._state_global(token)
  File "/tools/lizard-1.17.3/lizard_languages/js_style_language_states.py", line 41, in _state_global
    self.statemachine_return()
  File "/tools/lizard-1.17.3/lizard_languages/code_reader.py", line 37, in statemachine_return
    self.statemachine_before_return()
  File "/tools/lizard-1.17.3/lizard_languages/js_style_language_states.py", line 49, in statemachine_before_return
    self._pop_function_from_stack()
RecursionError: maximum recursion depth exceeded
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "lizard.py", line 1052, in <module>
    main()
  File "lizard.py", line 1035, in main
    warning_count = printer(result, options, schema, AllResult)
  File "/tools/lizard-1.17.3/lizard_ext/__init__.py", line 17, in print_csv
    csv_output(total_factory(list(results)), options.verbose)
  File "/tools/Python-v3.7.0/lib/python3.7/multiprocessing/pool.py", line 748, in next
    raise value
RecursionError: maximum recursion depth exceeded

And when use Lizard 1.16.3 to scan the same project, it works.

@cyw3
Copy link
Contributor Author

cyw3 commented Jul 15, 2020

the test case is the index.js of prettier@2.0.5

image

@terryyin
Copy link
Owner

terryyin commented Jul 16, 2020 via email

@shaikh-mansurali
Copy link

We are also facing same issue.

@jackhj000
Copy link

+1

@liiri
Copy link

liiri commented Aug 29, 2021

The core of the problem here is that the tokenizer is expecting every open html tag, i.e <Tag> to end with a closing tag </Tag>.
However, js also have generics, i.e Array<Tag> and then we quickly get into endless recursion of not having any closing tags.

Example snippet out of the referenced prettier:

{
    type: 'DebuggerStatement';
    _DebuggerStatement: void;
    end: number;
    innerComments: ?Array<Comment>;
    leadingComments: ?Array<Comment>;
    loc: {
        end: { column: number, line: number },
        start: { column: number, line: number },
    };
    start: number;
    trailingComments: ?Array<Comment>;
} 

each <Comment> block is leading us to nest into another tokenizer ...
Not sure whats the best approach to resolve this.

see microsoft/TypeScript#15713

@sthagen
Copy link

sthagen commented Oct 27, 2021

To help lizard at least survive these encounters, one may apply this crude monkey patch (or something similar):

diff --git a/lizard.py b/lizard.py
index ba8b0eb..ab74698 100755
--- a/lizard.py
+++ b/lizard.py
@@ -562,8 +562,11 @@ class FileAnalyzer(object):  # pylint: disable=R0903
         tokens = reader.generate_tokens(code)
         for processor in self.processors:
             tokens = processor(tokens, reader)
-        for _ in reader(tokens, reader):
-            pass
+        try:
+            for _ in reader(tokens, reader):
+                pass
+        except RecursionError as err:
+            print("skipped:", filename, "with reason: RecursionError (unclosed tags/scopes?)")  # or something similar ...
         return context.fileinfo

@cyw3
Copy link
Contributor Author

cyw3 commented Dec 31, 2021

Thanks!

@cyw3 cyw3 closed this as completed Dec 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants