diff --git a/docs/conf.py b/docs/conf.py index cb605ff6a1..b7fce71c3d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -32,9 +32,7 @@ # Replace |version| in the docs with the actual version string. rst_epilog = """ .. |version| replace:: {version} -""".format( - version=version -) +""".format(version=version) # -- General configuration --------------------------------------------------- diff --git a/gapic/cli/generate.py b/gapic/cli/generate.py index e8eee1f034..e3b0a902ed 100644 --- a/gapic/cli/generate.py +++ b/gapic/cli/generate.py @@ -38,7 +38,7 @@ "--output", type=click.File("wb"), default=sys.stdout.buffer, - help="Where to output the `CodeGeneratorResponse`. " "Defaults to stdout.", + help="Where to output the `CodeGeneratorResponse`. Defaults to stdout.", ) def generate(request: typing.BinaryIO, output: typing.BinaryIO) -> None: """Generate a full API client description.""" diff --git a/gapic/generator/generator.py b/gapic/generator/generator.py index f42e40655e..e9e006e748 100644 --- a/gapic/generator/generator.py +++ b/gapic/generator/generator.py @@ -131,9 +131,7 @@ def get_response(self, api_schema: api.API, opts: Options) -> CodeGeneratorRespo ) # Return the CodeGeneratorResponse output. - res = CodeGeneratorResponse( - file=[i for i in output_files.values()] - ) # type: ignore + res = CodeGeneratorResponse(file=[i for i in output_files.values()]) # type: ignore res.supported_features |= CodeGeneratorResponse.Feature.FEATURE_PROTO3_OPTIONAL # type: ignore return res diff --git a/gapic/samplegen_utils/snippet_index.py b/gapic/samplegen_utils/snippet_index.py index 945b43e61f..2a4d752f3b 100644 --- a/gapic/samplegen_utils/snippet_index.py +++ b/gapic/samplegen_utils/snippet_index.py @@ -117,7 +117,9 @@ def __init__(self, api_schema: api.API): self.metadata_index.client_library.name = ( api_schema.naming.warehouse_package_name ) - self.metadata_index.client_library.language = snippet_metadata_pb2.Language.PYTHON # type: ignore + self.metadata_index.client_library.language = ( + snippet_metadata_pb2.Language.PYTHON # type: ignore + ) self.metadata_index.client_library.version = api_schema.gapic_version diff --git a/gapic/samplegen_utils/yaml.py b/gapic/samplegen_utils/yaml.py index bb558cb269..0d004254be 100644 --- a/gapic/samplegen_utils/yaml.py +++ b/gapic/samplegen_utils/yaml.py @@ -116,7 +116,9 @@ def get(self, key, default=None): return next( iter( [ - e.val for e in self.elements if e.key == key # type: ignore + e.val + for e in self.elements + if e.key == key # type: ignore ] # type: ignore ), default, diff --git a/gapic/schema/api.py b/gapic/schema/api.py index b05f6b6dec..4ee478a643 100644 --- a/gapic/schema/api.py +++ b/gapic/schema/api.py @@ -941,11 +941,7 @@ def enforce_valid_library_settings( selective_gapic_errors = {} # TODO(https://github.com/googleapis/gapic-generator-python/issues/2446): # Workaround issue in Python 3.14 related to code coverage by adding `# pragma: no branch` - for ( - method_name - ) in ( - library_settings.python_settings.common.selective_gapic_generation.methods - ): # pragma: no branch + for method_name in library_settings.python_settings.common.selective_gapic_generation.methods: # pragma: no branch if method_name not in self.all_methods: selective_gapic_errors[method_name] = "Method does not exist." elif not method_name.startswith(library_settings.version): @@ -1180,8 +1176,7 @@ def __init__( object.__setattr__(field, "enum", maybe_enum_type) else: raise TypeError( - f"Unknown type referenced in " - f"{self.file_descriptor.name}: '{key}'" + f"Unknown type referenced in {self.file_descriptor.name}: '{key}'" ) # Only generate the service if this is a target file to be generated. diff --git a/gapic/schema/metadata.py b/gapic/schema/metadata.py index 7df8d0291f..9fc6e43c30 100644 --- a/gapic/schema/metadata.py +++ b/gapic/schema/metadata.py @@ -356,7 +356,7 @@ def resolve(self, selector: str) -> str: str: An absolute selector. """ if "." not in selector: - return f'{".".join(self.package)}.{selector}' + return f"{'.'.join(self.package)}.{selector}" return selector def with_context(self, *, collisions: Set[str]) -> "Address": diff --git a/gapic/schema/naming.py b/gapic/schema/naming.py index ebf650944f..96b029664f 100644 --- a/gapic/schema/naming.py +++ b/gapic/schema/naming.py @@ -86,7 +86,7 @@ def build( "The protos provided do not share a common root package. " "Ensure that all explicitly-specified protos are for a " "single API. " - f'The packages we got are: {", ".join(proto_packages)}' + f"The packages we got are: {', '.join(proto_packages)}" ) # Define the valid regex to split the package. diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index 17a7832756..f228256742 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -797,7 +797,7 @@ def get_field( # Quick check: If this cursor has no message, there is a problem. if not cursor.message: raise KeyError( - f'Field {".".join(field_path)} could not be resolved from ' + f"Field {'.'.join(field_path)} could not be resolved from " f"{cursor.name}.", ) diff --git a/gapic/templates/noxfile.py.j2 b/gapic/templates/noxfile.py.j2 index 274ca368e0..3c07c9b6a8 100644 --- a/gapic/templates/noxfile.py.j2 +++ b/gapic/templates/noxfile.py.j2 @@ -12,8 +12,7 @@ import warnings import nox -BLACK_VERSION = "black[jupyter]==23.7.0" -ISORT_VERSION = "isort==5.11.0" +RUFF_VERSION = "ruff==0.14.14" {% if api.naming.module_namespace %} LINT_PATHS = ["docs", "{{ api.naming.module_namespace[0] }}", "tests", "noxfile.py", "setup.py"] @@ -147,12 +146,11 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - session.install("flake8", BLACK_VERSION) - session.run( - "black", - "--check", - *LINT_PATHS, - ) + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run("ruff", "format", "--check", "--line-length=88", *LINT_PATHS) + {% if api.naming.module_namespace %} session.run("flake8", "{{ api.naming.module_namespace[0] }}", "tests") @@ -163,30 +161,37 @@ def lint(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - session.run( - "black", - *LINT_PATHS, - ) + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log("WARNING: The 'blacken' session is deprecated and will be removed in the next release. Please use 'nox -s format' in the future.") + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run("ruff", "format", "--line-length=88", *LINT_PATHS) @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) diff --git a/noxfile.py b/noxfile.py index e99bfad597..98d8b44dc8 100644 --- a/noxfile.py +++ b/noxfile.py @@ -31,10 +31,12 @@ showcase_version = os.environ.get("SHOWCASE_VERSION", "0.35.0") ADS_TEMPLATES = path.join(path.dirname(__file__), "gapic", "ads-templates") -BLACK_VERSION = "black==25.1.0" -BLACK_PATHS = ["docs", "gapic", "tests", "test_utils", "noxfile.py", "setup.py"] -# exclude golden files and generated protobuf code -BLACK_EXCLUDES = "|".join([".*golden.*", ".*pb2.py"]) +RUFF_VERSION = "ruff==0.14.14" +LINT_PATHS = ["docs", "gapic", "tests", "test_utils", "noxfile.py", "setup.py"] +# Ruff uses globs for excludes (different from Black's regex) +# .*golden.* -> *golden* +# .*pb2.py -> *pb2.py +RUFF_EXCLUDES = "*golden*,*pb2.py,*pb2.pyi" ALL_PYTHON = ( "3.7", @@ -294,7 +296,7 @@ def showcase_library( } ] update_service_yaml = _add_python_settings(tmp_dir, python_settings) - session.run("python", "-c" f"{update_service_yaml}") + session.run("python", f"-c{update_service_yaml}") # END TODO section to remove. if retry_config: session.run( @@ -755,14 +757,19 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - session.install("flake8", BLACK_VERSION) + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting session.run( - "black", + "ruff", + "format", "--check", - *BLACK_PATHS, - "--extend-exclude", - BLACK_EXCLUDES, + *LINT_PATHS, + "--exclude", + RUFF_EXCLUDES, ) + + # 3. Run Flake8 session.run( "flake8", "gapic", @@ -772,11 +779,54 @@ def lint(session): @nox.session(python="3.10") def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) + """Run ruff format. + + DEPRECATED: This session now uses Ruff instead of Black. + It formats code style only (indentation, quotes, etc). + """ + session.log( + "WARNING: The 'blacken' session is deprecated and will be removed in the next release. Please use 'nox -s format' in the future." + ) + + session.install(RUFF_VERSION) + + # 1. Format Code (Replaces black) + # We do NOT run 'ruff check --select I' here, preserving strict parity. + session.run( + "ruff", + "format", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + "--exclude", + RUFF_EXCLUDES, + ) + + +@nox.session(python=NEWEST_PYTHON) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically + session.run( + "ruff", + "check", + "--select", + "I", + "--fix", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + # 3. Run Ruff to format code session.run( - "black", - *BLACK_PATHS, - "--extend-exclude", - BLACK_EXCLUDES, + "ruff", + "format", + "--line-length=88", # Standard Black line length + *LINT_PATHS, ) diff --git a/tests/integration/goldens/asset/noxfile.py b/tests/integration/goldens/asset/noxfile.py index 487acba725..1d395a7dfc 100755 --- a/tests/integration/goldens/asset/noxfile.py +++ b/tests/integration/goldens/asset/noxfile.py @@ -23,8 +23,7 @@ import nox -BLACK_VERSION = "black[jupyter]==23.7.0" -ISORT_VERSION = "isort==5.11.0" +RUFF_VERSION = "ruff==0.14.14" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -150,42 +149,47 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - session.install("flake8", BLACK_VERSION) - session.run( - "black", - "--check", - *LINT_PATHS, - ) + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run("ruff", "format", "--check", "--line-length=88", *LINT_PATHS) session.run("flake8", "google", "tests") @nox.session(python=DEFAULT_PYTHON_VERSION) def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - session.run( - "black", - *LINT_PATHS, - ) + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log("WARNING: The 'blacken' session is deprecated and will be removed in the next release. Please use 'nox -s format' in the future.") + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run("ruff", "format", "--line-length=88", *LINT_PATHS) @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) diff --git a/tests/integration/goldens/credentials/noxfile.py b/tests/integration/goldens/credentials/noxfile.py index af4ba3e285..462cce9248 100755 --- a/tests/integration/goldens/credentials/noxfile.py +++ b/tests/integration/goldens/credentials/noxfile.py @@ -23,8 +23,7 @@ import nox -BLACK_VERSION = "black[jupyter]==23.7.0" -ISORT_VERSION = "isort==5.11.0" +RUFF_VERSION = "ruff==0.14.14" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -150,42 +149,47 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - session.install("flake8", BLACK_VERSION) - session.run( - "black", - "--check", - *LINT_PATHS, - ) + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run("ruff", "format", "--check", "--line-length=88", *LINT_PATHS) session.run("flake8", "google", "tests") @nox.session(python=DEFAULT_PYTHON_VERSION) def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - session.run( - "black", - *LINT_PATHS, - ) + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log("WARNING: The 'blacken' session is deprecated and will be removed in the next release. Please use 'nox -s format' in the future.") + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run("ruff", "format", "--line-length=88", *LINT_PATHS) @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) diff --git a/tests/integration/goldens/eventarc/noxfile.py b/tests/integration/goldens/eventarc/noxfile.py index c718640903..cd7b4f82fe 100755 --- a/tests/integration/goldens/eventarc/noxfile.py +++ b/tests/integration/goldens/eventarc/noxfile.py @@ -23,8 +23,7 @@ import nox -BLACK_VERSION = "black[jupyter]==23.7.0" -ISORT_VERSION = "isort==5.11.0" +RUFF_VERSION = "ruff==0.14.14" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -150,42 +149,47 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - session.install("flake8", BLACK_VERSION) - session.run( - "black", - "--check", - *LINT_PATHS, - ) + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run("ruff", "format", "--check", "--line-length=88", *LINT_PATHS) session.run("flake8", "google", "tests") @nox.session(python=DEFAULT_PYTHON_VERSION) def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - session.run( - "black", - *LINT_PATHS, - ) + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log("WARNING: The 'blacken' session is deprecated and will be removed in the next release. Please use 'nox -s format' in the future.") + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run("ruff", "format", "--line-length=88", *LINT_PATHS) @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) diff --git a/tests/integration/goldens/logging/noxfile.py b/tests/integration/goldens/logging/noxfile.py index 8bf90a69f4..e43fa5b2fb 100755 --- a/tests/integration/goldens/logging/noxfile.py +++ b/tests/integration/goldens/logging/noxfile.py @@ -23,8 +23,7 @@ import nox -BLACK_VERSION = "black[jupyter]==23.7.0" -ISORT_VERSION = "isort==5.11.0" +RUFF_VERSION = "ruff==0.14.14" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -150,42 +149,47 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - session.install("flake8", BLACK_VERSION) - session.run( - "black", - "--check", - *LINT_PATHS, - ) + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run("ruff", "format", "--check", "--line-length=88", *LINT_PATHS) session.run("flake8", "google", "tests") @nox.session(python=DEFAULT_PYTHON_VERSION) def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - session.run( - "black", - *LINT_PATHS, - ) + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log("WARNING: The 'blacken' session is deprecated and will be removed in the next release. Please use 'nox -s format' in the future.") + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run("ruff", "format", "--line-length=88", *LINT_PATHS) @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) diff --git a/tests/integration/goldens/logging_internal/noxfile.py b/tests/integration/goldens/logging_internal/noxfile.py index 8bf90a69f4..e43fa5b2fb 100755 --- a/tests/integration/goldens/logging_internal/noxfile.py +++ b/tests/integration/goldens/logging_internal/noxfile.py @@ -23,8 +23,7 @@ import nox -BLACK_VERSION = "black[jupyter]==23.7.0" -ISORT_VERSION = "isort==5.11.0" +RUFF_VERSION = "ruff==0.14.14" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -150,42 +149,47 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - session.install("flake8", BLACK_VERSION) - session.run( - "black", - "--check", - *LINT_PATHS, - ) + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run("ruff", "format", "--check", "--line-length=88", *LINT_PATHS) session.run("flake8", "google", "tests") @nox.session(python=DEFAULT_PYTHON_VERSION) def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - session.run( - "black", - *LINT_PATHS, - ) + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log("WARNING: The 'blacken' session is deprecated and will be removed in the next release. Please use 'nox -s format' in the future.") + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run("ruff", "format", "--line-length=88", *LINT_PATHS) @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) diff --git a/tests/integration/goldens/redis/noxfile.py b/tests/integration/goldens/redis/noxfile.py index 4349f5147d..25a3ec57da 100755 --- a/tests/integration/goldens/redis/noxfile.py +++ b/tests/integration/goldens/redis/noxfile.py @@ -23,8 +23,7 @@ import nox -BLACK_VERSION = "black[jupyter]==23.7.0" -ISORT_VERSION = "isort==5.11.0" +RUFF_VERSION = "ruff==0.14.14" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -150,42 +149,47 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - session.install("flake8", BLACK_VERSION) - session.run( - "black", - "--check", - *LINT_PATHS, - ) + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run("ruff", "format", "--check", "--line-length=88", *LINT_PATHS) session.run("flake8", "google", "tests") @nox.session(python=DEFAULT_PYTHON_VERSION) def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - session.run( - "black", - *LINT_PATHS, - ) + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log("WARNING: The 'blacken' session is deprecated and will be removed in the next release. Please use 'nox -s format' in the future.") + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run("ruff", "format", "--line-length=88", *LINT_PATHS) @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) diff --git a/tests/integration/goldens/redis_selective/noxfile.py b/tests/integration/goldens/redis_selective/noxfile.py index 4349f5147d..25a3ec57da 100755 --- a/tests/integration/goldens/redis_selective/noxfile.py +++ b/tests/integration/goldens/redis_selective/noxfile.py @@ -23,8 +23,7 @@ import nox -BLACK_VERSION = "black[jupyter]==23.7.0" -ISORT_VERSION = "isort==5.11.0" +RUFF_VERSION = "ruff==0.14.14" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -150,42 +149,47 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - session.install("flake8", BLACK_VERSION) - session.run( - "black", - "--check", - *LINT_PATHS, - ) + session.install("flake8", RUFF_VERSION) + + # 2. Check formatting + session.run("ruff", "format", "--check", "--line-length=88", *LINT_PATHS) session.run("flake8", "google", "tests") @nox.session(python=DEFAULT_PYTHON_VERSION) def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - session.run( - "black", - *LINT_PATHS, - ) + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log("WARNING: The 'blacken' session is deprecated and will be removed in the next release. Please use 'nox -s format' in the future.") + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run("ruff", "format", "--line-length=88", *LINT_PATHS) @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + "--line-length=88", # Standard Black line length *LINT_PATHS, ) diff --git a/tests/system/test_lro.py b/tests/system/test_lro.py index ba7241c2de..c5722ed27d 100644 --- a/tests/system/test_lro.py +++ b/tests/system/test_lro.py @@ -37,7 +37,6 @@ def test_lro(echo): @pytest.mark.asyncio async def test_lro_async(async_echo): - future = await async_echo.wait( { "end_time": datetime.now(tz=timezone.utc) + timedelta(seconds=1), diff --git a/tests/unit/common_types.py b/tests/unit/common_types.py index d8f8375499..4ea17c6429 100644 --- a/tests/unit/common_types.py +++ b/tests/unit/common_types.py @@ -94,7 +94,7 @@ def __init__( options=False, ident=False, resource_path=False, - meta=None + meta=None, ): self.fields = fields self.type = type diff --git a/tests/unit/generator/test_formatter.py b/tests/unit/generator/test_formatter.py index 9d613c2b31..5a5e24d68e 100644 --- a/tests/unit/generator/test_formatter.py +++ b/tests/unit/generator/test_formatter.py @@ -18,10 +18,9 @@ def test_fix_whitespace_top_level(): - assert ( - formatter.fix_whitespace( - textwrap.dedent( - """\ + assert formatter.fix_whitespace( + textwrap.dedent( + """\ import something @@ -36,10 +35,9 @@ class TooFarDown: class TooClose: # remains too close pass """ - ) ) - == textwrap.dedent( - """\ + ) == textwrap.dedent( + """\ import something @@ -53,15 +51,13 @@ class TooFarDown: class TooClose: # remains too close pass """ - ) ) def test_fix_whitespace_nested(): - assert ( - formatter.fix_whitespace( - textwrap.dedent( - """\ + assert formatter.fix_whitespace( + textwrap.dedent( + """\ class JustAClass: def foo(self): pass @@ -70,10 +66,9 @@ def foo(self): def too_far_down(self): pass """ - ) ) - == textwrap.dedent( - """\ + ) == textwrap.dedent( + """\ class JustAClass: def foo(self): pass @@ -81,15 +76,13 @@ def foo(self): def too_far_down(self): pass """ - ) ) def test_fix_whitespace_decorators(): - assert ( - formatter.fix_whitespace( - textwrap.dedent( - """\ + assert formatter.fix_whitespace( + textwrap.dedent( + """\ class JustAClass: def foo(self): pass @@ -99,10 +92,9 @@ def foo(self): def too_far_down(self): return 42 """ - ) ) - == textwrap.dedent( - """\ + ) == textwrap.dedent( + """\ class JustAClass: def foo(self): pass @@ -111,15 +103,13 @@ def foo(self): def too_far_down(self): return 42 """ - ) ) def test_fix_whitespace_intermediate_whitespace(): - assert ( - formatter.fix_whitespace( - textwrap.dedent( - """\ + assert formatter.fix_whitespace( + textwrap.dedent( + """\ class JustAClass: def foo(self): pass @@ -130,10 +120,9 @@ def foo(self): def too_far_down(self): return 42 """ - ) ) - == textwrap.dedent( - """\ + ) == textwrap.dedent( + """\ class JustAClass: def foo(self): pass @@ -142,15 +131,13 @@ def foo(self): def too_far_down(self): return 42 """ - ) ) def test_fix_whitespace_comment(): - assert ( - formatter.fix_whitespace( - textwrap.dedent( - """\ + assert formatter.fix_whitespace( + textwrap.dedent( + """\ def do_something(): do_first_thing() @@ -158,17 +145,15 @@ def do_something(): # Something something something. do_second_thing() """ - ) ) - == textwrap.dedent( - """\ + ) == textwrap.dedent( + """\ def do_something(): do_first_thing() # Something something something. do_second_thing() """ - ) ) diff --git a/tests/unit/generator/test_generator.py b/tests/unit/generator/test_generator.py index 1e4578b516..9d8545c419 100644 --- a/tests/unit/generator/test_generator.py +++ b/tests/unit/generator/test_generator.py @@ -861,13 +861,13 @@ def make_api( *protos, naming: naming.Naming = None, service_yaml_config: service_pb2.Service = None, - **kwargs + **kwargs, ) -> api.API: return api.API( naming=naming or make_naming(), service_yaml_config=service_yaml_config or service_pb2.Service(), all_protos={i.name: i for i in protos}, - **kwargs + **kwargs, ) diff --git a/tests/unit/generator/test_options.py b/tests/unit/generator/test_options.py index 49ae6e216d..8b17aae911 100644 --- a/tests/unit/generator/test_options.py +++ b/tests/unit/generator/test_options.py @@ -161,7 +161,7 @@ def test_options_service_yaml_config(fs): service_yaml_fpath = "testapi_v2.yaml" fs.create_file( service_yaml_fpath, - contents=("config_version: 3\n" "name: testapi.googleapis.com\n"), + contents=("config_version: 3\nname: testapi.googleapis.com\n"), ) opt_string = f"service-yaml={service_yaml_fpath}" opts = Options.build(opt_string) diff --git a/tests/unit/schema/test_api.py b/tests/unit/schema/test_api.py index 300e8cab89..9d2dab2ec6 100644 --- a/tests/unit/schema/test_api.py +++ b/tests/unit/schema/test_api.py @@ -2611,16 +2611,16 @@ def test_mixin_api_methods_locations(): assert len(ms) == 2 m1 = ms["ListLocations"] m1.options.ClearExtension(annotations_pb2.http) - m1.options.Extensions[annotations_pb2.http].selector = ( - "google.cloud.location.Locations.ListLocations" - ) + m1.options.Extensions[ + annotations_pb2.http + ].selector = "google.cloud.location.Locations.ListLocations" m1.options.Extensions[annotations_pb2.http].get = "/v1/{name=examples/*}/*" m1.options.Extensions[annotations_pb2.http].body = "*" m2 = ms["GetLocation"] m2.options.ClearExtension(annotations_pb2.http) - m2.options.Extensions[annotations_pb2.http].selector = ( - "google.cloud.location.Locations.GetLocation" - ) + m2.options.Extensions[ + annotations_pb2.http + ].selector = "google.cloud.location.Locations.GetLocation" m2.options.Extensions[annotations_pb2.http].get = "/v1/{name=examples/*}/*" m2.options.Extensions[annotations_pb2.http].body = "*" api_schema = api.API.build(fd, "google.example.v1", opts=opts) @@ -3032,9 +3032,9 @@ def get_file_descriptor_proto_for_tests( """ field_options = descriptor_pb2.FieldOptions() - field_options.Extensions[field_info_pb2.field_info].format = ( - field_info_pb2.FieldInfo.Format.Value("UUID4") - ) + field_options.Extensions[ + field_info_pb2.field_info + ].format = field_info_pb2.FieldInfo.Format.Value("UUID4") fd = ( make_file_pb2( @@ -4213,9 +4213,9 @@ def test_read_method_settings_from_service_yaml(): } cli_options = Options(service_yaml_config=service_yaml_config) field_options = descriptor_pb2.FieldOptions() - field_options.Extensions[field_info_pb2.field_info].format = ( - field_info_pb2.FieldInfo.Format.Value("UUID4") - ) + field_options.Extensions[ + field_info_pb2.field_info + ].format = field_info_pb2.FieldInfo.Format.Value("UUID4") squid = make_field_pb2( name="squid", type="TYPE_STRING", options=field_options, number=1 @@ -4430,9 +4430,9 @@ def test_method_settings_unsupported_auto_populated_field_field_info_format_rais the format of the field is `IPV4`. """ field_options = descriptor_pb2.FieldOptions() - field_options.Extensions[field_info_pb2.field_info].format = ( - field_info_pb2.FieldInfo.Format.Value("IPV4") - ) + field_options.Extensions[ + field_info_pb2.field_info + ].format = field_info_pb2.FieldInfo.Format.Value("IPV4") squid = make_field_pb2( name="squid", type="TYPE_STRING", options=field_options, number=1 ) @@ -4461,9 +4461,9 @@ def test_method_settings_invalid_multiple_issues(): # - Not annotated with google.api.field_info.format = UUID4 # - Not of type string # - Required field - field_options.Extensions[field_info_pb2.field_info].format = ( - field_info_pb2.FieldInfo.Format.Value("IPV4") - ) + field_options.Extensions[ + field_info_pb2.field_info + ].format = field_info_pb2.FieldInfo.Format.Value("IPV4") squid = make_field_pb2( name="squid", type="TYPE_INT32", options=field_options, number=1 ) diff --git a/tests/unit/schema/wrappers/test_field.py b/tests/unit/schema/wrappers/test_field.py index dd8367c2ef..69f243ede8 100644 --- a/tests/unit/schema/wrappers/test_field.py +++ b/tests/unit/schema/wrappers/test_field.py @@ -143,9 +143,9 @@ def test_not_required(): def test_uuid4(): field = make_field() - field.options.Extensions[field_info_pb2.field_info].format = ( - field_info_pb2.FieldInfo.Format.Value("UUID4") - ) + field.options.Extensions[ + field_info_pb2.field_info + ].format = field_info_pb2.FieldInfo.Format.Value("UUID4") assert field.uuid4 @@ -186,9 +186,9 @@ def test_ident_sphinx_map(): def test_resource_reference(): field = make_field(type="TYPE_STRING") - field.options.Extensions[resource_pb2.resource_reference].type = ( - "translate.googleapis.com/Glossary" - ) + field.options.Extensions[ + resource_pb2.resource_reference + ].type = "translate.googleapis.com/Glossary" assert field.resource_reference == "translate.googleapis.com/Glossary" diff --git a/tests/unit/schema/wrappers/test_method.py b/tests/unit/schema/wrappers/test_method.py index 088958e06b..87eb959cb8 100644 --- a/tests/unit/schema/wrappers/test_method.py +++ b/tests/unit/schema/wrappers/test_method.py @@ -180,7 +180,8 @@ def test_method_paged_result_field_no_page_field(): method = make_method( name="Foo", input_message=make_message( - name="FooRequest", fields=(make_field(name="page_token", type=9),) # str + name="FooRequest", + fields=(make_field(name="page_token", type=9),), # str ), output_message=make_message( name="FooResponse",