diff --git a/pman/__init__.py b/pman/__init__.py index 1e1b78d..1797f1a 100644 --- a/pman/__init__.py +++ b/pman/__init__.py @@ -1,27 +1,34 @@ -#pylint: skip-file +# ruff: noqa: I001, PLC0414 + # Utilities from ._utils import ( - config_exists, - get_abs_path, - get_config, - get_config_plugins, - get_python_program, - get_rel_path, - run_script, - is_frozen, + config_exists as config_exists, + get_abs_path as get_abs_path, + get_config as get_config, + get_config_plugins as get_config_plugins, + get_python_program as get_python_program, + get_rel_path as get_rel_path, + is_frozen as is_frozen, + run_script as run_script, ) # Core functions +from ._build import build as build from ._core import ( - create_project, - run, - dist, - clean, + clean as clean, + create_project as create_project, + dist as dist, + run as run, ) -from ._build import build # Exceptions -from .exceptions import * +from .exceptions import ( + BuildError as BuildError, + ConfigError as ConfigError, + FrozenEnvironmentError as FrozenEnvironmentError, + NoConfigError as NoConfigError, + PManError as PManError, +) # Version -from .version import __version__ +from .version import __version__ as __version__ diff --git a/pman/_build.py b/pman/_build.py index 9706c2b..5b41df1 100644 --- a/pman/_build.py +++ b/pman/_build.py @@ -1,5 +1,6 @@ import collections import concurrent.futures +import contextlib import dataclasses import fnmatch import itertools @@ -10,7 +11,6 @@ import sys import time -# pylint: disable=redefined-builtin from rich import ( live, print, @@ -18,9 +18,7 @@ table, ) - from . import plugins -from .plugins.common import ConverterResult from ._utils import ( disallow_frozen, ensure_config, @@ -28,9 +26,10 @@ get_rel_path, run_hooks, ) +from .plugins.common import ConverterResult -def gather_files(srcdir, include_patterns, exclude_patterns, verbose=False): +def gather_files(srcdir, include_patterns, exclude_patterns, *, verbose=False): found_assets = [] for root, _dirs, files in os.walk(srcdir): for asset in files: @@ -152,7 +151,7 @@ def generate_explicit_streams(config, converters): verbose=verbose ) plugin_name = stream_configs['plugin'] - converter = converter_map.get(plugin_name, None) + converter = converter_map.get(plugin_name) if not converter: print( f'Failed to find plugin ({plugin_name}) for stream\n' @@ -236,7 +235,7 @@ def skip_build(converter, asset): ] skip = ( os.path.exists(dst) - and all((os.stat(i).st_mtime <= os.stat(dst).st_mtime for i in deps)) + and all(os.stat(i).st_mtime <= os.stat(dst).st_mtime for i in deps) ) if skip: if verbose: @@ -249,10 +248,10 @@ def skip_build(converter, asset): max_workers = None pool = concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) jobs = [] - for converter, assets, converter_config in streams: + for converter, stream_assets, converter_config in streams: assets = [ asset - for asset in assets + for asset in stream_assets if not skip_build(converter, asset) ] @@ -317,19 +316,17 @@ def update_progress(): for _, fut in jobs: for result in fut.result(): builddb[result.output_file] = result - except KeyboardInterrupt as exc: - for pid in pool._processes: # pylint: disable=protected-access - try: + except KeyboardInterrupt: + for pid in pool._processes: # noqa + with contextlib.suppress(ProcessLookupError): os.kill(pid, signal.SIGKILL) - except ProcessLookupError: - pass shutdown_args = { 'wait': False } if sys.version_info >= (3, 9): shutdown_args['cancel_futures'] = True pool.shutdown(**shutdown_args) - raise exc + raise with open(builddb_path, 'w', encoding='utf8') as builddb_file: json.dump([dataclasses.asdict(i) for i in builddb.values()], builddb_file) diff --git a/pman/_core.py b/pman/_core.py index 6407c89..64f24f5 100644 --- a/pman/_core.py +++ b/pman/_core.py @@ -1,17 +1,18 @@ +import contextlib import os import shlex import shutil -import tomli as toml +import tomli as toml from . import creationutils from ._build import build from ._utils import ( + disallow_frozen, + ensure_config, get_abs_path, get_config, get_config_plugins, - ensure_config, - disallow_frozen, run_hooks, run_script, ) @@ -41,7 +42,7 @@ def create_project(projectdir='.', extra_plugins=None): config = get_config(projectdir) for plugin in get_config_plugins(config, 'pre_create'): - getattr(plugin, 'pre_create')(config) + plugin.pre_create(config) creationutils.create_dirs(projectdir, ( config['build']['asset_dir'], @@ -56,11 +57,8 @@ def create_project(projectdir='.', extra_plugins=None): ('test_imports.py', 'tests/test_imports.py'), )) - for plugin in get_config_plugins(config, 'pre_post'): - getattr(plugin, 'pre_post')(config) - - - + for plugin in get_config_plugins(config, 'post_create'): + plugin.post_create(config) @ensure_config @@ -69,7 +67,7 @@ def create_project(projectdir='.', extra_plugins=None): def run(config=None): mainfile = get_abs_path(config, config['run']['main_file']) print(f'Running main file: {mainfile}') - args = [mainfile] + shlex.split(config['run']['extra_args']) + args = [mainfile, *shlex.split(config['run']['extra_args'])] run_script(config, args, cwd=config['internal']['projectdir']) @@ -153,7 +151,5 @@ def clean(config=None): shutil.rmtree(get_abs_path(config, export_dir), ignore_errors=True) shutil.rmtree(get_abs_path(config, 'build'), ignore_errors=True) shutil.rmtree(get_abs_path(config, 'dist'), ignore_errors=True) - try: + with contextlib.suppress(FileNotFoundError): os.unlink(get_abs_path(config, '.pman_builddb')) - except FileNotFoundError: - pass diff --git a/pman/_utils.py b/pman/_utils.py index e2ded50..b46d054 100644 --- a/pman/_utils.py +++ b/pman/_utils.py @@ -4,7 +4,7 @@ import subprocess import sys -from .import plugins +from . import plugins from .config import Config from .exceptions import ( ConfigError, @@ -63,7 +63,7 @@ def run_program(_config, args, cwd=None): def run_script(config, args, cwd=None): pyprog = get_python_program(config) - run_program(config, [pyprog] + args, cwd=cwd) + run_program(config, [pyprog, *args], cwd=cwd) def get_config_plugins(config, has_attr=None): @@ -128,7 +128,7 @@ def disallow_frozen(func): @functools.wraps(func) def wrapper(*args, **kwargs): if is_frozen(): - raise FrozenEnvironmentError() + raise FrozenEnvironmentError return func(*args, **kwargs) return wrapper diff --git a/pman/cli.py b/pman/cli.py index 815fc51..3149198 100644 --- a/pman/cli.py +++ b/pman/cli.py @@ -2,7 +2,6 @@ import subprocess import sys - import pman @@ -36,12 +35,6 @@ def test(_, config): def dist(args, config): pman.get_python_program(config) - try: - import direct.dist.commands #pylint:disable=unused-import,unused-variable - except ImportError: - print('Setuptools-based distribution is not supported by this version of Panda3D') - return - build_installers = None if args.skip_installers: build_installers = False diff --git a/pman/config.py b/pman/config.py index 16ca804..1aea665 100644 --- a/pman/config.py +++ b/pman/config.py @@ -1,13 +1,14 @@ +import functools +import os from dataclasses import ( dataclass, field, fields, is_dataclass, ) -import functools -import os from typing import ( Any, + ClassVar, ) import tomli as toml @@ -54,7 +55,7 @@ def __contains__(self, key): @dataclass class GeneralConfig(ConfigBase): - DEFAULT_PLUGINS = [ + DEFAULT_PLUGINS: ClassVar[list[str]] = [ 'native2bam', 'blend2bam', ] @@ -110,7 +111,7 @@ class InternalConfig(ConfigBase): @dataclass class Config(ConfigBase): - PROJECT_CONFIG_NAMES = [ + PROJECT_CONFIG_NAMES: ClassVar[list[str]] = [ 'pyproject.toml', '.pman', '.pman.user', diff --git a/pman/exceptions.py b/pman/exceptions.py index 2c715ad..fbffd01 100644 --- a/pman/exceptions.py +++ b/pman/exceptions.py @@ -1,23 +1,23 @@ -class PManException(Exception): +class PManError(Exception): pass -class NoConfigError(PManException): +class NoConfigError(PManError): pass -class ConfigError(PManException): +class ConfigError(PManError): pass -class CouldNotFindPythonError(PManException): +class CouldNotFindPythonError(PManError): pass -class BuildError(PManException): +class BuildError(PManError): pass -class FrozenEnvironmentError(PManException): +class FrozenEnvironmentError(PManError): def __init__(self): super().__init__("Operation not supported in frozen applications") diff --git a/pman/native2bam.py b/pman/native2bam.py index 04bfd1a..c180ac2 100644 --- a/pman/native2bam.py +++ b/pman/native2bam.py @@ -3,7 +3,6 @@ import panda3d.core as p3d - CONFIG_DATA = """ assimp-gen-normals true bam-texture-mode unchanged @@ -23,8 +22,8 @@ def make_texpath_relative(node, srcdir, converted_textures): continue texture.filename = os.path.relpath(texture.filename, srcdir) converted_textures.add(texture) - renderstate = renderstate.set_attrib(texattrib) - geomnode.set_geom_state(idx, renderstate) + newrenderstate = renderstate.set_attrib(texattrib) + geomnode.set_geom_state(idx, newrenderstate) diff --git a/pman/plugins/__init__.py b/pman/plugins/__init__.py index 178b0c0..5e65e87 100644 --- a/pman/plugins/__init__.py +++ b/pman/plugins/__init__.py @@ -13,7 +13,7 @@ def load_plugin(entrypoint): return plugin_class() eps = entry_points() - if isinstance(eps, dict): # Python 3.8 and 3.9 + if isinstance(eps, dict): # Python 3.8 and 3.9 # noqa: SIM108 plugins = eps.get('pman.plugins') else: plugins = eps.select(group='pman.plugins') diff --git a/pman/plugins/blend2bam.py b/pman/plugins/blend2bam.py index e1c86b2..1363637 100644 --- a/pman/plugins/blend2bam.py +++ b/pman/plugins/blend2bam.py @@ -1,12 +1,13 @@ +import os +import subprocess +import sys from dataclasses import ( dataclass, field, ) -import os -import subprocess -import sys from typing import ( Any, + ClassVar, Literal, ) @@ -15,8 +16,9 @@ ConverterResult, ) + class Blend2BamPlugin: - converters = [ + converters: ClassVar[list[ConverterInfo]] = [ ConverterInfo( name='blend2bam', supported_extensions=['.blend'], @@ -93,5 +95,5 @@ def convert(self, config, converter_config, srcdir, dstdir, assets): ] )) - proc.check_returncode() - return results + proc.check_returncode() + return results diff --git a/pman/plugins/common.py b/pman/plugins/common.py index 1a95c0b..9924fe7 100644 --- a/pman/plugins/common.py +++ b/pman/plugins/common.py @@ -1,7 +1,7 @@ import typing - from dataclasses import dataclass, field + @dataclass(frozen=True) class ConverterInfo: name: str diff --git a/pman/plugins/copyfile.py b/pman/plugins/copyfile.py index 719a496..7c0dfc3 100644 --- a/pman/plugins/copyfile.py +++ b/pman/plugins/copyfile.py @@ -1,5 +1,8 @@ import os import shutil +from typing import ( + ClassVar, +) from .common import ( ConverterInfo, @@ -8,7 +11,7 @@ class CopyFilePlugin: - converters = [ + converters: ClassVar[list[ConverterInfo]] = [ ConverterInfo( name='copyfile', supported_extensions=[], diff --git a/pman/plugins/native2bam.py b/pman/plugins/native2bam.py index f2e7f51..3153a51 100644 --- a/pman/plugins/native2bam.py +++ b/pman/plugins/native2bam.py @@ -1,11 +1,14 @@ import os import subprocess +from typing import ( + ClassVar, +) from .common import ConverterInfo class Native2BamPlugin: - converters = [ + converters: ClassVar[list[ConverterInfo]] = [ ConverterInfo( name='native2bam', supported_extensions=[ diff --git a/pman/setuptools.py b/pman/setuptools.py index 82b51f6..d86879f 100644 --- a/pman/setuptools.py +++ b/pman/setuptools.py @@ -1,6 +1,8 @@ import os + import tomli as toml + def finalize_distribution_options(dist): from ._utils import get_config diff --git a/pman/shim.py b/pman/shim.py index 0d7c852..91b8354 100644 --- a/pman/shim.py +++ b/pman/shim.py @@ -1,10 +1,10 @@ import panda3d.core as p3d +from ._build import build from ._utils import ( get_config, is_frozen, ) -from ._build import build def init(_base): diff --git a/pman/templates/main.py b/pman/templates/main.py index f0c2a98..352af86 100644 --- a/pman/templates/main.py +++ b/pman/templates/main.py @@ -1,9 +1,9 @@ import sys -from direct.showbase.ShowBase import ShowBase import panda3d -import pman.shim +from direct.showbase.ShowBase import ShowBase +import pman.shim panda3d.core.load_prc_file_data( '', diff --git a/pman/templates/test_imports.py b/pman/templates/test_imports.py index 91fdc2e..7ad2ec7 100644 --- a/pman/templates/test_imports.py +++ b/pman/templates/test_imports.py @@ -1,2 +1,2 @@ def test_imports(): - import panda3d.core #pylint: disable=unused-import + import panda3d.core #noqa: F401 diff --git a/pyproject.toml b/pyproject.toml index 65c3356..07d6aa0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,8 +35,8 @@ homepage = "https://github.com/Moguri/pman" test = [ "panda3d", "pytest", - "pylint~=2.17.0", - "pytest-pylint" + "ruff >= 0.4.0", + "pytest-ruff", ] [project.scripts] @@ -57,16 +57,17 @@ packages = ["pman"] [tool.setuptools.dynamic] version = {attr = "pman.version.__version__"} -[tool.pylint.main] -jobs = 0 +[tool.ruff] +target-version = "py38" +line-length = 100 -[tool.pylint."message control"] -disable = [ - "r", - "missing-docstring", - "import-outside-toplevel", - "unspecified-encoding", +[tool.ruff.lint] +select = [ + "E", "F", "W", "I", "N", "UP", "YTT", "ASYNC", "BLE", "FBT", + "B", "A", "C4", "DTZ", "ISC", "ICN", "PIE", "RSE", "RET", "SLF", + "SLOT", "SIM", "TID", "TCH", "TD", "FIX", "ERA", "PLC", "PLE", + "PLW", "PERF", "RUF" ] [tool.pytest.ini_options] -addopts = "--pylint --ignore=pman/templates/test_imports.py" +addopts = "--ruff --ignore=pman/templates/test_imports.py" diff --git a/tests/conftest.py b/tests/conftest.py index c1507d7..7bc25d6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,15 +4,13 @@ import pman -#pylint:disable=redefined-outer-name -#pylint:disable=unused-argument -@pytest.fixture +@pytest.fixture() def projectdir(tmpdir): pman.create_project(tmpdir.strpath) os.chdir(tmpdir.strpath) -@pytest.fixture +@pytest.fixture() def projectconf(projectdir): with open('.pman', 'w') as conffile: yield conffile diff --git a/tests/test_config.py b/tests/test_config.py index 08f56b3..a181114 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -4,8 +4,6 @@ import pman.config -#pylint:disable=unused-argument - def test_conf_read(tmpdir): os.chdir(tmpdir.strpath) open('.pman', 'w').close() @@ -81,7 +79,7 @@ def test_conf_missing(projectdir): assert config['python'] assert config.python assert config['blend2bam'] - assert config.blend2bam # pylint: disable=no-member + assert config.blend2bam assert config.plugins['blend2bam'] def test_dataclass_from_dict(): diff --git a/tests/test_pman.py b/tests/test_pman.py index 32c1f9d..c59f7c7 100644 --- a/tests/test_pman.py +++ b/tests/test_pman.py @@ -1,8 +1,6 @@ import pman import pman.shim -#pylint:disable=unused-argument - def test_create_project(projectdir): # projectdir already creates a project @@ -39,7 +37,7 @@ def test_run_args(projectdir): pman.run(config) - with open('tmp', 'r') as tmpfile: + with open('tmp') as tmpfile: assert tmpfile.read() == "['--test', 'hello world']" def test_shim(projectdir):