Skip to content

Complex-number literals raise JSON error in Python #363

Closed
@jakelishman

Description

@jakelishman

Hello,

We use CodeClimate in a numerical Python library for quantum physics (QuTiP). I noticed that the duplication check errors out on Python files with complex literals in them (e.g. 1+1j), because they're reported as constant numerical values by the AST, but they can't be serialised directly to JSON.

For example, if I have a file complex.py with three different representations of the same complex literal:

def a():
    return 1 + 1j

def b():
    return 1+1j

def c():
    return (1+1J)

I run codeclimate analyze on it (setting mass_threshold: 1 in the configuration to be sure), but it reports no errors. Running it with debug on shows that it errored out in the parsing:

$ CODECLIMATE_DEBUG=1 codeclimate analyze complex.py
Starting analysis
I, [2021-06-16T17:08:13.904775 #1]  INFO -- : starting engine duplication
D, [2021-06-16T17:08:13.913623 #1] DEBUG -- : /config.json content: {"enabled"=>true, "config"=>{"languages"=>{"python"=>{"python_version"=>3, "mass_threshold"=>1}}}, "channel"=>"stable", "include_paths"=>["complex.py"], "debug"=>"1"}
D, [2021-06-16T17:08:13.936497 #1] DEBUG -- : docker run: ["docker", "run", "--name", "cc-engines-duplication-stable-9469e0f0-c421-4472-abf1-f5b5360dcaa8", "--cap-drop", "all", "--label", "com.codeclimate.label=550a3ba1-6b4f-4c1a-a0d7-16be3f7a0698", "--log-driver", "none", "--memory-swap", "-1", "--net", "none", "--rm", "--volume", "/Users/jake/tmp/complex:/code:ro", "--volume", "/tmp/cc/8997f528-5780-451e-81c2-d750bc7cfcd8:/config.json:ro", "--user", "9000:9000", "--memory", "1024000000", "codeclimate/codeclimate-duplication"]
D, [2021-06-16T17:08:14.336583 #1] DEBUG -- : engine stderr: 13
D, [2021-06-16T17:08:14.336766 #1] DEBUG -- : engine stderr: Parser process id: 13
D, [2021-06-16T17:08:14.338017 #1] DEBUG -- : engine stderr: codeclimate-parser socket not present
D, [2021-06-16T17:08:14.338164 #1] DEBUG -- : engine stderr: waiting 1s...
D, [2021-06-16T17:08:16.015964 #1] DEBUG -- : engine stderr: D, [2021-06-16T17:08:16.013924 #1] DEBUG -- : Processing 1 python files concurrency=2
D, [2021-06-16T17:08:16.016154 #1] DEBUG -- : engine stderr: /home/app/.rubies/ruby-2.5.1/lib/ruby/gems/2.5.0/gems/concurrent-ruby-1.0.0/lib/concurrent/atomic/mutex_atomic_fixnum.rb:80: warning: constant ::Fixnum is deprecated
D, [2021-06-16T17:08:16.018794 #1] DEBUG -- : engine stderr: D, [2021-06-16T17:08:16.015640 #1] DEBUG -- : Processing python file: complex.py
D, [2021-06-16T17:08:16.070863 #1] DEBUG -- : engine stderr: I, [2021-06-16T17:08:16.069556 #1]  INFO -- : Skipping file complex.py due to exception (CC::Engine::Analyzers::ParserError): `python3 /usr/src/app/lib/cc/engine/analyzers/python/parser.py` exited with code 1:
D, [2021-06-16T17:08:16.071149 #1] DEBUG -- : engine stderr: Traceback (most recent call last):
D, [2021-06-16T17:08:16.071247 #1] DEBUG -- : engine stderr:   File "/usr/src/app/lib/cc/engine/analyzers/python/parser.py", line 47, in <module>
D, [2021-06-16T17:08:16.071290 #1] DEBUG -- : engine stderr:     print(json.dumps(to_json(ast.parse(source))))
D, [2021-06-16T17:08:16.072500 #1] DEBUG -- : engine stderr:   File "/usr/local/python3/lib/python3.7/json/__init__.py", line 231, in dumps
D, [2021-06-16T17:08:16.072665 #1] DEBUG -- : engine stderr:     return _default_encoder.encode(obj)
D, [2021-06-16T17:08:16.072790 #1] DEBUG -- : engine stderr:   File "/usr/local/python3/lib/python3.7/json/encoder.py", line 199, in encode
D, [2021-06-16T17:08:16.072916 #1] DEBUG -- : engine stderr:     chunks = self.iterencode(o, _one_shot=True)
D, [2021-06-16T17:08:16.072970 #1] DEBUG -- : engine stderr:   File "/usr/local/python3/lib/python3.7/json/encoder.py", line 257, in iterencode
D, [2021-06-16T17:08:16.073069 #1] DEBUG -- : engine stderr:     return _iterencode(o, 0)
D, [2021-06-16T17:08:16.073165 #1] DEBUG -- : engine stderr:   File "/usr/local/python3/lib/python3.7/json/encoder.py", line 179, in default
D, [2021-06-16T17:08:16.073217 #1] DEBUG -- : engine stderr:     raise TypeError(f'Object of type {o.__class__.__name__} '
D, [2021-06-16T17:08:16.073252 #1] DEBUG -- : engine stderr: TypeError: Object of type complex is not JSON serializable
D, [2021-06-16T17:08:16.073348 #1] DEBUG -- : engine stderr:
D, [2021-06-16T17:08:16.074902 #1] DEBUG -- : engine stderr: /usr/src/app/lib/cc/engine/analyzers/command_line_runner.rb:26:in `block in run'
D, [2021-06-16T17:08:16.075792 #1] DEBUG -- : engine stderr: /home/app/.rubies/ruby-2.5.1/lib/ruby/2.5.0/timeout.rb:93:in `block in timeout'
D, [2021-06-16T17:08:16.076834 #1] DEBUG -- : engine stderr: /home/app/.rubies/ruby-2.5.1/lib/ruby/2.5.0/timeout.rb:33:in `block in catch'
D, [2021-06-16T17:08:16.078338 #1] DEBUG -- : engine stderr: /home/app/.rubies/ruby-2.5.1/lib/ruby/2.5.0/timeout.rb:33:in `catch'
D, [2021-06-16T17:08:16.078990 #1] DEBUG -- : engine stderr: /home/app/.rubies/ruby-2.5.1/lib/ruby/2.5.0/timeout.rb:33:in `catch'
D, [2021-06-16T17:08:16.081147 #1] DEBUG -- : engine stderr: /home/app/.rubies/ruby-2.5.1/lib/ruby/2.5.0/timeout.rb:108:in `timeout'
D, [2021-06-16T17:08:16.081442 #1] DEBUG -- : engine stderr: /usr/src/app/lib/cc/engine/analyzers/command_line_runner.rb:18:in `run'
D, [2021-06-16T17:08:16.082227 #1] DEBUG -- : engine stderr: /usr/src/app/lib/cc/engine/analyzers/python/parser.rb:23:in `parse'
D, [2021-06-16T17:08:16.083131 #1] DEBUG -- : engine stderr: /usr/src/app/lib/cc/engine/analyzers/python/main.rb:26:in `process_file'
D, [2021-06-16T17:08:16.083798 #1] DEBUG -- : engine stderr: /usr/src/app/lib/cc/engine/analyzers/analyzer_base.rb:41:in `run'
D, [2021-06-16T17:08:16.083935 #1] DEBUG -- : engine stderr: /usr/src/app/lib/cc/engine/analyzers/reporter.rb:76:in `block in process_files'
D, [2021-06-16T17:08:16.083999 #1] DEBUG -- : engine stderr: /usr/src/app/lib/cc/engine/analyzers/file_thread_pool.rb:24:in `block (2 levels) in run'
D, [2021-06-16T17:08:16.084422 #1] DEBUG -- : engine stderr: D, [2021-06-16T17:08:16.070274 #1] DEBUG -- : Processed 1 python files
D, [2021-06-16T17:08:16.084603 #1] DEBUG -- : engine stderr: D, [2021-06-16T17:08:16.081480 #1] DEBUG -- : Reported 0 violations...
I, [2021-06-16T17:08:16.192031 #1]  INFO -- : finished engine duplication

Analysis complete! Found 0 issues.

This is the case with both Python 2 and Python 3.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    pFad - Phonifier reborn

    Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

    Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


    Alternative Proxies:

    Alternative Proxy

    pFad Proxy

    pFad v3 Proxy

    pFad v4 Proxy