diff --git a/PYTHON/downloadCats/generate_cats.py b/PYTHON/downloadCats/generate_cats.py index c83d6cb..e746b63 100644 --- a/PYTHON/downloadCats/generate_cats.py +++ b/PYTHON/downloadCats/generate_cats.py @@ -23,9 +23,7 @@ while requests_send < MAX_REQUESTS: ) requests_send += 1 response = json.loads(res.text) - urls = [] - for cat in response: - urls.append(cat.get("url")) + urls = [cat.get("url") for cat in response] Path("./CATS2").mkdir(parents=True, exist_ok=True) for url in urls: diff --git a/PYTHON/keyboardCoop/main.py b/PYTHON/keyboardCoop/main.py index c216d62..b3052c3 100644 --- a/PYTHON/keyboardCoop/main.py +++ b/PYTHON/keyboardCoop/main.py @@ -242,9 +242,10 @@ class KeyboardCoopGame: new_col = col_idx + dc # Check bounds - if 0 <= new_row < len(self.keyboard_layout): - if 0 <= new_col < len(self.keyboard_layout[new_row]): - adjacents.append(self.keyboard_layout[new_row][new_col]) + if 0 <= new_row < len(self.keyboard_layout) and 0 <= new_col < len( + self.keyboard_layout[new_row] + ): + adjacents.append(self.keyboard_layout[new_row][new_col]) self.key_adjacency[letter] = adjacents diff --git a/PYTHON/lichess_bot/engine.py b/PYTHON/lichess_bot/engine.py index 4376330..840fa4a 100644 --- a/PYTHON/lichess_bot/engine.py +++ b/PYTHON/lichess_bot/engine.py @@ -99,7 +99,7 @@ class RandomEngine: move = chess.Move.from_uci(chosen_uci) except Exception: msg = f"Engine returned invalid move: '{chosen_uci}' (output: {output!r})" - raise RuntimeError(msg) + raise RuntimeError(msg) from None if move not in board.legal_moves: msg = f"Engine returned illegal move for position: {chosen_uci}" diff --git a/PYTHON/lichess_bot/tests/test_puzzles.py b/PYTHON/lichess_bot/tests/test_puzzles.py index 1009f1f..4fa3d1d 100644 --- a/PYTHON/lichess_bot/tests/test_puzzles.py +++ b/PYTHON/lichess_bot/tests/test_puzzles.py @@ -41,9 +41,7 @@ def test_puzzle_engine_follow_solution(fen: str, moves_str: str) -> None: # Moves are space-separated UCIs alternating sides # starting from side-to-move in the FEN solution_moves = moves_str.split() - step = 0 - for uci in solution_moves: - step += 1 + for step, uci in enumerate(solution_moves, start=1): # Engine move on this ply mv, expl = eng.choose_move_with_explanation(board, time_budget_sec=0.5) assert mv is not None, f"No move returned at step {step}.\nExplanation: {expl}" diff --git a/PYTHON/lichess_bot/tools/generate_blunder_tests.py b/PYTHON/lichess_bot/tools/generate_blunder_tests.py index 345c7d7..4c63d36 100755 --- a/PYTHON/lichess_bot/tools/generate_blunder_tests.py +++ b/PYTHON/lichess_bot/tools/generate_blunder_tests.py @@ -178,7 +178,7 @@ def fen_and_uci_for_blunders( f"side {bl.side} in position FEN: {fen_before}. " f"Error: {e}" ) - raise ValueError(msg) + raise ValueError(msg) from e results.append((fen_before, move.uci(), best_uci, bl)) return results diff --git a/PYTHON/screen_locker/screen_lock.py b/PYTHON/screen_locker/screen_lock.py index 8c958b8..ea1715f 100755 --- a/PYTHON/screen_locker/screen_lock.py +++ b/PYTHON/screen_locker/screen_lock.py @@ -634,11 +634,11 @@ class ScreenLocker: try: with open(self.log_file) as f: logs = json.load(f) - - today = datetime.now(tz=timezone.utc).strftime("%Y-%m-%d") - return today in logs except (OSError, json.JSONDecodeError): return False + else: + today = datetime.now(tz=timezone.utc).strftime("%Y-%m-%d") + return today in logs def save_workout_log(self) -> None: """Save workout data to log file.""" diff --git a/PYTHON/split/split_x_into_n_symmetrically.py b/PYTHON/split/split_x_into_n_symmetrically.py index d243fba..fec89b7 100644 --- a/PYTHON/split/split_x_into_n_symmetrically.py +++ b/PYTHON/split/split_x_into_n_symmetrically.py @@ -23,8 +23,7 @@ def calculate_symmetric_weights( next_weight = weights_left[-1] + factor weights_left.append(next_weight) else: - for i in range(half_n - 1): - weights_left.append(middle_weight - (i + 1)) + weights_left.extend(middle_weight - (i + 1) for i in range(half_n - 1)) if n % 2 == 0: weights = weights_left[::-1] + weights_left diff --git a/PYTHON/stockfish_analysis/analyze_chess_game.py b/PYTHON/stockfish_analysis/analyze_chess_game.py index bea116c..b13b034 100755 --- a/PYTHON/stockfish_analysis/analyze_chess_game.py +++ b/PYTHON/stockfish_analysis/analyze_chess_game.py @@ -159,7 +159,7 @@ def _parse_threads(value: str) -> int | None: return max(1, n) except ValueError: msg = "--threads must be an integer or 'auto'" - raise argparse.ArgumentTypeError(msg) + raise argparse.ArgumentTypeError(msg) from None def _parse_hash_mb(value: str) -> int | None: @@ -171,7 +171,7 @@ def _parse_hash_mb(value: str) -> int | None: return max(16, mb) except ValueError: msg = "--hash-mb must be an integer (MB) or 'auto'" - raise argparse.ArgumentTypeError(msg) + raise argparse.ArgumentTypeError(msg) from None def _detect_total_mem_mb() -> int | None: diff --git a/pyproject.toml b/pyproject.toml index d3d4fa2..e788b6c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,19 +31,9 @@ ignore = [ "D203", # 1 blank line required before class docstring (conflicts with D211) # D212 vs D213 conflict - we use D212 (summary on first line after """) "D213", # Multi-line docstring summary should start at second line (conflicts with D212) + # Formatter conflicts - these rules conflict with ruff format "COM812", # Trailing comma missing (conflicts with formatter) "ISC001", # Implicit string concatenation (conflicts with formatter) - # Style preferences - relaxed for script-heavy repository - "PERF401", # manual-list-comprehension - style preference - "RUF005", # collection-literal-concatenation - style preference - "SIM102", # collapsible-if - style preference - "SIM103", # needless-bool - style preference - "SIM105", # suppressible-exception - style preference - "SIM108", # if-else-block - style preference - "SIM113", # enumerate-for-loop - style preference - "B904", # raise-without-from - style preference - "TRY300", # try-consider-else - style preference - "TRY301", # raise-within-try - style preference ] # Allow ALL rules to be auto-fixed @@ -120,6 +110,7 @@ unfixable = [] "PTH", # os.path patterns in existing code "LOG015", # Root logger in bot "G004", # f-strings in logging + "TRY301", # Raise in try block for null checks on subprocess streams ] "PYTHON/lichess_bot/engine.py" = [ "BLE001", # Blind except for engine error handling @@ -159,6 +150,7 @@ unfixable = [] "S311", # Random for number randomization, not crypto "LOG015", # Root logger in script "G004", # f-strings in logging + "TRY301", # Raise in try block for input validation ] "PYTHON/keyboardCoop/main.py" = [ "FBT003", # Boolean positional values in pygame API calls (e.g., font.render)