diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..990e27819 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,18 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: master + hooks: + - id: check-ast + - id: check-json + - id: check-xml + - id: check-yaml +- repo: local + hooks: + - id: pylint + name: pylint + entry: pylint + language: system + types: [python] + exclude: '^(pyextra)|(external)/' + args: + - --disable=R,C,W diff --git a/.pylintrc b/.pylintrc index 64a55daf8..9a55710c4 100644 --- a/.pylintrc +++ b/.pylintrc @@ -3,7 +3,7 @@ # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code -extension-pkg-whitelist=scipy +extension-pkg-whitelist=scipy cereal.messaging.messaging_pyx # Add files or directories to the blacklist. They should be base names, not # paths. diff --git a/Pipfile b/Pipfile index d0c6b8ee2..c743ecd4d 100644 --- a/Pipfile +++ b/Pipfile @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:48daf8ab5c86410503faaec54272993937b8dc2fd6793243689e91872f53136f -size 2026 +oid sha256:c4ea33acc8b1f639f0719f436989886263a67271decbcf29ab8907208161da03 +size 2043 diff --git a/Pipfile.lock b/Pipfile.lock index 7c328f717..fde2f81ca 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6268aff3b5943f5f279e1c0c89f17914309d6245cfe5de3c64c8cd75c3acadda -size 156137 +oid sha256:34b9162abbc667c0b14f418f43668422491613c32bfe8a7d8da86b3fc256350f +size 165941 diff --git a/common/url_file.py b/common/url_file.py index 1f6d4a081..184b7452b 100644 --- a/common/url_file.py +++ b/common/url_file.py @@ -1,3 +1,5 @@ +# pylint: skip-file + import os import time import tempfile diff --git a/common/window.py b/common/window.py index 5af3d83cd..7454a8620 100644 --- a/common/window.py +++ b/common/window.py @@ -27,10 +27,10 @@ class Window(): def getkey(self): while 1: event = pygame.event.wait() - if event.type == QUIT: + if event.type == pygame.QUIT: pygame.quit() sys.exit() - if event.type == KEYDOWN: + if event.type == pygame.KEYDOWN: return event.key def getclick(self): @@ -47,4 +47,3 @@ if __name__ == "__main__": print("draw") img += 1 win.draw(img) - diff --git a/scripts/waste.py b/scripts/waste.py index 55aeba066..2834dea19 100755 --- a/scripts/waste.py +++ b/scripts/waste.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 from multiprocessing import Process -from setproctitle import setproctitle +from setproctitle import setproctitle # pylint: disable=no-name-in-module import os import numpy as np from common.realtime import sec_since_boot @@ -32,4 +32,3 @@ def main(gctx=None): if __name__ == "__main__": main() - diff --git a/selfdrive/controls/tests/test_clustering.py b/selfdrive/controls/tests/test_clustering.py index e899ff7d5..290b26702 100644 --- a/selfdrive/controls/tests/test_clustering.py +++ b/selfdrive/controls/tests/test_clustering.py @@ -1,3 +1,5 @@ +# pylint: skip-file + import time import unittest import numpy as np diff --git a/selfdrive/debug/internal/cycle_alerts.py b/selfdrive/debug/internal/cycle_alerts.py deleted file mode 100644 index cc073aaa2..000000000 --- a/selfdrive/debug/internal/cycle_alerts.py +++ /dev/null @@ -1,50 +0,0 @@ -# USAGE: python cycle_alerts.py [duration_millis=1000] -# Then start manager - -import argparse -import time - -import cereal.messaging as messaging -from selfdrive.controls.lib.alerts import ALERTS - -def now_millis(): return time.time() * 1000 - -default_alerts = sorted(ALERTS, key=lambda alert: (alert.alert_size, len(alert.alert_text_2))) - -def cycle_alerts(duration_millis, alerts=None): - if alerts is None: - alerts = default_alerts - - controls_state = messaging.pub_sock('controlsState') - - last_pop_millis = now_millis() - alert = alerts.pop() - while 1: - if (now_millis() - last_pop_millis) > duration_millis: - alerts.insert(0, alert) - alert = alerts.pop() - last_pop_millis = now_millis() - print('sending {}'.format(str(alert))) - - dat = messaging.new_message('controlsState') - - dat.controlsState.alertType = alert.alert_type - dat.controlsState.alertText1 = alert.alert_text_1 - dat.controlsState.alertText2 = alert.alert_text_2 - dat.controlsState.alertSize = alert.alert_size - dat.controlsState.alertStatus = alert.alert_status - dat.controlsState.alertSound = alert.audible_alert - controls_state.send(dat.to_bytes()) - - time.sleep(0.01) - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--duration', type=int, default=1000) - parser.add_argument('--alert-types', nargs='+') - args = parser.parse_args() - alerts = None - if args.alert_types: - alerts = [next(a for a in ALERTS if a.alert_type==alert_type) for alert_type in args.alert_types] - - cycle_alerts(args.duration, alerts=alerts) diff --git a/selfdrive/debug/internal/sounds/test_sound_stability.py b/selfdrive/debug/internal/sounds/test_sound_stability.py index 18b87abb2..2b8662208 100755 --- a/selfdrive/debug/internal/sounds/test_sound_stability.py +++ b/selfdrive/debug/internal/sounds/test_sound_stability.py @@ -6,7 +6,7 @@ import datetime import random from common.basedir import BASEDIR -from selfdrive import messaging +import cereal.messaging as messaging if __name__ == "__main__": diff --git a/selfdrive/debug/internal/test_paramsd.py b/selfdrive/debug/internal/test_paramsd.py index 356edfaef..3553949ac 100755 --- a/selfdrive/debug/internal/test_paramsd.py +++ b/selfdrive/debug/internal/test_paramsd.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +# pylint: skip-file + import numpy as np import math from tqdm import tqdm diff --git a/selfdrive/locationd/models/loc_kf.py b/selfdrive/locationd/models/loc_kf.py index f1834b14c..fbb6b1b58 100755 --- a/selfdrive/locationd/models/loc_kf.py +++ b/selfdrive/locationd/models/loc_kf.py @@ -443,8 +443,6 @@ class LocKalman(): r = self.predict_and_update_orb_features(data, t, kind) elif kind == ObservationKind.MSCKF_TEST: r = self.predict_and_update_msckf_test(data, t, kind) - elif kind == ObservationKind.FEATURE_TRACK_TEST: - r = self.predict_and_update_feature_track_test(data, t, kind) elif kind == ObservationKind.ODOMETRIC_SPEED: r = self.predict_and_update_odo_speed(data, t, kind) else: diff --git a/selfdrive/loggerd/ethernetsniffer.py b/selfdrive/loggerd/ethernetsniffer.py index 023dacc90..3c3ffb338 100755 --- a/selfdrive/loggerd/ethernetsniffer.py +++ b/selfdrive/loggerd/ethernetsniffer.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +# pylint: skip-file + import cereal.messaging as messaging import pcap @@ -13,4 +15,3 @@ def main(): if __name__ == "__main__": main() - diff --git a/selfdrive/test/process_replay/inject_model.py b/selfdrive/test/process_replay/inject_model.py index 08fd74a62..38647b451 100755 --- a/selfdrive/test/process_replay/inject_model.py +++ b/selfdrive/test/process_replay/inject_model.py @@ -85,8 +85,3 @@ def inject_model(msgs, segment_name): assert abs(len(new_msgs) - len(list(msgs))) < 2 return new_msgs - - - -if __name__ == "__main__": - inject_model("0375fdf7b1ce594d|2019-06-13--08-32-25/3") diff --git a/selfdrive/test/test_eon_fan.py b/selfdrive/test/test_eon_fan.py index 4d683cf4d..c7e435741 100755 --- a/selfdrive/test/test_eon_fan.py +++ b/selfdrive/test/test_eon_fan.py @@ -2,7 +2,7 @@ import sys import time -from selfdrive.thermald import setup_eon_fan, set_eon_fan +from selfdrive.thermald.thermald import setup_eon_fan, set_eon_fan if __name__ == "__main__": val = 0 @@ -18,5 +18,3 @@ if __name__ == "__main__": time.sleep(2) val += 1 val %= 4 - - diff --git a/selfdrive/test/test_leeco_alt_fan.py b/selfdrive/test/test_leeco_alt_fan.py index 882ca787a..c10ede34a 100755 --- a/selfdrive/test/test_leeco_alt_fan.py +++ b/selfdrive/test/test_leeco_alt_fan.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +# pylint: skip-file + import time from smbus2 import SMBus @@ -18,4 +20,3 @@ def setup_leon_fan(): bus.close() setup_leon_fan() - diff --git a/selfdrive/test/test_leeco_fan.py b/selfdrive/test/test_leeco_fan.py index 2ecccf305..55267285b 100755 --- a/selfdrive/test/test_leeco_fan.py +++ b/selfdrive/test/test_leeco_fan.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +# pylint: skip-file + import time from smbus2 import SMBus @@ -20,4 +22,3 @@ def setup_leon_fan(): bus.close() setup_leon_fan() - diff --git a/tools/lib/framereader.py b/tools/lib/framereader.py index 87c6d6e94..741f51dae 100644 --- a/tools/lib/framereader.py +++ b/tools/lib/framereader.py @@ -1,3 +1,5 @@ +# pylint: skip-file + import os import sys import json diff --git a/tools/lib/kbhit.py b/tools/lib/kbhit.py index 30587590a..99b88bfbc 100644 --- a/tools/lib/kbhit.py +++ b/tools/lib/kbhit.py @@ -1,18 +1,17 @@ #!/usr/bin/env python -import os import sys import termios import atexit from select import select + class KBHit: - def __init__(self): '''Creates a KBHit object that you can call to do various keyboard things. ''' - self.set_kbhit_terminal() - + self.set_kbhit_terminal() + def set_kbhit_terminal(self): # Save the terminal settings self.fd = sys.stdin.fileno() @@ -29,12 +28,8 @@ class KBHit: def set_normal_term(self): ''' Resets to normal terminal. On Windows this is a no-op. ''' - - if os.name == 'nt': - pass - - else: - termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old_term) + + termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old_term) def getch(self): @@ -42,7 +37,7 @@ class KBHit: Should not be called in the same program as getarrow(). ''' return sys.stdin.read(1) - + def getarrow(self): ''' Returns an arrow-key code after kbhit() has been called. Codes are @@ -52,29 +47,23 @@ class KBHit: 3 : left Should not be called in the same program as getch(). ''' - - if os.name == 'nt': - msvcrt.getch() # skip 0xE0 - c = msvcrt.getch() - vals = [72, 77, 80, 75] - - else: - c = sys.stdin.read(3)[2] - vals = [65, 67, 66, 68] - + + c = sys.stdin.read(3)[2] + vals = [65, 67, 66, 68] + return vals.index(ord(c.decode('utf-8'))) - + def kbhit(self): ''' Returns True if keyboard character was hit, False otherwise. - ''' + ''' dr,dw,de = select([sys.stdin], [], [], 0) return dr != [] - - -# Test + + +# Test if __name__ == "__main__": - + kb = KBHit() print('Hit any key, or ESC to exit') @@ -86,7 +75,5 @@ if __name__ == "__main__": if ord(c) == 27: # ESC break print(c) - - kb.set_normal_term() - + kb.set_normal_term() diff --git a/tools/lib/mkvparse/mkvgen.py b/tools/lib/mkvparse/mkvgen.py index 963d60d01..df1781278 100755 --- a/tools/lib/mkvparse/mkvgen.py +++ b/tools/lib/mkvparse/mkvgen.py @@ -4,7 +4,7 @@ import random import math # Simple hacky Matroska generator -# Reads mp3 file "q.mp3" and jpeg images from img/0.jpg, img/1.jpg and so on and +# Reads mp3 file "q.mp3" and jpeg images from img/0.jpg, img/1.jpg and so on and # writes Matroska file with mjpeg and mp3 to stdout # License=MIT @@ -71,7 +71,7 @@ def random_uid(): def rint(): return int(random.random()*(0x100**4)) return ben(rint()) + ben(rint()) + ben(rint()) + ben(rint()) - + def example(): write_ebml_header(sys.stdout, "matroska", 2, 2) @@ -133,7 +133,7 @@ def example(): def mp3framesgenerator(f): debt="" while True: - for i in xrange(0,len(debt)+1): + for i in range(0,len(debt)+1): if i >= len(debt)-1: debt = debt + f.read(8192) break @@ -144,13 +144,13 @@ def example(): # sys.stderr.write("len="+str(i)+"\n") debt = debt[i:] break - + mp3 = mp3framesgenerator(mp3file) - mp3.next() + next(mp3) - for i in xrange(0,530): + for i in range(0,530): framefile = open("img/"+str(i)+".jpg", "rb") framedata = framefile.read() framefile.close() @@ -168,8 +168,8 @@ def example(): + framedata ))) - for u in xrange(0,4): - mp3f=mp3.next() + for u in range(0,4): + mp3f=next(mp3) if random.random()<1: sys.stdout.write(ebml_element(0x1F43B675, "" # Cluster + ebml_element(0xE7, ben(i*26*4+u*26)) # TimeCode, uint, milliseconds diff --git a/tools/lib/mkvparse/mkvindex.py b/tools/lib/mkvparse/mkvindex.py index c05423006..694965fbf 100644 --- a/tools/lib/mkvparse/mkvindex.py +++ b/tools/lib/mkvparse/mkvindex.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (c) 2016, Comma.ai, Inc. +# flake8: noqa import re import binascii @@ -15,7 +15,7 @@ class MatroskaIndex(mkvparse.MatroskaHandler): self.frameindex = [] def tracks_available(self): - _, self.config_record = self.tracks[1]['CodecPrivate'] + _, self.config_record = self.tracks[1]['CodecPrivate'] # pylint: disable=no-member def frame(self, track_id, timestamp, pos, length, more_laced_frames, duration, keyframe, invisible, discardable): @@ -62,4 +62,3 @@ def simple_gen(of, config_record, w, h, framedata): + ebml_element(0xE7, ben(0)) # TimeCode, uint, milliseconds # + ebml_element(0xA7, ben(0)) # Position, uint + ''.join(blocks))) - diff --git a/tools/lib/mkvparse/mkvparse.py b/tools/lib/mkvparse/mkvparse.py index 114fb4cce..ea4b7e010 100644 --- a/tools/lib/mkvparse/mkvparse.py +++ b/tools/lib/mkvparse/mkvparse.py @@ -7,6 +7,7 @@ # No proper EOF handling unfortunately # See "mkvuser.py" for the example +# pylint: skip-file import traceback from struct import unpack @@ -15,7 +16,7 @@ import sys import datetime if sys.version < '3': - range=xrange + range=xrange # pylint disable=undefined-variable else: #identity=lambda x:x def ord(something): @@ -159,7 +160,7 @@ def read_fixedlength_number(f, length, signed=False): buf = f.read(length) (r, pos) = parse_fixedlength_number(buf, 0, length, signed) return r - + def read_ebml_element_header(f): ''' Read Element ID and size @@ -180,10 +181,10 @@ class EbmlElementType: FLOAT=7 DATE=8 - JUST_GO_ON=10 # For "Segment". - # Actually MASTER, but don't build the tree for all subelements, + JUST_GO_ON=10 # For "Segment". + # Actually MASTER, but don't build the tree for all subelements, # interpreting all child elements as if they were top-level elements - + EET=EbmlElementType @@ -510,7 +511,7 @@ def read_ebml_element_tree(f, total_size): while(total_size>0): (id_, size, hsize) = read_ebml_element_header(f) if size == -1: - sys.stderr.write("mkvparse: Element %x without size? Damaged data? Skipping %d bytes\n" % (id_, size, total_size)) + sys.stderr.write("mkvparse: Element %x without size? Damaged data? Skipping %d bytes\n" % (id_, size, total_size)) # pylint disable=too-many-format-args f.read(total_size); break; if size>total_size: @@ -523,9 +524,9 @@ def read_ebml_element_tree(f, total_size): (type_, name) = element_types_names[id_] data = read_simple_element(f, type_, size) total_size-=(size+hsize) - childs.append((name, (type_, data))) + childs.append((name, (type_, data))) return childs - + class MatroskaHandler: """ User for mkvparse should override these methods """ @@ -569,7 +570,7 @@ def handle_block(buffer, buffer_pos, handler, cluster_timecode, timecode_scale=1 handler.frame(tracknum, block_timecode, buffer_pos+pos, len(buffer)-pos, 0, duration, f_keyframe, f_invisible, f_discardable) return - + numframes = ord(buffer[pos]); pos+=1 numframes+=1 @@ -628,9 +629,9 @@ def resync(f): if b2 == b"\x54\xAE\x6B": (seglen ,x )= read_matroska_number(f) return (0x1654AE6B, seglen, x+4) # tracks - - - + + + def mkvparse(f, handler): ''' @@ -655,14 +656,14 @@ def mkvparse(f, handler): (id_, size, hsize) = read_ebml_element_header(f) except StopIteration: break; - if not (id_ in element_types_names): + if not (id_ in element_types_names): sys.stderr.write("mkvparse: Unknown element with id %x and size %d\n"%(id_, size)) (resync_element_id, resync_element_size, resync_element_headersize) = resync(f) if resync_element_id: continue; else: break; - else: + else: id_ = resync_element_id size=resync_element_size hsize=resync_element_headersize @@ -686,7 +687,7 @@ def mkvparse(f, handler): continue; else: break; - + if name=="EBML" and type(data) == list: d = dict(tree) if 'EBMLReadVersion' in d: @@ -694,12 +695,12 @@ def mkvparse(f, handler): if 'DocTypeReadVersion' in d: if d['DocTypeReadVersion'][1]>2: sys.stderr.write("mkvparse: Warning: DocTypeReadVersion too big\n") dt = d['DocType'][1] - if dt != "matroska" and dt != "webm": + if dt != "matroska" and dt != "webm": sys.stderr.write("mkvparse: Warning: EBML DocType is not \"matroska\" or \"webm\"") elif name=="Info" and type(data) == list: handler.segment_info = tree handler.segment_info_available() - + d = dict(tree) if "TimecodeScale" in d: timecode_scale = d["TimecodeScale"][1] diff --git a/tools/replay/unlog_segment.py b/tools/replay/unlog_segment.py index cea3c9697..1c80cd047 100755 --- a/tools/replay/unlog_segment.py +++ b/tools/replay/unlog_segment.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +# pylint: skip-file + import argparse import bisect import select diff --git a/tools/replay/unlogger.py b/tools/replay/unlogger.py index 920d9d0b3..3463660e8 100755 --- a/tools/replay/unlogger.py +++ b/tools/replay/unlogger.py @@ -421,7 +421,7 @@ def main(argv): if not p.is_alive(): [p.terminate() for p in subprocesses.values()] exit() - signal.signal(signal.SIGCHLD, signal.SIGIGN) + signal.signal(signal.SIGCHLD, signal.SIG_IGN) signal.signal(signal.SIGCHLD, exit_if_children_dead) if args.interactive: diff --git a/tools/sim/bridge.py b/tools/sim/bridge.py index 0235e1d9f..f2949239e 100755 --- a/tools/sim/bridge.py +++ b/tools/sim/bridge.py @@ -79,7 +79,7 @@ def go(q): threading.Thread(target=health_function).start() threading.Thread(target=fake_driver_monitoring).start() - import carla + import carla # pylint: disable=import-error client = carla.Client("127.0.0.1", 2000) client.set_timeout(5.0) world = client.load_world('Town04') @@ -231,7 +231,7 @@ if __name__ == "__main__": print("WARNING: NO CARLA") while 1: time.sleep(1) - + from multiprocessing import Process, Queue q = Queue() p = Process(target=go, args=(q,)) @@ -246,4 +246,3 @@ if __name__ == "__main__": # start input poll for keyboard from lib.keyboard_ctrl import keyboard_poll_thread keyboard_poll_thread(q) - diff --git a/tools/sim/lib/can.py b/tools/sim/lib/can.py index 3948e818b..a446d38cd 100755 --- a/tools/sim/lib/can.py +++ b/tools/sim/lib/can.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import cereal.messaging as messaging from opendbc.can.packer import CANPacker -from selfdrive.boardd.boardd_api_impl import can_list_to_can_capnp +from selfdrive.boardd.boardd_api_impl import can_list_to_can_capnp # pylint: disable=no-name-in-module from selfdrive.car.honda.values import FINGERPRINTS, CAR from selfdrive.car import crc8_pedal import math @@ -88,4 +88,3 @@ def sendcan_function(sendcan): steer_torque = 0.0 return (gas, brake, steer_torque) - diff --git a/tools/sim/lib/manual_ctrl.py b/tools/sim/lib/manual_ctrl.py index a32d606d4..4c94c13f7 100755 --- a/tools/sim/lib/manual_ctrl.py +++ b/tools/sim/lib/manual_ctrl.py @@ -132,8 +132,8 @@ def wheel_poll_thread(q): print('%d buttons found: %s' % (num_buttons, ', '.join(button_map))) # Enable FF - import evdev - from evdev import ecodes, InputDevice, ff + import evdev # pylint: disable=import-error + from evdev import ecodes, InputDevice, ff # pylint: disable=import-error device = evdev.list_devices()[0] evtdev = InputDevice(device) val = 24000 diff --git a/tools/streamer/streamerd.py b/tools/streamer/streamerd.py index 6ce940afc..81b20fa2d 100755 --- a/tools/streamer/streamerd.py +++ b/tools/streamer/streamerd.py @@ -1,4 +1,6 @@ #!/usr/bin/env python +# pylint: skip-file + import os import sys import zmq