Skip to content

Commit

Permalink
Merge pull request #1783 from avanwinkle/prospector
Browse files Browse the repository at this point in the history
Increase Prospector Strictness: High
  • Loading branch information
avanwinkle committed Mar 21, 2024
2 parents 4a4725d + 1dd8ae6 commit a9b12f1
Show file tree
Hide file tree
Showing 57 changed files with 265 additions and 162 deletions.
2 changes: 1 addition & 1 deletion .prospector.yaml
@@ -1,4 +1,4 @@
strictness: medium
strictness: high
max-line-length: 120

mccabe:
Expand Down
4 changes: 2 additions & 2 deletions mpf/commands/test.py
Expand Up @@ -2,23 +2,23 @@
import os

import argparse
import logging
import re
import unittest
import sys

from kivy.logger import Logger # pylint: disable=import-error
from mpf.commands import MpfCommandLineParser
from mpf.tests.MpfDocTestCase import MpfDocTestCase, MpfDocTestCaseNoFakeGame
from mpf.tests.MpfIntegrationDocTestCase import MpfIntegrationDocTestCase

# some hacks to unbreak logging after loading the kivy logger
import logging
root = logging.root
os.environ['KIVY_NO_FILELOG'] = '1'
os.environ['KIVY_NO_CONSOLELOG'] = '1'
os.environ["KIVY_NO_ARGS"] = "1"

# pylint: disable-msg=import-error,wrong-import-position
from kivy.logger import Logger
for handler in Logger.handlers:
Logger.removeHandler(handler)
sys.stdout = sys.__stdout__
Expand Down
2 changes: 1 addition & 1 deletion mpf/config_players/event_player.py
Expand Up @@ -54,7 +54,7 @@ def handle_subscription_change(self, value, settings, priority, context, key):

if s["number"] is not None:
self.delay.add(callback=self._post_event, ms=s["number"],
event=event, priority=s["priority"], params=s["params"])
event=event, priority=s["priority"], params=s["params"])
else:
self._post_event(event, s["priority"], s["params"])

Expand Down
1 change: 1 addition & 0 deletions mpf/core/assets.py
Expand Up @@ -634,6 +634,7 @@ def load_asset(self, asset):
task.add_done_callback(Util.raise_exceptions)


# pylint: disable-msg=invalid-name
TUnconditionalAssetEntry = Tuple[AssetClass, int]
TConditionalAssetEntry = Tuple[AssetClass, int, BoolTemplate]
TMaybeConditionalAssetEntry = Union[TUnconditionalAssetEntry, TConditionalAssetEntry]
Expand Down
2 changes: 1 addition & 1 deletion mpf/core/ball_search.py
Expand Up @@ -279,7 +279,7 @@ def _run(self):

# if a callback returns True we wait for the next one
self.debug_log("Ball search: %s (phase: %s iteration: %s)",
element.name, self.phase, self.iteration)
element.name, self.phase, self.iteration)
if element.callback(self.phase, self.iteration):
self.delay.add(name='run', callback=self._run, ms=timeout)
return
Expand Down
3 changes: 2 additions & 1 deletion mpf/core/bcp/bcp.py
Expand Up @@ -58,7 +58,8 @@ def _setup_bcp_connections(self, queue: QueuedEvent, **kwargs):
"""Connect to BCP servers from MPF config."""
del kwargs
if 'connections' not in self.machine.config['bcp'] or \
not self.machine.config['bcp']['connections'] or self.machine.config['bcp']['connections'] == 'None':
not self.machine.config['bcp']['connections'] or \
self.machine.config['bcp']['connections'] == 'None':
return

client_connect_futures = []
Expand Down
29 changes: 14 additions & 15 deletions mpf/core/config_validator.py
Expand Up @@ -180,9 +180,7 @@ def _validate_config(self, config_spec, source, base_spec=None, add_missing_keys

if not isinstance(source, dict):
raise self.validation_error(source, validation_failure_info,
"Config attribute should be dict but is {}".format(
source.__class__
))
"Config attribute should be dict but is {}".format(source.__class__))

