diff --git a/pyproject.toml b/pyproject.toml index bb554a26b7..ff7d381234 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,8 @@ include = ['*.py', '*.recipe'] exclude = [ "*_ui.py", "bypy/*", - "setup/*", + "setup/polib.py", + "setup/linux-installer.py", "src/css_selectors/*", "src/polyglot/*", "src/templite/*", @@ -20,7 +21,7 @@ exclude = [ quote-style = 'single' [tool.ruff.lint] -ignore = ['E402', 'E722', 'E741', 'E401'] +ignore = ['E402', 'E722', 'E741'] select = ['E', 'F', 'I', 'W', 'INT'] [tool.ruff.lint.per-file-ignores] diff --git a/ruff-strict-pep8.toml b/ruff-strict-pep8.toml new file mode 100644 index 0000000000..5bcd7c87c8 --- /dev/null +++ b/ruff-strict-pep8.toml @@ -0,0 +1,38 @@ +line-length = 160 +target-version = 'py38' +builtins = ['_', 'I', 'P'] +include = ['*.py', '*.recipe'] +exclude = [ + "*_ui.py", + "bypy/*", + "setup/polib.py", + "setup/linux-installer.py", + "src/css_selectors/*", + "src/polyglot/*", + "src/templite/*", + "src/tinycss/*", +] + +[format] +quote-style = 'single' + +[lint] +ignore = ['E402', 'E722', 'E741'] +select = ['E', 'F', 'I', 'W', 'INT'] + +[lint.per-file-ignores] +"src/calibre/ebooks/unihandecode/*codepoints.py" = ['E501', 'W191'] +"src/qt/*.py" = ['I'] +"src/qt/*.pyi" = ['I'] + +[lint.isort] +detect-same-package = true +extra-standard-library = ["aes", "elementmaker", "encodings"] +known-first-party = ["calibre_extensions", "calibre_plugins", "polyglot"] +known-third-party = ["odf", "qt", "templite", "tinycss", "css_selectors"] +relative-imports-order = "closest-to-furthest" +split-on-trailing-comma = false +section-order = ['__python__', "future", "standard-library", "third-party", "first-party", "local-folder"] + +[lint.isort.sections] +'__python__' = ['__python__'] diff --git a/setup/check.py b/setup/check.py index 85dbffee18..b64876a6a5 100644 --- a/setup/check.py +++ b/setup/check.py @@ -23,15 +23,19 @@ class Message: return f'{self.filename}:{self.lineno}: {self.msg}' +def get_ruff_config(is_strict_check): + if is_strict_check: + return ['--config=ruff-strict-pep8.toml'] + else: + return [] + + def checkable_python_files(SRC): for dname in ('odf', 'calibre'): for x in os.walk(os.path.join(SRC, dname)): for f in x[-1]: y = os.path.join(x[0], f) - if (f.endswith('.py') and f not in ( - 'dict_data.py', 'unicodepoints.py', 'krcodepoints.py', - 'jacodepoints.py', 'vncodepoints.py', 'zhcodepoints.py') and - 'prs500/driver.py' not in y) and not f.endswith('_ui.py'): + if f.endswith('.py') and not f.endswith('_ui.py'): yield y @@ -40,12 +44,15 @@ class Check(Command): description = 'Check for errors in the calibre source code' CACHE = 'check.json' + CACHE_STRICT = 'check-strict.json' def add_options(self, parser): parser.add_option('--fix', '--auto-fix', default=False, action='store_true', help='Try to automatically fix some of the smallest errors') parser.add_option('--pep8', '--pep8-commit', default=False, action='store_true', help='Try to automatically fix some of the smallest errors, then perform a pep8 commit') + parser.add_option('--strict', '--strict-pep8', default=False, action='store_true', + help='Perform the checking more strictely. See the file "strict-pep8.toml"') def get_files(self): yield from checkable_python_files(self.SRC) @@ -80,7 +87,7 @@ class Check(Command): @property def cache_file(self): - return self.j(build_cache_dir(), self.CACHE) + return self.j(build_cache_dir(), self.CACHE_STRICT if self.is_strict_check else self.CACHE) def save_cache(self, cache): dump_json(cache, self.cache_file) @@ -88,8 +95,8 @@ class Check(Command): def file_has_errors(self, f): ext = os.path.splitext(f)[1] if ext in {'.py', '.recipe'}: - p2 = subprocess.Popen(['ruff', 'check', f]) - return p2.wait() != 0 + p = subprocess.Popen(['ruff', 'check', f] + get_ruff_config(self.is_strict_check)) + return p.wait() != 0 if ext == '.pyj': p = subprocess.Popen(['rapydscript', 'lint', f]) return p.wait() != 0 @@ -113,11 +120,15 @@ class Check(Command): if opts.fix and opts.pep8: self.info('setup.py check: error: options --fix and --pep8 are mutually exclusive') raise SystemExit(2) + if opts.strict and opts.pep8: + self.info('setup.py check: error: options --strict and --pep8 are mutually exclusive') + raise SystemExit(2) self.fhash_cache = {} self.wn_path = os.path.expanduser('~/work/srv/main/static') self.has_changelog_check = os.path.exists(self.wn_path) self.auto_fix = opts.fix + self.is_strict_check = opts.strict if opts.pep8: self.run_pep8_commit() else: @@ -167,11 +178,12 @@ class Check(Command): self.info('\t\t', str(err)) def clean(self): - try: - os.remove(self.cache_file) - except OSError as err: - if err.errno != errno.ENOENT: - raise + for cache_file in [self.j(build_cache_dir(), self.CACHE), self.j(build_cache_dir(), self.CACHE_STRICT)]: + try: + os.remove(cache_file) + except OSError as err: + if err.errno != errno.ENOENT: + raise class UpgradeSourceCode(Command):