# EU-Utility - Modern Python Packaging Configuration # https://github.com/ImpulsiveFPS/EU-Utility [build-system] requires = [ "setuptools>=65.0", "wheel>=0.41.0", "setuptools-scm>=7.0", ] build-backend = "setuptools.build_meta" [project] name = "eu-utility" version = "2.1.0" description = "A versatile Entropia Universe utility suite with a modular plugin system" readme = "README.md" license = {text = "MIT"} authors = [ {name = "ImpulsiveFPS", email = "dev@impulsivefps.com"}, ] maintainers = [ {name = "ImpulsiveFPS", email = "dev@impulsivefps.com"}, ] keywords = [ "entropia universe", "game utility", "overlay", "plugin system", "ocr", "tracker", "calculator", "gaming", "mmorpg", ] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: End Users/Desktop", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3 :: Only", "Topic :: Games/Entertainment", "Topic :: Utilities", "Topic :: Desktop Environment", "Environment :: X11 Applications :: Qt", "Environment :: Win32 (MS Windows)", "Natural Language :: English", ] requires-python = ">=3.11" dependencies = [ "PyQt6>=6.4.0,<7.0.0", "keyboard>=0.13.5,<1.0.0", "psutil>=5.9.0,<6.0.0", "pyperclip>=1.8.2,<2.0.0", "easyocr>=1.7.0,<2.0.0", "pytesseract>=0.3.10,<1.0.0", "pyautogui>=0.9.54,<1.0.0", "pillow>=10.0.0,<11.0.0", "requests>=2.28.0,<3.0.0", "urllib3>=1.26.0,<3.0.0", "numpy>=1.21.0,<2.0.0", 'portalocker>=2.7.0; platform_system=="Windows"', 'pywin32>=306; platform_system=="Windows"', ] [project.optional-dependencies] spotify = [ "spotipy>=2.23.0,<3.0.0", 'pycaw>=20230407; platform_system=="Windows"', ] discord = [ "pypresence>=4.3.0,<5.0.0", ] all = [ "spotipy>=2.23.0,<3.0.0", 'pycaw>=20230407; platform_system=="Windows"', "pypresence>=4.3.0,<5.0.0", ] dev = [ "pytest>=7.4.0,<8.0.0", "pytest-cov>=4.1.0,<5.0.0", "pytest-mock>=3.11.0,<4.0.0", "pytest-benchmark>=4.0.0,<5.0.0", "pytest-qt>=4.2.0,<5.0.0", "pytest-xvfb>=2.0.0,<3.0.0", "black>=23.0.0,<24.0.0", "flake8>=6.0.0,<7.0.0", "mypy>=1.5.0,<2.0.0", "isort>=5.12.0,<6.0.0", "pydocstyle>=6.3.0,<7.0.0", "bandit>=1.7.5,<2.0.0", "safety>=2.3.0,<3.0.0", "sphinx>=7.0.0,<8.0.0", "sphinx-rtd-theme>=1.3.0,<2.0.0", "myst-parser>=2.0.0,<3.0.0", "build>=0.10.0,<1.0.0", "twine>=4.0.0,<5.0.0", "wheel>=0.41.0,<1.0.0", "pre-commit>=3.4.0,<4.0.0", ] [project.scripts] eu-utility = "core.main:main" eu-utility-secure = "core.main_optimized:main" [project.gui-scripts] eu-utility-gui = "core.main:main" [project.urls] Homepage = "https://github.com/ImpulsiveFPS/EU-Utility" Documentation = "https://github.com/ImpulsiveFPS/EU-Utility/tree/main/docs" Repository = "https://github.com/ImpulsiveFPS/EU-Utility.git" "Bug Tracker" = "https://github.com/ImpulsiveFPS/EU-Utility/issues" Changelog = "https://github.com/ImpulsiveFPS/EU-Utility/blob/main/CHANGELOG.md" # ============================================================================= # TOOL CONFIGURATIONS # ============================================================================= # Black - Code Formatter [tool.black] line-length = 100 target-version = ["py311", "py312"] include = '\.pyi?$' extend-exclude = ''' /( \.git | \.venv | venv | env | build | dist | __pycache__ | \.pytest_cache | htmlcov | \.tox | migrations )/ ''' skip-string-normalization = false preview = false # isort - Import Sorting [tool.isort] profile = "black" line_length = 100 multi_line_output = 3 include_trailing_comma = true force_grid_wrap = 0 use_parentheses = true ensure_newline_before_comments = true skip = [".git", "__pycache__", "venv", ".venv", "build", "dist"] known_first_party = ["core", "plugins"] known_third_party = ["PyQt6", "pytest"] # flake8 - Linting [tool.flake8] max-line-length = 100 extend-ignore = [ "E203", # Whitespace before ':' (conflicts with black) "E501", # Line too long (handled by black) "W503", # Line break before binary operator (black style) ] exclude = [ ".git", "__pycache__", ".venv", "venv", "build", "dist", ".pytest_cache", "htmlcov", ".tox", "migrations", ] per-file-ignores = [ "__init__.py:F401,F403", "test_*.py:S101", ] max-complexity = 10 # mypy - Type Checking [tool.mypy] python_version = "3.11" warn_return_any = true warn_unused_configs = true disallow_untyped_defs = true disallow_incomplete_defs = true check_untyped_defs = true disallow_untyped_decorators = false no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true warn_no_return = true warn_unreachable = true strict_equality = true show_error_codes = true show_column_numbers = true show_error_context = true pretty = true # Module-specific settings [[tool.mypy.overrides]] module = [ "pytesseract.*", "pyautogui.*", "easyocr.*", "keyboard.*", "psutil.*", "PIL.*", "win32con.*", "win32gui.*", "win32api.*", "portalocker.*", ] ignore_missing_imports = true # pytest - Testing [tool.pytest.ini_options] testpaths = ["tests"] python_files = ["test_*.py"] python_classes = ["Test*"] python_functions = ["test_*"] addopts = [ "-v", "--tb=short", "--strict-markers", "--cov=core", "--cov=plugins", "--cov-report=term-missing", "--cov-report=html:htmlcov", "--cov-report=xml:coverage.xml", "--cov-fail-under=80", ] markers = [ "unit: Unit tests for individual components", "integration: Integration tests for plugin interactions", "ui: UI automation tests", "performance: Performance benchmarks", "slow: Slow tests that may be skipped in CI", "requires_qt: Tests requiring PyQt6", "requires_network: Tests requiring network access", ] filterwarnings = [ "ignore::DeprecationWarning", "ignore::PendingDeprecationWarning", ] # Coverage - Code Coverage [tool.coverage.run] source = ["core", "plugins"] branch = true omit = [ "*/tests/*", "*/test_*", "*/venv/*", "*/.venv/*", "setup.py", "run_tests.py", "code_review_report.py", "*/benchmarks/*", "*_vulnerable.py", ] [tool.coverage.report] exclude_lines = [ "pragma: no cover", "def __repr__", "if self.debug:", "if settings.DEBUG", "raise AssertionError", "raise NotImplementedError", "if 0:", "if __name__ == .__main__.:", "class .*\\bProtocol\\):", "@(abc\\.)?abstractmethod", "pass", ] fail_under = 80 show_missing = true skip_covered = false [tool.coverage.html] directory = "htmlcov" # Bandit - Security Linter [tool.bandit] exclude_dirs = [ "tests", "test", ".venv", "venv", "build", "dist", ] skips = [ "B101", # assert_used (common in Python code) "B311", # random (acceptable for non-cryptographic use) ] # Pydocstyle - Docstring Conventions [tool.pydocstyle] convention = "google" match = "(?!test_).*\\.py" match_dir = "^(?!tests|\\.venv|venv|build|dist).*" add_ignore = [ "D100", # Missing docstring in public module "D104", # Missing docstring in public package "D107", # Missing docstring in __init__ ] # setuptools - Package Discovery [tool.setuptools] packages = ["core", "core.*", "plugins", "plugins.*"] include-package-data = true zip-safe = false [tool.setuptools.package-data] core = ["*.json", "*.yaml", "*.yml", "*.css", "*.qss"] plugins = ["*/assets/*", "*/templates/*"] [tool.setuptools.exclude-package-data] core = ["tests/*", "*_test.py", "test_*.py"] plugins = ["tests/*", "*_test.py", "test_*.py"]