Use ruff instead of black+isort (#644)
* Use ruff * Update .gitignore * Format code * Use Ruff on generated code * Update pre-commit hook * Wrong commit * Remove wrong imports * Update hook * Format code * Target Python 3.8 * Reformat * Pin ruff version
This commit is contained in:
parent
37fa3abbac
commit
f41934a0e2
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,3 +18,4 @@ output
|
|||||||
.asv
|
.asv
|
||||||
venv
|
venv
|
||||||
.devcontainer
|
.devcontainer
|
||||||
|
.ruff_cache
|
@ -2,16 +2,13 @@ ci:
|
|||||||
autofix_prs: false
|
autofix_prs: false
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pycqa/isort
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: 5.11.5
|
rev: v0.7.4
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: ruff-format
|
||||||
|
args: ["--diff", "src", "tests"]
|
||||||
- repo: https://github.com/psf/black
|
- id: ruff
|
||||||
rev: 23.1.0
|
args: ["--select", "I", "src", "tests"]
|
||||||
hooks:
|
|
||||||
- id: black
|
|
||||||
args: ["--target-version", "py310"]
|
|
||||||
|
|
||||||
- repo: https://github.com/PyCQA/doc8
|
- repo: https://github.com/PyCQA/doc8
|
||||||
rev: 0.10.1
|
rev: 0.10.1
|
||||||
|
941
poetry.lock
generated
941
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -13,11 +13,11 @@ packages = [
|
|||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.8"
|
python = "^3.8"
|
||||||
black = { version = ">=23.1.0", optional = true }
|
# The Ruff version is pinned. To update it, also update it in .pre-commit-config.yaml
|
||||||
|
ruff = { version = "~0.7.4", optional = true }
|
||||||
grpclib = "^0.4.1"
|
grpclib = "^0.4.1"
|
||||||
jinja2 = { version = ">=3.0.3", optional = true }
|
jinja2 = { version = ">=3.0.3", optional = true }
|
||||||
python-dateutil = "^2.8"
|
python-dateutil = "^2.8"
|
||||||
isort = { version = "^5.11.5", optional = true }
|
|
||||||
typing-extensions = "^4.7.1"
|
typing-extensions = "^4.7.1"
|
||||||
betterproto-rust-codec = { version = "0.1.1", optional = true }
|
betterproto-rust-codec = { version = "0.1.1", optional = true }
|
||||||
|
|
||||||
@ -47,9 +47,16 @@ tomlkit = ">=0.7.0"
|
|||||||
protoc-gen-python_betterproto = "betterproto.plugin:main"
|
protoc-gen-python_betterproto = "betterproto.plugin:main"
|
||||||
|
|
||||||
[tool.poetry.extras]
|
[tool.poetry.extras]
|
||||||
compiler = ["black", "isort", "jinja2"]
|
compiler = ["ruff", "jinja2"]
|
||||||
rust-codec = ["betterproto-rust-codec"]
|
rust-codec = ["betterproto-rust-codec"]
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
extend-exclude = ["tests/output_*"]
|
||||||
|
target-version = "py38"
|
||||||
|
|
||||||
|
[tool.ruff.lint.isort]
|
||||||
|
combine-as-imports = true
|
||||||
|
lines-after-imports = 2
|
||||||
|
|
||||||
# Dev workflow tasks
|
# Dev workflow tasks
|
||||||
|
|
||||||
@ -65,13 +72,29 @@ help = "Run tests"
|
|||||||
cmd = "mypy src --ignore-missing-imports"
|
cmd = "mypy src --ignore-missing-imports"
|
||||||
help = "Check types with mypy"
|
help = "Check types with mypy"
|
||||||
|
|
||||||
[tool.poe.tasks]
|
|
||||||
_black = "black . --exclude tests/output_ --target-version py310"
|
|
||||||
_isort = "isort . --extend-skip-glob 'tests/output_*/**/*'"
|
|
||||||
|
|
||||||
[tool.poe.tasks.format]
|
[tool.poe.tasks.format]
|
||||||
sequence = ["_black", "_isort"]
|
sequence = ["_format", "_sort-imports"]
|
||||||
help = "Apply black and isort formatting to source code"
|
help = "Format the source code, and sort the imports"
|
||||||
|
|
||||||
|
[tool.poe.tasks.check]
|
||||||
|
sequence = ["_check-format", "_check-imports"]
|
||||||
|
help = "Check that the source code is formatted and the imports sorted"
|
||||||
|
|
||||||
|
[tool.poe.tasks._format]
|
||||||
|
cmd = "ruff format src tests"
|
||||||
|
help = "Format the source code without sorting the imports"
|
||||||
|
|
||||||
|
[tool.poe.tasks._sort-imports]
|
||||||
|
cmd = "ruff check --select I --fix src tests"
|
||||||
|
help = "Sort the imports"
|
||||||
|
|
||||||
|
[tool.poe.tasks._check-format]
|
||||||
|
cmd = "ruff format --diff src tests"
|
||||||
|
help = "Check that the source code is formatted"
|
||||||
|
|
||||||
|
[tool.poe.tasks._check-imports]
|
||||||
|
cmd = "ruff check --select I src tests"
|
||||||
|
help = "Check that the imports are sorted"
|
||||||
|
|
||||||
[tool.poe.tasks.docs]
|
[tool.poe.tasks.docs]
|
||||||
cmd = "sphinx-build docs docs/build"
|
cmd = "sphinx-build docs docs/build"
|
||||||
@ -106,23 +129,6 @@ help = "Regenerate the types in betterproto.lib.std.google"
|
|||||||
shell = "poe generate && tox"
|
shell = "poe generate && tox"
|
||||||
help = "Run tests with multiple pythons"
|
help = "Run tests with multiple pythons"
|
||||||
|
|
||||||
[tool.poe.tasks.check-style]
|
|
||||||
cmd = "black . --check --diff"
|
|
||||||
help = "Check if code style is correct"
|
|
||||||
|
|
||||||
[tool.isort]
|
|
||||||
py_version = 37
|
|
||||||
profile = "black"
|
|
||||||
force_single_line = false
|
|
||||||
combine_as_imports = true
|
|
||||||
lines_after_imports = 2
|
|
||||||
include_trailing_comma = true
|
|
||||||
force_grid_wrap = 2
|
|
||||||
src_paths = ["src", "tests"]
|
|
||||||
|
|
||||||
[tool.black]
|
|
||||||
target-version = ['py37']
|
|
||||||
|
|
||||||
[tool.doc8]
|
[tool.doc8]
|
||||||
paths = ["docs"]
|
paths = ["docs"]
|
||||||
max_line_length = 88
|
max_line_length = 88
|
||||||
|
@ -66,8 +66,7 @@ if sys.version_info >= (3, 10):
|
|||||||
from types import UnionType as _types_UnionType
|
from types import UnionType as _types_UnionType
|
||||||
else:
|
else:
|
||||||
|
|
||||||
class _types_UnionType:
|
class _types_UnionType: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# Proto 3 data types
|
# Proto 3 data types
|
||||||
|
@ -1204,9 +1204,9 @@ class EnumDescriptorProto(betterproto.Message):
|
|||||||
name: str = betterproto.string_field(1)
|
name: str = betterproto.string_field(1)
|
||||||
value: List["EnumValueDescriptorProto"] = betterproto.message_field(2)
|
value: List["EnumValueDescriptorProto"] = betterproto.message_field(2)
|
||||||
options: "EnumOptions" = betterproto.message_field(3)
|
options: "EnumOptions" = betterproto.message_field(3)
|
||||||
reserved_range: List[
|
reserved_range: List["EnumDescriptorProtoEnumReservedRange"] = (
|
||||||
"EnumDescriptorProtoEnumReservedRange"
|
betterproto.message_field(4)
|
||||||
] = betterproto.message_field(4)
|
)
|
||||||
"""
|
"""
|
||||||
Range of reserved numeric values. Reserved numeric values may not be used
|
Range of reserved numeric values. Reserved numeric values may not be used
|
||||||
by enum values in the same enum declaration. Reserved ranges may not
|
by enum values in the same enum declaration. Reserved ranges may not
|
||||||
@ -1792,9 +1792,9 @@ class FeatureSetDefaults(betterproto.Message):
|
|||||||
for the closest matching edition, followed by proto merges.
|
for the closest matching edition, followed by proto merges.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defaults: List[
|
defaults: List["FeatureSetDefaultsFeatureSetEditionDefault"] = (
|
||||||
"FeatureSetDefaultsFeatureSetEditionDefault"
|
betterproto.message_field(1)
|
||||||
] = betterproto.message_field(1)
|
)
|
||||||
minimum_edition: "Edition" = betterproto.enum_field(4)
|
minimum_edition: "Edition" = betterproto.enum_field(4)
|
||||||
"""
|
"""
|
||||||
The minimum supported edition (inclusive) when this was constructed.
|
The minimum supported edition (inclusive) when this was constructed.
|
||||||
|
@ -53,9 +53,9 @@ class CodeGeneratorRequest(betterproto.Message):
|
|||||||
parameter: str = betterproto.string_field(2)
|
parameter: str = betterproto.string_field(2)
|
||||||
"""The generator parameter passed on the command-line."""
|
"""The generator parameter passed on the command-line."""
|
||||||
|
|
||||||
proto_file: List[
|
proto_file: List["betterproto_lib_pydantic_google_protobuf.FileDescriptorProto"] = (
|
||||||
"betterproto_lib_pydantic_google_protobuf.FileDescriptorProto"
|
betterproto.message_field(15)
|
||||||
] = betterproto.message_field(15)
|
)
|
||||||
"""
|
"""
|
||||||
FileDescriptorProtos for all files in files_to_generate and everything
|
FileDescriptorProtos for all files in files_to_generate and everything
|
||||||
they import. The files will appear in topological order, so each file
|
they import. The files will appear in topological order, so each file
|
||||||
@ -195,9 +195,9 @@ class CodeGeneratorResponseFile(betterproto.Message):
|
|||||||
content: str = betterproto.string_field(15)
|
content: str = betterproto.string_field(15)
|
||||||
"""The file contents."""
|
"""The file contents."""
|
||||||
|
|
||||||
generated_code_info: (
|
generated_code_info: "betterproto_lib_pydantic_google_protobuf.GeneratedCodeInfo" = betterproto.message_field(
|
||||||
"betterproto_lib_pydantic_google_protobuf.GeneratedCodeInfo"
|
16
|
||||||
) = betterproto.message_field(16)
|
)
|
||||||
"""
|
"""
|
||||||
Information describing the file content being inserted. If an insertion
|
Information describing the file content being inserted. If an insertion
|
||||||
point is used, this information will be appropriately offset and inserted
|
point is used, this information will be appropriately offset and inserted
|
||||||
|
@ -1064,9 +1064,9 @@ class EnumDescriptorProto(betterproto.Message):
|
|||||||
name: str = betterproto.string_field(1)
|
name: str = betterproto.string_field(1)
|
||||||
value: List["EnumValueDescriptorProto"] = betterproto.message_field(2)
|
value: List["EnumValueDescriptorProto"] = betterproto.message_field(2)
|
||||||
options: "EnumOptions" = betterproto.message_field(3)
|
options: "EnumOptions" = betterproto.message_field(3)
|
||||||
reserved_range: List[
|
reserved_range: List["EnumDescriptorProtoEnumReservedRange"] = (
|
||||||
"EnumDescriptorProtoEnumReservedRange"
|
betterproto.message_field(4)
|
||||||
] = betterproto.message_field(4)
|
)
|
||||||
"""
|
"""
|
||||||
Range of reserved numeric values. Reserved numeric values may not be used
|
Range of reserved numeric values. Reserved numeric values may not be used
|
||||||
by enum values in the same enum declaration. Reserved ranges may not
|
by enum values in the same enum declaration. Reserved ranges may not
|
||||||
@ -1688,9 +1688,9 @@ class FeatureSetDefaults(betterproto.Message):
|
|||||||
for the closest matching edition, followed by proto merges.
|
for the closest matching edition, followed by proto merges.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defaults: List[
|
defaults: List["FeatureSetDefaultsFeatureSetEditionDefault"] = (
|
||||||
"FeatureSetDefaultsFeatureSetEditionDefault"
|
betterproto.message_field(1)
|
||||||
] = betterproto.message_field(1)
|
)
|
||||||
minimum_edition: "Edition" = betterproto.enum_field(4)
|
minimum_edition: "Edition" = betterproto.enum_field(4)
|
||||||
"""
|
"""
|
||||||
The minimum supported edition (inclusive) when this was constructed.
|
The minimum supported edition (inclusive) when this was constructed.
|
||||||
|
@ -46,9 +46,9 @@ class CodeGeneratorRequest(betterproto.Message):
|
|||||||
parameter: str = betterproto.string_field(2)
|
parameter: str = betterproto.string_field(2)
|
||||||
"""The generator parameter passed on the command-line."""
|
"""The generator parameter passed on the command-line."""
|
||||||
|
|
||||||
proto_file: List[
|
proto_file: List["betterproto_lib_google_protobuf.FileDescriptorProto"] = (
|
||||||
"betterproto_lib_google_protobuf.FileDescriptorProto"
|
betterproto.message_field(15)
|
||||||
] = betterproto.message_field(15)
|
)
|
||||||
"""
|
"""
|
||||||
FileDescriptorProtos for all files in files_to_generate and everything
|
FileDescriptorProtos for all files in files_to_generate and everything
|
||||||
they import. The files will appear in topological order, so each file
|
they import. The files will appear in topological order, so each file
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import os.path
|
import os.path
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .module_validation import ModuleValidator
|
from .module_validation import ModuleValidator
|
||||||
@ -6,8 +7,6 @@ from .module_validation import ModuleValidator
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# betterproto[compiler] specific dependencies
|
# betterproto[compiler] specific dependencies
|
||||||
import black
|
|
||||||
import isort.api
|
|
||||||
import jinja2
|
import jinja2
|
||||||
except ImportError as err:
|
except ImportError as err:
|
||||||
print(
|
print(
|
||||||
@ -40,20 +39,17 @@ def outputfile_compiler(output_file: OutputTemplate) -> str:
|
|||||||
|
|
||||||
code = body_template.render(output_file=output_file)
|
code = body_template.render(output_file=output_file)
|
||||||
code = header_template.render(output_file=output_file) + code
|
code = header_template.render(output_file=output_file) + code
|
||||||
code = isort.api.sort_code_string(
|
|
||||||
code=code,
|
# Sort imports, delete unused ones
|
||||||
show_diff=False,
|
code = subprocess.check_output(
|
||||||
py_version=37,
|
["ruff", "check", "--select", "I,F401", "--fix", "--silent", "-"],
|
||||||
profile="black",
|
input=code,
|
||||||
combine_as_imports=True,
|
encoding="utf-8",
|
||||||
lines_after_imports=2,
|
|
||||||
quiet=True,
|
|
||||||
force_grid_wrap=2,
|
|
||||||
known_third_party=["grpclib", "betterproto"],
|
|
||||||
)
|
)
|
||||||
code = black.format_str(
|
|
||||||
src_contents=code,
|
# Format the code
|
||||||
mode=black.Mode(),
|
code = subprocess.check_output(
|
||||||
|
["ruff", "format", "-"], input=code, encoding="utf-8"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Validate the generated code.
|
# Validate the generated code.
|
||||||
|
@ -621,9 +621,7 @@ iso_candidates = """2009-12-12T12:34
|
|||||||
2010-02-18T16:00:00.23334444
|
2010-02-18T16:00:00.23334444
|
||||||
2010-02-18T16:00:00,2283
|
2010-02-18T16:00:00,2283
|
||||||
2009-05-19 143922
|
2009-05-19 143922
|
||||||
2009-05-19 1439""".split(
|
2009-05-19 1439""".split("\n")
|
||||||
"\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_iso_datetime():
|
def test_iso_datetime():
|
||||||
|
@ -62,7 +62,7 @@ def test_load_varint_file():
|
|||||||
stream.read(2) # Skip until first multi-byte
|
stream.read(2) # Skip until first multi-byte
|
||||||
assert betterproto.load_varint(stream) == (
|
assert betterproto.load_varint(stream) == (
|
||||||
123456789,
|
123456789,
|
||||||
b"\x95\x9A\xEF\x3A",
|
b"\x95\x9a\xef\x3a",
|
||||||
) # Multi-byte varint
|
) # Multi-byte varint
|
||||||
|
|
||||||
|
|
||||||
@ -338,7 +338,7 @@ def run_java_single_varint(value: int, tmp_path) -> int:
|
|||||||
|
|
||||||
def test_single_varint(compile_jar, tmp_path):
|
def test_single_varint(compile_jar, tmp_path):
|
||||||
single_byte = (1, b"\x01")
|
single_byte = (1, b"\x01")
|
||||||
multi_byte = (123456789, b"\x95\x9A\xEF\x3A")
|
multi_byte = (123456789, b"\x95\x9a\xef\x3a")
|
||||||
|
|
||||||
# Write a single-byte varint to a file and have Java read it back
|
# Write a single-byte varint to a file and have Java read it back
|
||||||
returned = run_java_single_varint(single_byte[0], tmp_path)
|
returned = run_java_single_varint(single_byte[0], tmp_path)
|
||||||
@ -351,8 +351,8 @@ def test_single_varint(compile_jar, tmp_path):
|
|||||||
|
|
||||||
def test_multiple_varints(compile_jar, tmp_path):
|
def test_multiple_varints(compile_jar, tmp_path):
|
||||||
single_byte = (1, b"\x01")
|
single_byte = (1, b"\x01")
|
||||||
multi_byte = (123456789, b"\x95\x9A\xEF\x3A")
|
multi_byte = (123456789, b"\x95\x9a\xef\x3a")
|
||||||
over32 = (3000000000, b"\x80\xBC\xC1\x96\x0B")
|
over32 = (3000000000, b"\x80\xbc\xc1\x96\x0b")
|
||||||
|
|
||||||
# Write two varints to the same file
|
# Write two varints to the same file
|
||||||
with open(tmp_path / "py_multiple_varints.out", "wb") as stream:
|
with open(tmp_path / "py_multiple_varints.out", "wb") as stream:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user