for k in list(this_spec.keys()):
if this_spec[k] == 'ignore' or k[0] == '_':
Expand Down Expand Up @@ -235,9 +233,10 @@ def validate_config_item(self, spec, validation_failure_info,
if item == 'item not in config!@#':
if default == 'default required!@#':
section = self._build_error_path(validation_failure_info.parent)
raise self.validation_error("None", validation_failure_info,
'Required setting "{}:" is missing from section "{}:" in your config.'.format(
validation_failure_info.item, section), 9)
raise self.validation_error(
"None", validation_failure_info,
f'Required setting "{validation_failure_info.item}:" is missing '
f'from section "{section}:" in your config.', 9)
item = default

if item_type == 'single':
Expand Down Expand Up @@ -375,9 +374,9 @@ def _validate_type_enum(self, item, param, validation_failure_info):
if item is True and 'yes' in enum_values:
return 'yes'

raise self.validation_error(item, validation_failure_info,
"Entry \"{}\" is not valid for enum. Valid values are: {}".format(
item, str(param)))
raise self.validation_error(
item, validation_failure_info,
f'Entry "{item}" is not valid for enum. Valid values are: {str(param)}')

def _validate_type_machine(self, item, param, validation_failure_info):
if item is None:
Expand All @@ -387,20 +386,20 @@ def _validate_type_machine(self, item, param, validation_failure_info):

if not isinstance(item, str):
raise self.validation_error(item, validation_failure_info,
'Expected "{}" in "{}" to be string'.format(item, param),
10)
'Expected "{}" in "{}" to be string'.format(item, param),
10)

if not item:
raise self.validation_error(item, validation_failure_info,
'Setting "{}" is empty'.format(param),
14)
'Setting "{}" is empty'.format(param),
14)

if item in section:
return section[item]

raise self.validation_error(item, validation_failure_info,
'Device "{}" not found in "{}:" section in your config.'.format(item, param),
6)
'Device "{}" not found in "{}:" section in your config.'.format(item, param),
6)

@classmethod
def _validate_type_list(cls, item, validation_failure_info):
Expand Down
2 changes: 1 addition & 1 deletion mpf/core/data_manager.py
Expand Up @@ -129,7 +129,7 @@ def _writing_thread(self): # pragma: no cover
# save data
try:
FileManager.save(self.filename, data)
except Exception as e:
except Exception as e: # pylint: disable=broad-exception-caught
# If the file writer has an exception handle it here. Otherwise
# this thread will die and all subsequent write attempts will no-op.
self.info_log("ERROR writing file %s: %s", self.filename, e)
Expand Down
16 changes: 15 additions & 1 deletion mpf/core/platform.py
Expand Up @@ -527,19 +527,30 @@ async def get_hw_switch_states(self) -> Dict[str, bool]:

@dataclass
class SwitchSettings:

"""Base class for a switch configuration setting."""

hw_switch: Any
invert: Any
debounce: Any


@dataclass
class DriverSettings:

"""Base class for a driver configuration setting."""

hw_driver: Any
pulse_settings: Any
hold_settings: Any
recycle: Any


@dataclass
class DriverConfig:

"""Base class for a driver platform configuration."""

name: str
default_pulse_ms: int
default_pulse_power: float
Expand All @@ -550,13 +561,16 @@ class DriverConfig:
max_pulse_power: float
max_hold_power: float


@dataclass
class RepulseSettings:

"""Base class for a driver repulse setting."""

enable_repulse: bool
debounce_ms: int



class DriverPlatform(BasePlatform, metaclass=abc.ABCMeta):

"""Baseclass for platforms with drivers."""
Expand Down
10 changes: 7 additions & 3 deletions mpf/core/plugin.py
Expand Up @@ -2,9 +2,12 @@

from mpf.core.logging import LogMixin


class MpfPlugin(LogMixin):

__slots__ = ("machine", "name")
"""Base class for a plugin module."""

__slots__ = ("machine", "name", "config")

config_section = None

Expand All @@ -13,11 +16,12 @@ def __init__(self, machine):
super().__init__()
self.machine = machine
self.name = type(self).__name__
self.config = None

if self.config_section and self.config_section not in self.machine.config:
self.machine.log.debug('"%s:" section not found in machine '
'configuration, so the %s will not be '
'used.', self.config_section, self.name)
'configuration, so the %s will not be '
'used.', self.config_section, self.name)

