mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-07-04 14:43:01 +02:00
refactor: rename folders to fix N999, INP001, S311 linting rules
- Rename PYTHON/ to python_pkg/ (fix N999 uppercase folder) - Rename camelCase folders to snake_case: - randomJPG -> random_jpg - tagDivider -> tag_divider - downloadCats -> download_cats - keyboardCoop -> keyboard_coop - extractLinks -> extract_links - scapeWebsite -> scrape_website - Rename camelCase files: - generateJpeg.py -> generate_jpeg.py - tagDivider.py -> tag_divider.py - Rename poker-modifier-app to poker_modifier_app (fix INP001) - Add __init__.py to poker_modifier_app - Replace random module with secrets.SystemRandom (fix S311) - Fix S110 try-except-pass with contextlib.suppress - Update all imports and config references
This commit is contained in:
parent
6b62f6bea9
commit
ec8861d01c
8
.github/workflows/python-tests.yml
vendored
8
.github/workflows/python-tests.yml
vendored
@ -4,15 +4,15 @@ on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "PYTHON/lichess_bot/**"
|
||||
- "PYTHON/**"
|
||||
- "python_pkg/lichess_bot/**"
|
||||
- "python_pkg/**"
|
||||
- "tests/**"
|
||||
- "requirements.txt"
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "PYTHON/lichess_bot/**"
|
||||
- "PYTHON/**"
|
||||
- "python_pkg/lichess_bot/**"
|
||||
- "python_pkg/**"
|
||||
- "tests/**"
|
||||
- "requirements.txt"
|
||||
|
||||
|
||||
1
poker_modifier_app/__init__.py
Normal file
1
poker_modifier_app/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
"""Poker modifier application package."""
|
||||
@ -1,12 +1,15 @@
|
||||
"""Texas Hold'em poker game modifier application."""
|
||||
|
||||
import logging
|
||||
import random
|
||||
import secrets
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
# Use cryptographically secure random number generator
|
||||
_rng = secrets.SystemRandom()
|
||||
|
||||
|
||||
class PokerModifierApp:
|
||||
"""GUI application for poker game modifiers."""
|
||||
@ -850,7 +853,7 @@ class PokerModifierApp:
|
||||
modifier_chance = self.prob_var.get()
|
||||
|
||||
# Determine if modifier should be applied
|
||||
random_value = random.random() * 100
|
||||
random_value = _rng.random() * 100
|
||||
should_apply_modifier = random_value < modifier_chance
|
||||
|
||||
if should_apply_modifier:
|
||||
@ -886,7 +889,7 @@ class PokerModifierApp:
|
||||
bg_color = "#2d4a2d" # Green for normal
|
||||
|
||||
# Select random modifier from appropriate pool
|
||||
selected_modifier = random.choice(modifier_pool).copy()
|
||||
selected_modifier = _rng.choice(modifier_pool).copy()
|
||||
|
||||
# Special handling for Steel Cards - randomize the rank
|
||||
if selected_modifier["name"] == "Steel Cards":
|
||||
@ -905,7 +908,7 @@ class PokerModifierApp:
|
||||
"King",
|
||||
"Ace",
|
||||
]
|
||||
steel_rank = random.choice(ranks)
|
||||
steel_rank = _rng.choice(ranks)
|
||||
selected_modifier["description"] = selected_modifier["description"].format(
|
||||
steel_rank=steel_rank
|
||||
)
|
||||
@ -64,112 +64,96 @@ unfixable = []
|
||||
"D103", # Allow missing function docstring
|
||||
"PTH", # Allow os.path in conftest
|
||||
]
|
||||
# N999 ignores for PYTHON folder naming (uppercase folder)
|
||||
"PYTHON/**/__init__.py" = [
|
||||
"N999", # Invalid module name due to PYTHON folder naming
|
||||
]
|
||||
"PYTHON/randomJPG/generateJpeg.py" = [
|
||||
"N999", # camelCase filename preserved for compatibility
|
||||
"S311", # Random for image generation, not crypto
|
||||
"python_pkg/random_jpg/generate_jpeg.py" = [
|
||||
"PTH", # os.path patterns in existing code
|
||||
"LOG015", # Root logger in script
|
||||
"G004", # f-strings in logging
|
||||
]
|
||||
"PYTHON/tagDivider/tagDivider.py" = [
|
||||
"N999", # camelCase filename preserved for compatibility
|
||||
"python_pkg/tag_divider/tag_divider.py" = [
|
||||
"PTH", # os.path patterns in existing code
|
||||
"LOG015", # Root logger in script
|
||||
]
|
||||
"poker-modifier-app/*.py" = [
|
||||
"INP001", # Folder has hyphen, can't be a valid Python package
|
||||
"S311", # Random for game mechanics, not crypto
|
||||
"poker_modifier_app/*.py" = [
|
||||
"LOG015", # Root logger in script
|
||||
"G004", # f-strings in logging
|
||||
]
|
||||
"poker-modifier-app/poker_modifier_app.py" = [
|
||||
"INP001", # Folder has hyphen, can't be a valid Python package
|
||||
"poker_modifier_app/poker_modifier_app.py" = [
|
||||
"FBT003", # Boolean positional values in tkinter API calls
|
||||
"S311", # Random for game mechanics, not crypto
|
||||
"LOG015", # Root logger in app
|
||||
"G004", # f-strings in logging
|
||||
]
|
||||
"PYTHON/downloadCats/generate_cats.py" = [
|
||||
"python_pkg/download_cats/generate_cats.py" = [
|
||||
"PERF203", # Try-except needed for download resilience in loop
|
||||
"PTH", # os.path patterns in existing code
|
||||
"LOG015", # Root logger in script
|
||||
"G004", # f-strings in logging
|
||||
]
|
||||
"PYTHON/lichess_bot/main.py" = [
|
||||
"python_pkg/lichess_bot/main.py" = [
|
||||
"C901", # Complex functions handling game lifecycle (run_bot, handle_game)
|
||||
"PERF203", # Try-except needed for stream/move error handling in loops
|
||||
"PLR0912", # Complex nested game event handling with many branches
|
||||
"PLR0915", # Long function handling complete game lifecycle
|
||||
"BLE001", # Blind except for resilient bot operation
|
||||
"S110", # Try-except-pass for non-critical error handling
|
||||
"S603", # Subprocess call for analysis script
|
||||
"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" = [
|
||||
"python_pkg/lichess_bot/engine.py" = [
|
||||
"BLE001", # Blind except for engine error handling
|
||||
"S110", # Try-except-pass for optional features
|
||||
"S603", # Subprocess for engine communication
|
||||
"PTH", # os.path patterns
|
||||
"LOG015", # Root logger for debug messages
|
||||
]
|
||||
"PYTHON/lichess_bot/lichess_api.py" = [
|
||||
"python_pkg/lichess_bot/lichess_api.py" = [
|
||||
"BLE001", # Blind except for API resilience
|
||||
"LOG015", # Root logger in API client
|
||||
"G004", # f-strings in logging
|
||||
]
|
||||
"PYTHON/lichess_bot/utils.py" = [
|
||||
"python_pkg/lichess_bot/utils.py" = [
|
||||
"BLE001", # Blind except for file operations
|
||||
"PTH", # os.path patterns
|
||||
"LOG015", # Root logger
|
||||
"G004", # f-strings in logging
|
||||
]
|
||||
"PYTHON/lichess_bot/tools/generate_blunder_tests.py" = [
|
||||
"python_pkg/lichess_bot/tools/generate_blunder_tests.py" = [
|
||||
"BLE001", # Blind except for test generation
|
||||
"PTH", # os.path patterns in tool
|
||||
"LOG015", # Root logger in tool
|
||||
"G004", # f-strings in logging
|
||||
]
|
||||
"PYTHON/stockfish_analysis/analyze_chess_game.py" = [
|
||||
"python_pkg/stockfish_analysis/analyze_chess_game.py" = [
|
||||
"C901", # Complex main() with many argument combinations and analysis modes
|
||||
"PLR0912", # Complex main() with many argument combinations and analysis modes
|
||||
"PLR0915", # Long main() handling complete analysis workflow
|
||||
"BLE001", # Blind except for engine configuration
|
||||
"S110", # Try-except-pass for optional engine features
|
||||
"PTH", # os.path patterns
|
||||
"LOG015", # Root logger in analysis tool
|
||||
"G004", # f-strings in logging
|
||||
]
|
||||
"PYTHON/randomize_numbers/random_digits.py" = [
|
||||
"python_pkg/randomize_numbers/random_digits.py" = [
|
||||
"PERF203", # Try-except needed for parsing user input in loop
|
||||
"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" = [
|
||||
"python_pkg/keyboard_coop/main.py" = [
|
||||
"FBT003", # Boolean positional values in pygame API calls (e.g., font.render)
|
||||
"PTH", # os.path patterns
|
||||
"LOG015", # Root logger in script
|
||||
]
|
||||
"PYTHON/screen_locker/screen_lock.py" = [
|
||||
"python_pkg/screen_locker/screen_lock.py" = [
|
||||
"FBT003", # Boolean positional values in tkinter API calls
|
||||
"PTH", # os.path patterns
|
||||
"LOG015", # Root logger in app
|
||||
"G004", # f-strings in logging
|
||||
]
|
||||
"PYTHON/scapeWebsite/scrape_comics.py" = [
|
||||
"python_pkg/scrape_website/scrape_comics.py" = [
|
||||
"BLE001", # Blind except for web scraping resilience
|
||||
"PTH", # os.path patterns
|
||||
"LOG015", # Root logger in script
|
||||
"G004", # f-strings in logging
|
||||
]
|
||||
"PYTHON/extractLinks/main.py" = [
|
||||
"python_pkg/extract_links/main.py" = [
|
||||
"PTH", # os.path patterns
|
||||
"LOG015", # Root logger in script
|
||||
"G004", # f-strings in logging
|
||||
@ -181,7 +165,7 @@ convention = "google" # Use Google docstring convention
|
||||
[tool.ruff.lint.isort]
|
||||
force-single-line = false
|
||||
force-sort-within-sections = true
|
||||
known-first-party = ["PYTHON"]
|
||||
known-first-party = ["python_pkg"]
|
||||
|
||||
[tool.ruff.lint.flake8-quotes]
|
||||
docstring-quotes = "double"
|
||||
|
||||
@ -6,13 +6,16 @@ Players take turns selecting adjacent keys to form valid English words.
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import secrets
|
||||
import sys
|
||||
|
||||
import pygame
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
# Use cryptographically secure random number generator
|
||||
_rng = secrets.SystemRandom()
|
||||
|
||||
# Initialize Pygame
|
||||
pygame.init()
|
||||
|
||||
@ -202,7 +205,7 @@ class KeyboardCoopGame:
|
||||
"""Generate a random keyboard layout and calculate adjacencies."""
|
||||
# All 26 letters
|
||||
all_letters = list("abcdefghijklmnopqrstuvwxyz")
|
||||
random.shuffle(all_letters)
|
||||
_rng.shuffle(all_letters)
|
||||
|
||||
# Create random layout with same structure as QWERTY (10-9-7)
|
||||
self.keyboard_layout = [
|
||||
@ -1,6 +1,8 @@
|
||||
"""Chess engine wrapper for the C-based random/scoring engine."""
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
@ -144,12 +146,10 @@ class RandomEngine:
|
||||
# best move
|
||||
chosen = data.get("chosen_move")
|
||||
if isinstance(chosen, str):
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
bm = chess.Move.from_uci(chosen)
|
||||
if bm in board.legal_moves:
|
||||
best_move = bm
|
||||
except Exception:
|
||||
best_move = None
|
||||
# Store compact explanations for debugging
|
||||
cand_expl = json.dumps(analyze, ensure_ascii=False)
|
||||
best_expl = json.dumps(
|
||||
@ -160,7 +160,6 @@ class RandomEngine:
|
||||
ensure_ascii=False,
|
||||
)
|
||||
except Exception:
|
||||
# Leave defaults with raw output text
|
||||
pass
|
||||
logging.debug("Failed to parse engine JSON output")
|
||||
|
||||
return cand_score, cand_expl, best_move, best_expl
|
||||
@ -1,6 +1,7 @@
|
||||
"""Main entry point for the Lichess bot."""
|
||||
|
||||
import argparse
|
||||
import contextlib
|
||||
import datetime
|
||||
import json
|
||||
import logging
|
||||
@ -12,9 +13,9 @@ import threading
|
||||
import chess
|
||||
import chess.pgn
|
||||
|
||||
from PYTHON.lichess_bot.engine import RandomEngine
|
||||
from PYTHON.lichess_bot.lichess_api import LichessAPI
|
||||
from PYTHON.lichess_bot.utils import backoff_sleep, get_and_increment_version
|
||||
from python_pkg.lichess_bot.engine import RandomEngine
|
||||
from python_pkg.lichess_bot.lichess_api import LichessAPI
|
||||
from python_pkg.lichess_bot.utils import backoff_sleep, get_and_increment_version
|
||||
|
||||
|
||||
def run_bot(log_level: str = "INFO", *, decline_correspondence: bool = False) -> None:
|
||||
@ -91,7 +92,7 @@ def run_bot(log_level: str = "INFO", *, decline_correspondence: bool = False) ->
|
||||
white_name = event["white"].get("name") or white_id or "?"
|
||||
black_name = event["black"].get("name") or black_id or "?"
|
||||
# Set site and date if available
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
# Lichess event may include 'createdAt' ms epoch
|
||||
created_ms = event.get("createdAt") or event.get(
|
||||
"createdAtDate"
|
||||
@ -100,8 +101,6 @@ def run_bot(log_level: str = "INFO", *, decline_correspondence: bool = False) ->
|
||||
game_date_iso = datetime.datetime.fromtimestamp(
|
||||
int(created_ms) / 1000, tz=datetime.timezone.utc
|
||||
).strftime("%Y.%m.%d")
|
||||
except Exception:
|
||||
pass
|
||||
site_url = f"https://lichess.org/{game_id}"
|
||||
me = api.get_my_user_id()
|
||||
if me == white_id:
|
||||
@ -241,7 +240,7 @@ def run_bot(log_level: str = "INFO", *, decline_correspondence: bool = False) ->
|
||||
if game_log_path:
|
||||
game = chess.pgn.Game.from_board(board)
|
||||
# Record the bot version in the PGN headers
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
game.headers["BotVersion"] = f"v{bot_version}"
|
||||
if site_url:
|
||||
game.headers["Site"] = site_url
|
||||
@ -251,8 +250,6 @@ def run_bot(log_level: str = "INFO", *, decline_correspondence: bool = False) ->
|
||||
game.headers["White"] = white_name
|
||||
if black_name:
|
||||
game.headers["Black"] = black_name
|
||||
except Exception:
|
||||
pass
|
||||
with open(game_log_path, "a") as lf:
|
||||
lf.write("\nPGN:\n")
|
||||
exporter = chess.pgn.StringExporter(
|
||||
@ -293,9 +290,9 @@ def run_bot(log_level: str = "INFO", *, decline_correspondence: bool = False) ->
|
||||
lines: list[str] = []
|
||||
ply_line_re = __import__("re").compile(r"^\s*(\d+)\s")
|
||||
# Read stdout line by line
|
||||
if proc.stdout is None:
|
||||
msg = "subprocess stdout is None"
|
||||
raise RuntimeError(msg)
|
||||
# stdout/stderr are guaranteed non-None with PIPE
|
||||
assert proc.stdout is not None # noqa: S101
|
||||
assert proc.stderr is not None # noqa: S101
|
||||
for line in proc.stdout:
|
||||
lines.append(line)
|
||||
m = ply_line_re.match(line)
|
||||
@ -321,9 +318,6 @@ def run_bot(log_level: str = "INFO", *, decline_correspondence: bool = False) ->
|
||||
)
|
||||
|
||||
# Capture any remaining stderr and ensure process ends
|
||||
if proc.stderr is None:
|
||||
msg = "subprocess stderr is None"
|
||||
raise RuntimeError(msg)
|
||||
stderr_text = proc.stderr.read() or ""
|
||||
ret = proc.wait()
|
||||
analysis_text = "".join(lines)
|
||||
@ -4,7 +4,7 @@ import sys
|
||||
|
||||
import pytest
|
||||
|
||||
# Add repository root to sys.path so 'import PYTHON.*' works when running
|
||||
# Add repository root to sys.path so 'import python_pkg.*' works when running
|
||||
# pytest with a subdirectory as rootdir.
|
||||
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../.."))
|
||||
if ROOT not in sys.path:
|
||||
@ -6,7 +6,7 @@ import os
|
||||
import chess
|
||||
import pytest
|
||||
|
||||
from PYTHON.lichess_bot.engine import RandomEngine
|
||||
from python_pkg.lichess_bot.engine import RandomEngine
|
||||
|
||||
|
||||
def _load_top_puzzles(csv_path: str, limit: int = 8) -> list[tuple[str, str]]:
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from PYTHON.lichess_bot.utils import backoff_sleep
|
||||
from python_pkg.lichess_bot.utils import backoff_sleep
|
||||
|
||||
|
||||
def test_backoff_sleep_increments_and_caps(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
@ -4,7 +4,7 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from PYTHON.lichess_bot.utils import get_and_increment_version
|
||||
from python_pkg.lichess_bot.utils import get_and_increment_version
|
||||
|
||||
|
||||
def test_version_file_increments_and_persists(
|
||||
@ -16,17 +16,17 @@ Where logs are loaded from:
|
||||
|
||||
Usage examples:
|
||||
# Process all logs in tools/past_games
|
||||
python PYTHON/lichess_bot/tools/generate_blunder_tests.py
|
||||
python python_pkg/lichess_bot/tools/generate_blunder_tests.py
|
||||
|
||||
# Process a specific game by id from tools/past_games
|
||||
python PYTHON/lichess_bot/tools/generate_blunder_tests.py OVmR29MI
|
||||
python python_pkg/lichess_bot/tools/generate_blunder_tests.py OVmR29MI
|
||||
|
||||
# Process an explicit file path
|
||||
python PYTHON/lichess_bot/tools/generate_blunder_tests.py \
|
||||
python python_pkg/lichess_bot/tools/generate_blunder_tests.py \
|
||||
/path/to/lichess_bot_game_xxxxx.log
|
||||
|
||||
It will create files like:
|
||||
PYTHON/lichess_bot/tests/test_blunders_<gameid>.py
|
||||
python_pkg/lichess_bot/tests/test_blunders_<gameid>.py
|
||||
|
||||
Dependencies: python-chess, pytest (already in requirements.txt)
|
||||
"""
|
||||
@ -203,7 +203,7 @@ REPO_ROOT = os.path.dirname(
|
||||
if REPO_ROOT not in sys.path:
|
||||
sys.path.insert(0, REPO_ROOT)
|
||||
|
||||
from PYTHON.lichess_bot.engine import RandomEngine # noqa: E402
|
||||
from python_pkg.lichess_bot.engine import RandomEngine # noqa: E402
|
||||
|
||||
BLUNDER_CASES = [
|
||||
]
|
||||
@ -5,12 +5,15 @@ from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import secrets
|
||||
|
||||
from PIL import Image
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
# Use cryptographically secure random number generator
|
||||
_rng = secrets.SystemRandom()
|
||||
|
||||
MAX_IMAGE_SIZE = 1000
|
||||
|
||||
|
||||
@ -57,7 +60,7 @@ def generate_bloated_jpeg(config: ImageConfig, image_index: int, folder: str) ->
|
||||
# of random colors from the list
|
||||
for y in range(0, config.size, config.block_size):
|
||||
for x in range(0, config.size, config.block_size):
|
||||
color = random.choice(rgb_colors)
|
||||
color = _rng.choice(rgb_colors)
|
||||
for i in range(config.block_size):
|
||||
for j in range(config.block_size):
|
||||
pixels[x + i, y + j] = color
|
||||
@ -2,12 +2,15 @@
|
||||
|
||||
import contextlib
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
import secrets
|
||||
import sys
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
# Use cryptographically secure random number generator
|
||||
_rng = secrets.SystemRandom()
|
||||
|
||||
DEFAULT_MIN_PERCENTAGE = 1
|
||||
DEFAULT_MAX_PERCENTAGE = 20
|
||||
|
||||
@ -20,8 +23,8 @@ def randomize_numbers(
|
||||
"""Apply random percentage variation to a list of numbers."""
|
||||
randomized_numbers = []
|
||||
for number in numbers:
|
||||
percentage = random.uniform(min_percentage, max_percentage) / 100
|
||||
if random.choice([True, False]):
|
||||
percentage = _rng.uniform(min_percentage, max_percentage) / 100
|
||||
if _rng.choice([True, False]):
|
||||
new_number = number + (number * percentage)
|
||||
else:
|
||||
new_number = number - (number * percentage)
|
||||
@ -60,16 +63,17 @@ if __name__ == "__main__":
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
input_string = " ".join(sys.argv[1:])
|
||||
numbers, decimal_counts = parse_input(input_string)
|
||||
|
||||
if len(numbers) == 0:
|
||||
logging.error("No valid numbers provided.")
|
||||
sys.exit(1)
|
||||
|
||||
min_percentage = DEFAULT_MIN_PERCENTAGE
|
||||
max_percentage = DEFAULT_MAX_PERCENTAGE
|
||||
|
||||
try:
|
||||
input_string = " ".join(sys.argv[1:])
|
||||
numbers, decimal_counts = parse_input(input_string)
|
||||
min_percentage = DEFAULT_MIN_PERCENTAGE
|
||||
max_percentage = DEFAULT_MAX_PERCENTAGE
|
||||
|
||||
if len(numbers) == 0:
|
||||
msg = "No valid numbers provided."
|
||||
raise ValueError(msg)
|
||||
|
||||
if len(sys.argv) > len(numbers) + 1:
|
||||
with contextlib.suppress(ValueError):
|
||||
min_percentage = float(sys.argv[len(numbers) + 1])
|
||||
@ -2,7 +2,7 @@
|
||||
"""Analyze a chess game's moves using a local Stockfish engine and rate each move.
|
||||
|
||||
Usage:
|
||||
python3 PYTHON/analyze_chess_game.py <path-to-file>
|
||||
python3 python_pkg/analyze_chess_game.py <path-to-file>
|
||||
[--engine stockfish]
|
||||
[--time 0.5 | --depth 20]
|
||||
[--threads auto|N]
|
||||
@ -11,7 +11,7 @@ Usage:
|
||||
[--last-move-only]
|
||||
|
||||
Notes:
|
||||
- Requires python-chess. Install from PYTHON/stockfish_analysis/requirements.txt
|
||||
- Requires python-chess. Install from python_pkg/stockfish_analysis/requirements.txt
|
||||
- The input file can be a pure PGN or a log file containing a PGN section.
|
||||
- The script tries to locate the PGN by looking for a 'PGN:' marker,
|
||||
PGN tags '[...]', or a move list starting with '1.'.
|
||||
@ -41,7 +41,7 @@ try:
|
||||
import chess.pgn
|
||||
except Exception: # pragma: no cover
|
||||
logging.exception("Missing dependency. Please install python-chess:")
|
||||
logging.exception(" pip install -r PYTHON/stockfish_analysis/requirements.txt")
|
||||
logging.exception(" pip install -r python_pkg/stockfish_analysis/requirements.txt")
|
||||
raise
|
||||
|
||||
# Memory configuration constants
|
||||
@ -177,22 +177,20 @@ def _parse_hash_mb(value: str) -> int | None:
|
||||
def _detect_total_mem_mb() -> int | None:
|
||||
# Prefer psutil if available
|
||||
if psutil is not None:
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
return int(psutil.virtual_memory().total // (1024 * 1024))
|
||||
except Exception:
|
||||
pass
|
||||
# Fallback approach for Linux systems using proc meminfo.
|
||||
try:
|
||||
with open("/proc/meminfo", encoding="utf-8", errors="ignore") as f:
|
||||
for line in f:
|
||||
if line.startswith("MemTotal:"):
|
||||
parts = line.split()
|
||||
if len(parts) >= MEMINFO_PARTS_MIN and parts[1].isdigit():
|
||||
# Value is in kB
|
||||
kb = int(parts[1])
|
||||
return kb // 1024
|
||||
except Exception:
|
||||
pass
|
||||
with (
|
||||
contextlib.suppress(Exception),
|
||||
open("/proc/meminfo", encoding="utf-8", errors="ignore") as f,
|
||||
):
|
||||
for line in f:
|
||||
if line.startswith("MemTotal:"):
|
||||
parts = line.split()
|
||||
if len(parts) >= MEMINFO_PARTS_MIN and parts[1].isdigit():
|
||||
# Value is in kB
|
||||
kb = int(parts[1])
|
||||
return kb // 1024
|
||||
return None
|
||||
|
||||
|
||||
@ -320,7 +318,7 @@ def main() -> None:
|
||||
wanted_threads = max(wanted_threads, min_thr)
|
||||
engine.configure({"Threads": int(wanted_threads)})
|
||||
except Exception:
|
||||
pass
|
||||
logging.debug("Failed to configure Threads option")
|
||||
|
||||
# Configure hash table size in MB.
|
||||
if "Hash" in options:
|
||||
@ -338,7 +336,7 @@ def main() -> None:
|
||||
target_hash = max(target_hash, min_hash)
|
||||
engine.configure({"Hash": int(target_hash)})
|
||||
except Exception:
|
||||
pass
|
||||
logging.debug("Failed to configure Hash option")
|
||||
|
||||
# MultiPV
|
||||
effective_mpv = max(1, int(args.multipv))
|
||||
@ -349,7 +347,7 @@ def main() -> None:
|
||||
effective_mpv = min(effective_mpv, max_mpv)
|
||||
engine.configure({"MultiPV": int(effective_mpv)})
|
||||
except Exception:
|
||||
pass
|
||||
logging.debug("Failed to configure MultiPV option")
|
||||
|
||||
# Enable NNUE if the option exists
|
||||
for nnue_key in ("Use NNUE", "UseNNUE"):
|
||||
Loading…
Reference in New Issue
Block a user