def initialize(self):
"""Called when the plugin is enabled and loaded into MPF.
Expand Down
2 changes: 1 addition & 1 deletion mpf/core/text_ui.py
Expand Up @@ -170,7 +170,7 @@ async def _bcp_status_report(self, client, cpu, rss, vms):

def _update_stats(self):
# Runtime
rt = (datetime.now() - self.start_time)
rt = datetime.now() - self.start_time
mins, sec = divmod(rt.seconds + rt.days * 86400, 60)
hours, mins = divmod(mins, 60)
self.footer_uptime.text = 'RUNNING {:d}:{:02d}:{:02d}'.format(hours, mins, sec)
Expand Down
2 changes: 1 addition & 1 deletion mpf/devices/ball_hold.py
Expand Up @@ -251,7 +251,7 @@ def _lost_ball(self, device, balls, **kwargs):
else:
self.info_log("Ball device %s lost %s balls but hold is not holding. Doing nothing.", device, balls)
# Do not claim this ball
return { 'balls': balls }
return {'balls': balls}

def _hold_ball(self, device, new_balls, unclaimed_balls, **kwargs):
"""Handle result of _ball_enter event of hold_devices."""
Expand Down
4 changes: 2 additions & 2 deletions mpf/devices/light.py
Expand Up @@ -344,8 +344,8 @@ async def _initialize(self):
self.default_fade_ms = (self.machine.config['light_settings']
['default_fade_ms'])

if len(self.hw_drivers) == 4 and all(
channel in self.hw_drivers for channel in ['red', 'green', 'blue', 'white']):
if len(self.hw_drivers) == 4 and all(channel in self.hw_drivers
for channel in ['red', 'green', 'blue', 'white']):
self._rbgw_style = self.machine.config['mpf']['rgbw_white_behavior']

self.debug_log("Initializing Light. CC Profile: %s, "
Expand Down
23 changes: 11 additions & 12 deletions mpf/devices/light_group.py
Expand Up @@ -95,20 +95,20 @@ def color(self, color, fade_ms=None, priority=0, key=None):
def _reorder_lights(self):
if self.config['size'] == '8digit':
#Magic order for 8 digit NeoSeg displays from CobraPin
order = [95,90,93,82,85,89,86,91,88,87,81,92,83,84,94,
104,76,79,96,99,103,100,77,102,101,75,78,97,98,80,
110,105,108,67,70,74,71,106,73,72,66,107,68,69,109,
119,61,64,111,114,118,115,62,117,116,60,63,112,113,65,
5,0,3,52,55,59,56,1,58,57,51,2,53,54,4,
14,46,49,6,9,13,10,47,12,11,45,48,7,8,50,
20,15,18,37,40,44,41,16,43,42,36,17,38,39,19,
29,31,34,21,24,28,25,32,27,26,30,33,22,23,35]
order = [95, 90, 93, 82, 85, 89, 86, 91, 88, 87, 81, 92, 83, 84, 94,
104, 76, 79, 96, 99, 103, 100, 77, 102, 101, 75, 78, 97, 98, 80,
110, 105, 108, 67, 70, 74, 71, 106, 73, 72, 66, 107, 68, 69, 109,
119, 61, 64, 111, 114, 118, 115, 62, 117, 116, 60, 63, 112, 113, 65,
5, 0, 3, 52, 55, 59, 56, 1, 58, 57, 51, 2, 53, 54, 4,
14, 46, 49, 6, 9, 13, 10, 47, 12, 11, 45, 48, 7, 8, 50,
20, 15, 18, 37, 40, 44, 41, 16, 43, 42, 36, 17, 38, 39, 19,
29, 31, 34, 21, 24, 28, 25, 32, 27, 26, 30, 33, 22, 23, 35]
elif self.config['size'] == '2digit':
#Magic order for 2 digit NeoSeg displays from CobraPin
order = [5,0,3,22,25,29,26,1,28,27,21,2,23,24,4,
14,16,19,6,9,13,10,17,12,11,15,18,7,8,20]
order = [5, 0, 3, 22, 25, 29, 26, 1, 28, 27, 21, 2, 23, 24, 4,
14, 16, 19, 6, 9, 13, 10, 17, 12, 11, 15, 18, 7, 8, 20]
else:
order = range(0,len(self.lights))
order = range(0, len(self.lights))

self.lights = [self.lights[i] for i in order]

Expand Down Expand Up @@ -179,7 +179,6 @@ class NeoSegDisplay(LightGroup):

__slots__ = [] # type: List[str]


def _create_lights(self):
if self.config['size'] == '8digit':
count = 120
Expand Down
2 changes: 1 addition & 1 deletion mpf/devices/multiball_lock.py
Expand Up @@ -335,7 +335,7 @@ def _lost_ball(self, device, balls, **kwargs):
del kwargs
self.info_log("Ball device %s lost %s balls, %s has %s locked balls and action %s",
device.name, balls, self.name, self.locked_balls,
self.config['ball_lost_action'] )
self.config['ball_lost_action'])
if self.locked_balls and self.config['ball_lost_action'] == "add_to_play":
self.info_log("Ball device %s lost %s balls, adding to balls_in_play", device.name, balls)
self.machine.game.balls_in_play += balls
Expand Down
1 change: 0 additions & 1 deletion mpf/devices/score_reel_controller.py
Expand Up @@ -152,7 +152,6 @@ async def _game_starting(self, **kwargs):
score_reel_group.set_value(0)
await score_reel_group.wait_for_ready()


def _game_ending(self, **kwargs):
"""Reset controller."""
del kwargs
Expand Down
2 changes: 1 addition & 1 deletion mpf/devices/segment_display/segment_display_text.py
Expand Up @@ -47,7 +47,7 @@ def from_str(cls, text: str, display_size: int, collapse_dots: bool, collapse_co
char_colors = [None] * len(text)
return UncoloredSegmentDisplayText(
cls._create_characters(text, display_size, collapse_dots, collapse_commas, use_dots_for_commas,
char_colors), collapse_dots, collapse_commas, use_dots_for_commas)
char_colors), collapse_dots, collapse_commas, use_dots_for_commas)

@classmethod
def _embed_dots_and_commas(cls, text: str, collapse_dots: bool, collapse_commas: bool, use_dots_for_commas: bool):
Expand Down
4 changes: 2 additions & 2 deletions mpf/devices/segment_display/transition_manager.py
Expand Up @@ -25,8 +25,8 @@ def get_transition(output_length: int, collapse_dots: bool, collapse_commas: boo
if transition_config:
config = transition_config.copy()
config.pop('type')
return TRANSITIONS[transition_config['type']](output_length, collapse_dots, collapse_commas,
use_dots_for_commas, config)
return TRANSITIONS[transition_config['type']](output_length, collapse_dots, collapse_commas,
use_dots_for_commas, config)

return None

Expand Down
2 changes: 1 addition & 1 deletion mpf/devices/sequence_shot.py
Expand Up @@ -180,7 +180,7 @@ def _completed(self):
elapsed = 0

"""Post sequence complete event including its elapsed time to complete."""
self.machine.events.post("{}_hit".format(self.name),elapsed=elapsed)
self.machine.events.post("{}_hit".format(self.name), elapsed=elapsed)
'''event: (name)_hit
desc: The sequence_shot called (name) was just completed.
'''
Expand Down
2 changes: 1 addition & 1 deletion mpf/devices/speedometer.py
Expand Up @@ -37,5 +37,5 @@ def _handle_stop_switch(self, **kwargs):
delta = self.config['stop_switch'].last_change - self.time_start
self.time_start = None
print(delta)
self.machine.events.post("{}_hit".format(self.name), delta = delta)
self.machine.events.post("{}_hit".format(self.name), delta=delta)
# TODO: post event
1 change: 1 addition & 0 deletions mpf/file_interfaces/yaml_interface.py
Expand Up @@ -10,6 +10,7 @@
_yaml = yaml.YAML(typ='safe')
_yaml.default_flow_style = False


class YamlInterface(FileInterface):

"""File interface for yaml files."""
Expand Down
1 change: 1 addition & 0 deletions mpf/modes/bonus/code/bonus.py
Expand Up @@ -104,6 +104,7 @@ def _bonus_next_item(self):
self._bonus_next_item()
return

# pylint: disable=superfluous-parens
if self.settings["rounding_value"] and (r := (score % self.settings["rounding_value"])):
self.debug_log("rounding bonus score %s remainder of %s", score, r)
if self.settings["rounding_direction"] == "down":
Expand Down
2 changes: 1 addition & 1 deletion mpf/modes/high_score/code/high_score.py
Expand Up @@ -184,7 +184,7 @@ async def _run(self) -> None:
new_list.append([player, player[category_name]])

# sort if from highest to lowest
new_list.sort(key=lambda x: x[1], reverse=(category_name not in self.high_score_config['reverse_sort']))
new_list.sort(key=lambda x: x[1], reverse=category_name not in self.high_score_config['reverse_sort'])

# scan through and see if any of our players are in this list
i = 0
Expand Down

0 comments on commit a9b12f1

Please sign in to comment.