Initial commit
This commit is contained in:
466
skills/python-code-quality/reference/pyright-configuration.md
Normal file
466
skills/python-code-quality/reference/pyright-configuration.md
Normal file
@@ -0,0 +1,466 @@
|
||||
## Pyright Configuration
|
||||
|
||||
Pyright offers flexible configuration options specified in a JSON-formatted text configuration. By default, the file is called “pyrightconfig.json” and is located within the root directory of your project. Multi-root workspaces (“Add Folder to Workspace…”) are supported, and each workspace root can have its own “pyrightconfig.json” file. For a sample pyrightconfig.json file, see [below](configuration.md#sample-config-file).
|
||||
|
||||
Pyright settings can also be specified in a `[tool.pyright]` section of a “pyproject.toml” file. A “pyrightconfig.json” file always takes precedent over “pyproject.toml” if both are present. For a sample pyproject.toml file, see [below](configuration.md#sample-pyprojecttoml-file).
|
||||
|
||||
Relative paths specified within the config file are relative to the config file’s location. Paths with shell variables (including `~`) are not supported. Paths within a config file should generally be relative paths so the config file can be shared by other developers who contribute to the project.
|
||||
|
||||
## Environment Options
|
||||
|
||||
The following settings control the *environment* in which Pyright will check for diagnostics. These settings determine how Pyright finds source files, imports, and what Python version specific rules are applied.
|
||||
|
||||
- **include** [array of paths, optional]: Paths of directories or files that should be considered part of the project. If no paths are specified, pyright defaults to the directory that contains the config file. Paths may contain wildcard characters ** (a directory or multiple levels of directories), * (a sequence of zero or more characters), or ? (a single character). If no include paths are specified, the root path for the workspace is assumed.
|
||||
|
||||
- **exclude** [array of paths, optional]: Paths of directories or files that should not be considered part of the project. These override the directories and files that `include` matched, allowing specific subdirectories to be excluded. Note that files in the exclude paths may still be included in the analysis if they are referenced (imported) by source files that are not excluded. Paths may contain wildcard characters ** (a directory or multiple levels of directories), * (a sequence of zero or more characters), or ? (a single character). If no exclude paths are specified, Pyright automatically excludes the following: `**/node_modules`, `**/__pycache__`, `**/.*`. Pylance also excludes any virtual environment directories regardless of the exclude paths specified. For more detail on Python environment specification and discovery, refer to the [import resolution](import-resolution.md#configuring-your-python-environment) documentation.
|
||||
|
||||
- **strict** [array of paths, optional]: Paths of directories or files that should use “strict” analysis if they are included. This is the same as manually adding a “# pyright: strict” comment. In strict mode, most type-checking rules are enabled. Refer to [this table](configuration.md#diagnostic-settings-defaults) for details about which rules are enabled in strict mode. Paths may contain wildcard characters ** (a directory or multiple levels of directories), * (a sequence of zero or more characters), or ? (a single character).
|
||||
|
||||
- **extends** [path, optional]: Path to another `.json` or `.toml` file that is used as a “base configuration”, allowing this configuration to inherit configuration settings. Top-level keys within this configuration overwrite top-level keys in the base configuration. Multiple levels of inheritance are supported. Relative paths specified in a configuration file are resolved relative to the location of that configuration file.
|
||||
|
||||
- **defineConstant** [map of constants to values (boolean or string), optional]: Set of identifiers that should be assumed to contain a constant value wherever used within this program. For example, `{ "DEBUG": true }` indicates that pyright should assume that the identifier `DEBUG` will always be equal to `True`. If this identifier is used within a conditional expression (such as `if not DEBUG:`) pyright will use the indicated value to determine whether the guarded block is reachable or not. Member expressions that reference one of these constants (e.g. `my_module.DEBUG`) are also supported.
|
||||
|
||||
- **typeshedPath** [path, optional]: Path to a directory that contains typeshed type stub files. Pyright ships with a bundled copy of typeshed type stubs. If you want to use a different version of typeshed stubs, you can clone the [typeshed github repo](https://github.com/python/typeshed) to a local directory and reference the location with this path. This option is useful if you’re actively contributing updates to typeshed.
|
||||
|
||||
- **stubPath** [path, optional]: Path to a directory that contains custom type stubs. Each package's type stub file(s) are expected to be in its own subdirectory. The default value of this setting is "./typings". (typingsPath is now deprecated)
|
||||
|
||||
- **venvPath** [path, optional]: Path to a directory containing one or more subdirectories, each of which contains a virtual environment. When used in conjunction with a **venv** setting (see below), pyright will search for imports in the virtual environment’s site-packages directory rather than the paths specified by the default Python interpreter. If you are working on a project with other developers, it is best not to specify this setting in the config file, since this path will typically differ for each developer. Instead, it can be specified on the command line or in a per-user setting. For more details, refer to the [import resolution](import-resolution.md#configuring-your-python-environment) documentation. This setting is ignored when using Pylance. VS Code's python interpreter path is used instead.
|
||||
|
||||
- **venv** [string, optional]: Used in conjunction with the venvPath, specifies the virtual environment to use. For more details, refer to the [import resolution](import-resolution.md#configuring-your-python-environment) documentation. This setting is ignored when using Pylance.
|
||||
|
||||
- **verboseOutput** [boolean]: Specifies whether output logs should be verbose. This is useful when diagnosing certain problems like import resolution issues.
|
||||
|
||||
- **extraPaths** [array of strings, optional]: Additional search paths that will be used when searching for modules imported by files.
|
||||
|
||||
- **pythonVersion** [string, optional]: Specifies the version of Python that will be used to execute the source code. The version should be specified as a string in the format "M.m" where M is the major version and m is the minor (e.g. `"3.0"` or `"3.6"`). If a version is provided, pyright will generate errors if the source code makes use of language features that are not supported in that version. It will also tailor its use of type stub files, which conditionalizes type definitions based on the version. If no version is specified, pyright will use the version of the current python interpreter, if one is present.
|
||||
|
||||
- **pythonPlatform** [string, optional]: Specifies the target platform that will be used to execute the source code. Should be one of `"Windows"`, `"Darwin"`, `"Linux"`, or `"All"`. If specified, pyright will tailor its use of type stub files, which conditionalize type definitions based on the platform. If no platform is specified, pyright will use the current platform.
|
||||
|
||||
- **executionEnvironments** [array of objects, optional]: Specifies a list of execution environments (see [below](configuration.md#execution-environment-options)). Execution environments are searched from start to finish by comparing the path of a source file with the root path specified in the execution environment.
|
||||
|
||||
- **useLibraryCodeForTypes** [boolean]: Determines whether pyright reads, parses and analyzes library code to extract type information in the absence of type stub files. Type information will typically be incomplete. We recommend using type stubs where possible. The default value for this option is true.
|
||||
|
||||
## Type Evaluation Settings
|
||||
|
||||
The following settings determine how different types should be evaluated.
|
||||
|
||||
- **strictListInference** [boolean]: When inferring the type of a list, use strict type assumptions. For example, the expression `[1, 'a', 3.4]` could be inferred to be of type `list[Any]` or `list[int | str | float]`. If this setting is true, it will use the latter (stricter) type. The default value for this setting is `false`.
|
||||
|
||||
- **strictDictionaryInference** [boolean]: When inferring the type of a dictionary’s keys and values, use strict type assumptions. For example, the expression `{'a': 1, 'b': 'a'}` could be inferred to be of type `dict[str, Any]` or `dict[str, int | str]`. If this setting is true, it will use the latter (stricter) type. The default value for this setting is `false`.
|
||||
|
||||
- **strictSetInference** [boolean]: When inferring the type of a set, use strict type assumptions. For example, the expression `{1, 'a', 3.4}` could be inferred to be of type `set[Any]` or `set[int | str | float]`. If this setting is true, it will use the latter (stricter) type. The default value for this setting is `false`.
|
||||
|
||||
- **analyzeUnannotatedFunctions** [boolean]: Analyze and report errors for functions and methods that have no type annotations for input parameters or return types. The default value for this setting is `true`.
|
||||
|
||||
- **strictParameterNoneValue** [boolean]: PEP 484 indicates that when a function parameter is assigned a default value of None, its type should implicitly be Optional even if the explicit type is not. When enabled, this rule requires that parameter type annotations use Optional explicitly in this case. The default value for this setting is `true`.
|
||||
|
||||
- **enableTypeIgnoreComments** [boolean]: PEP 484 defines support for "# type: ignore" comments. This switch enables or disables support for these comments. The default value for this setting is `true`. This does not affect "# pyright: ignore" comments.
|
||||
|
||||
- **deprecateTypingAliases** [boolean]: PEP 585 indicates that aliases to types in standard collections that were introduced solely to support generics are deprecated as of Python 3.9. This switch controls whether these are treated as deprecated. This applies only when pythonVersion is 3.9 or newer. The default value for this setting is `false` but may be switched to `true` in the future.
|
||||
|
||||
- **enableReachabilityAnalysis** [boolean]: If enabled, code that is determined to be unreachable by type analysis is reported using a tagged hint. This setting does not affect code that is determined to be unreachable independent of type analysis; such code is always reported as unreachable using a tagged hint. This setting also has no effect when using the command-line version of pyright because it never emits tagged hints for unreachable code.
|
||||
|
||||
- **enableExperimentalFeatures** [boolean]: Enables a set of experimental (mostly undocumented) features that correspond to proposed or exploratory changes to the Python typing standard. These features will likely change or be removed, so they should not be used except for experimentation purposes. The default value for this setting is `false`.
|
||||
|
||||
- **disableBytesTypePromotions** [boolean]: Disables legacy behavior where `bytearray` and `memoryview` are considered subtypes of `bytes`. [PEP 688](https://peps.python.org/pep-0688/#no-special-meaning-for-bytes) deprecates this behavior, but this switch is provided to restore the older behavior. The default value for this setting is `true`.
|
||||
|
||||
## Type Check Diagnostics Settings
|
||||
|
||||
The following settings control pyright’s diagnostic output (warnings or errors).
|
||||
|
||||
- **typeCheckingMode** ["off", "basic", "standard", "strict"]: Specifies the default rule set to use. Some rules can be overridden using additional configuration flags documented below. The default value for this setting is "standard". If set to "off", all type-checking rules are disabled, but Python syntax and semantic errors are still reported.
|
||||
|
||||
- **ignore** [array of paths, optional]: Paths of directories or files whose diagnostic output (errors and warnings) should be suppressed even if they are an included file or within the transitive closure of an included file. Paths may contain wildcard characters ** (a directory or multiple levels of directories), * (a sequence of zero or more characters), or ? (a single character). This setting can be overridden in VS code in your settings.json.
|
||||
|
||||
### Type Check Rule Overrides
|
||||
|
||||
The following settings allow more fine grained control over the **typeCheckingMode**. Unless otherwise specified, each diagnostic setting can specify a boolean value (`false` indicating that no error is generated and `true` indicating that an error is generated). Alternatively, a string value of `"none"`, `"warning"`, `"information"`, or `"error"` can be used to specify the diagnostic level.
|
||||
|
||||
- **reportGeneralTypeIssues** [boolean or string, optional]: Generate or suppress diagnostics for general type inconsistencies, unsupported operations, argument/parameter mismatches, etc. This covers all of the basic type-checking rules not covered by other rules. It does not include syntax errors. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportPropertyTypeMismatch** [boolean or string, optional]: Generate or suppress diagnostics for properties where the type of the value passed to the setter is not assignable to the value returned by the getter. Such mismatches violate the intended use of properties, which are meant to act like variables. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportFunctionMemberAccess** [boolean or string, optional]: Generate or suppress diagnostics for non-standard member accesses for functions. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportMissingImports** [boolean or string, optional]: Generate or suppress diagnostics for imports that have no corresponding imported python file or type stub file. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportMissingModuleSource** [boolean or string, optional]: Generate or suppress diagnostics for imports that have no corresponding source file. This happens when a type stub is found, but the module source file was not found, indicating that the code may fail at runtime when using this execution environment. Type checking will be done using the type stub. The default value for this setting is `"warning"`.
|
||||
|
||||
- **reportInvalidTypeForm** [boolean or string, optional]: Generate or suppress diagnostics for type annotations that use invalid type expression forms or are semantically invalid. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportMissingTypeStubs** [boolean or string, optional]: Generate or suppress diagnostics for imports that have no corresponding type stub file (either a typeshed file or a custom type stub). The type checker requires type stubs to do its best job at analysis. The default value for this setting is `"none"`. Note that there is a corresponding quick fix for this diagnostics that let you generate custom type stub to improve editing experiences.
|
||||
|
||||
- **reportImportCycles** [boolean or string, optional]: Generate or suppress diagnostics for cyclical import chains. These are not errors in Python, but they do slow down type analysis and often hint at architectural layering issues. Generally, they should be avoided. The default value for this setting is `"none"`. Note that there are import cycles in the typeshed stdlib typestub files that are ignored by this setting.
|
||||
|
||||
- **reportUnusedImport** [boolean or string, optional]: Generate or suppress diagnostics for an imported symbol that is not referenced within that file. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnusedClass** [boolean or string, optional]: Generate or suppress diagnostics for a class with a private name (starting with an underscore) that is not accessed. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnusedFunction** [boolean or string, optional]: Generate or suppress diagnostics for a function or method with a private name (starting with an underscore) that is not accessed. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnusedVariable** [boolean or string, optional]: Generate or suppress diagnostics for a variable that is not accessed. The default value for this setting is `"none"`. Variables whose names begin with an underscore are exempt from this check.
|
||||
|
||||
- **reportDuplicateImport** [boolean or string, optional]: Generate or suppress diagnostics for an imported symbol or module that is imported more than once. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportWildcardImportFromLibrary** [boolean or string, optional]: Generate or suppress diagnostics for a wildcard import from an external library. The use of this language feature is highly discouraged and can result in bugs when the library is updated. The default value for this setting is `"warning"`.
|
||||
|
||||
- **reportAbstractUsage** [boolean or string, optional]: Generate or suppress diagnostics for the attempted instantiate an abstract or protocol class or use of an abstract method. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportArgumentType** [boolean or string, optional]: Generate or suppress diagnostics for argument type incompatibilities when evaluating a call expression. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportAssertTypeFailure** [boolean or string, optional]: Generate or suppress diagnostics for a type mismatch detected by the `typing.assert_type` call. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportAssignmentType** [boolean or string, optional]: Generate or suppress diagnostics for assignment type incompatibility. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportAttributeAccessIssue** [boolean or string, optional]: Generate or suppress diagnostics related to attribute accesses. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportCallIssue** [boolean or string, optional]: Generate or suppress diagnostics related to call expressions and arguments passed to a call target. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportInconsistentOverload** [boolean or string, optional]: Generate or suppress diagnostics for an overloaded function that has overload signatures that are inconsistent with each other or with the implementation. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportIndexIssue** [boolean or string, optional]: Generate or suppress diagnostics related to index operations and expressions. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportInvalidTypeArguments** [boolean or string, optional]: Generate or suppress diagnostics for invalid type argument usage. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportNoOverloadImplementation** [boolean or string, optional]: Generate or suppress diagnostics for an overloaded function or method if the implementation is not provided. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportOperatorIssue** [boolean or string, optional]: Generate or suppress diagnostics related to the use of unary or binary operators (like `*` or `not`). The default value for this setting is `"error"`.
|
||||
|
||||
- **reportOptionalSubscript** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to subscript (index) a variable with an Optional type. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportOptionalMemberAccess** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to access a member of a variable with an Optional type. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportOptionalCall** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to call a variable with an Optional type. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportOptionalIterable** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to use an Optional type as an iterable value (e.g. within a `for` statement). The default value for this setting is `"error"`.
|
||||
|
||||
- **reportOptionalContextManager** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to use an Optional type as a context manager (as a parameter to a `with` statement). The default value for this setting is `"error"`.
|
||||
|
||||
- **reportOptionalOperand** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to use an Optional type as an operand to a unary operator (like `~`) or the left-hand operator of a binary operator (like `*` or `<<`). The default value for this setting is `"error"`.
|
||||
|
||||
- **reportRedeclaration** [boolean or string, optional]: Generate or suppress diagnostics for a symbol that has more than one type declaration. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportReturnType** [boolean or string, optional]: Generate or suppress diagnostics related to function return type compatibility. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportTypedDictNotRequiredAccess** [boolean or string, optional]: Generate or suppress diagnostics for an attempt to access a non-required field within a TypedDict without first checking whether it is present. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportUntypedFunctionDecorator** [boolean or string, optional]: Generate or suppress diagnostics for function decorators that have no type annotations. These obscure the function type, defeating many type analysis features. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUntypedClassDecorator** [boolean or string, optional]: Generate or suppress diagnostics for class decorators that have no type annotations. These obscure the class type, defeating many type analysis features. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUntypedBaseClass** [boolean or string, optional]: Generate or suppress diagnostics for base classes whose type cannot be determined statically. These obscure the class type, defeating many type analysis features. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUntypedNamedTuple** [boolean or string, optional]: Generate or suppress diagnostics when “namedtuple” is used rather than “NamedTuple”. The former contains no type information, whereas the latter does. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportPrivateUsage** [boolean or string, optional]: Generate or suppress diagnostics for incorrect usage of private or protected variables or functions. Protected class members begin with a single underscore (“_”) and can be accessed only by subclasses. Private class members begin with a double underscore but do not end in a double underscore and can be accessed only within the declaring class. Variables and functions declared outside of a class are considered private if their names start with either a single or double underscore, and they cannot be accessed outside of the declaring module. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportTypeCommentUsage** [boolean or string, optional]: Prior to Python 3.5, the grammar did not support type annotations, so types needed to be specified using “type comments”. Python 3.5 eliminated the need for function type comments, and Python 3.6 eliminated the need for variable type comments. Future versions of Python will likely deprecate all support for type comments. If enabled, this check will flag any type comment usage unless it is required for compatibility with the specified language version. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportPrivateImportUsage** [boolean or string, optional]: Generate or suppress diagnostics for use of a symbol from a "py.typed" module that is not meant to be exported from that module. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportConstantRedefinition** [boolean or string, optional]: Generate or suppress diagnostics for attempts to redefine variables whose names are all-caps with underscores and numerals. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportDeprecated** [boolean or string, optional]: Generate or suppress diagnostics for use of a class or function that has been marked as deprecated. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportIncompatibleMethodOverride** [boolean or string, optional]: Generate or suppress diagnostics for methods that override a method of the same name in a base class in an incompatible manner (wrong number of parameters, incompatible parameter types, or incompatible return type). The default value for this setting is `"error"`.
|
||||
|
||||
- **reportIncompatibleVariableOverride** [boolean or string, optional]: Generate or suppress diagnostics for class variable declarations that override a symbol of the same name in a base class with a type that is incompatible with the base class symbol type. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportInconsistentConstructor** [boolean or string, optional]: Generate or suppress diagnostics when an `__init__` method signature is inconsistent with a `__new__` signature. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportOverlappingOverload** [boolean or string, optional]: Generate or suppress diagnostics for function overloads that overlap in signature and obscure each other or have incompatible return types. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportPossiblyUnboundVariable** [boolean or string, optional]: Generate or suppress diagnostics for variables that are possibly unbound on some code paths. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportMissingSuperCall** [boolean or string, optional]: Generate or suppress diagnostics for `__init__`, `__init_subclass__`, `__enter__` and `__exit__` methods in a subclass that fail to call through to the same-named method on a base class. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUninitializedInstanceVariable** [boolean or string, optional]: Generate or suppress diagnostics for instance variables within a class that are not initialized or declared within the class body or the `__init__` method. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportInvalidStringEscapeSequence** [boolean or string, optional]: Generate or suppress diagnostics for invalid escape sequences used within string literals. The Python specification indicates that such sequences will generate a syntax error in future versions. The default value for this setting is `"warning"`.
|
||||
|
||||
- **reportUnknownParameterType** [boolean or string, optional]: Generate or suppress diagnostics for input or return parameters for functions or methods that have an unknown type. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnknownArgumentType** [boolean or string, optional]: Generate or suppress diagnostics for call arguments for functions or methods that have an unknown type. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnknownLambdaType** [boolean or string, optional]: Generate or suppress diagnostics for input or return parameters for lambdas that have an unknown type. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnknownVariableType** [boolean or string, optional]: Generate or suppress diagnostics for variables that have an unknown type. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnknownMemberType** [boolean or string, optional]: Generate or suppress diagnostics for class or instance variables that have an unknown type. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportMissingParameterType** [boolean or string, optional]: Generate or suppress diagnostics for input parameters for functions or methods that are missing a type annotation. The `self` and `cls` parameters used within methods are exempt from this check. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportMissingTypeArgument** [boolean or string, optional]: Generate or suppress diagnostics when a generic class is used without providing explicit or implicit type arguments. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportInvalidTypeVarUse** [boolean or string, optional]: Generate or suppress diagnostics when a TypeVar is used inappropriately (e.g. if a TypeVar appears only once) within a generic function signature. The default value for this setting is `"warning"`.
|
||||
|
||||
- **reportCallInDefaultInitializer** [boolean or string, optional]: Generate or suppress diagnostics for function calls, list expressions, set expressions, or dictionary expressions within a default value initialization expression. Such calls can mask expensive operations that are performed at module initialization time. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnnecessaryIsInstance** [boolean or string, optional]: Generate or suppress diagnostics for `isinstance` or `issubclass` calls where the result is statically determined to be always true or always false. Such calls are often indicative of a programming error. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnnecessaryCast** [boolean or string, optional]: Generate or suppress diagnostics for `cast` calls that are statically determined to be unnecessary. Such calls are sometimes indicative of a programming error. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnnecessaryComparison** [boolean or string, optional]: Generate or suppress diagnostics for `==` or `!=` comparisons or other conditional expressions that are statically determined to always evaluate to False or True. Such comparisons are sometimes indicative of a programming error. The default value for this setting is `"none"`. Also reports `case` clauses in a `match` statement that can be statically determined to never match (with exception of the `_` wildcard pattern, which is exempted).
|
||||
|
||||
- **reportUnnecessaryContains** [boolean or string, optional]: Generate or suppress diagnostics for `in` operations that are statically determined to always evaluate to False or True. Such operations are sometimes indicative of a programming error. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportAssertAlwaysTrue** [boolean or string, optional]: Generate or suppress diagnostics for `assert` statement that will provably always assert because its first argument is a parenthesized tuple (for example, `assert (v > 0, "Bad value")` when the intent was probably `assert v > 0, "Bad value"`). This is a common programming error. The default value for this setting is `"warning"`.
|
||||
|
||||
- **reportSelfClsParameterName** [boolean or string, optional]: Generate or suppress diagnostics for a missing or misnamed “self” parameter in instance methods and “cls” parameter in class methods. Instance methods in metaclasses (classes that derive from “type”) are allowed to use “cls” for instance methods. The default value for this setting is `"warning"`.
|
||||
|
||||
- **reportImplicitStringConcatenation** [boolean or string, optional]: Generate or suppress diagnostics for two or more string literals that follow each other, indicating an implicit concatenation. This is considered a bad practice and often masks bugs such as missing commas. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUndefinedVariable** [boolean or string, optional]: Generate or suppress diagnostics for undefined variables. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportUnboundVariable** [boolean or string, optional]: Generate or suppress diagnostics for unbound variables. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportUnhashable** [boolean or string, optional]: Generate or suppress diagnostics for the use of an unhashable object in a container that requires hashability. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportInvalidStubStatement** [boolean or string, optional]: Generate or suppress diagnostics for statements that are syntactically correct but have no purpose within a type stub file. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportIncompleteStub** [boolean or string, optional]: Generate or suppress diagnostics for a module-level `__getattr__` call in a type stub file, indicating that it is incomplete. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnsupportedDunderAll** [boolean or string, optional]: Generate or suppress diagnostics for statements that define or manipulate `__all__` in a way that is not allowed by a static type checker, thus rendering the contents of `__all__` to be unknown or incorrect. Also reports names within the `__all__` list that are not present in the module namespace. The default value for this setting is `"warning"`.
|
||||
|
||||
- **reportUnusedCallResult** [boolean or string, optional]: Generate or suppress diagnostics for call statements whose return value is not used in any way and is not None. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnusedCoroutine** [boolean or string, optional]: Generate or suppress diagnostics for call statements whose return value is not used in any way and is a Coroutine. This identifies a common error where an `await` keyword is mistakenly omitted. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportUnusedExcept** [boolean or string, optional]: Generate or suppress diagnostics for an `except` clause that will never be reached. The default value for this setting is `"error"`.
|
||||
|
||||
- **reportUnusedExpression** [boolean or string, optional]: Generate or suppress diagnostics for simple expressions whose results are not used in any way. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnnecessaryTypeIgnoreComment** [boolean or string, optional]: Generate or suppress diagnostics for a `# type: ignore` or `# pyright: ignore` comment that would have no effect if removed. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportMatchNotExhaustive** [boolean or string, optional]: Generate or suppress diagnostics for a `match` statement that does not provide cases that exhaustively match against all potential types of the target expression. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportUnreachable** [boolean or string, optional]: Generate or suppress diagnostics for code that is determined to be structurally unreachable or unreachable by type analysis. The default value for this setting is `"none"`.
|
||||
|
||||
- **reportImplicitOverride** [boolean or string, optional]: Generate or suppress diagnostics for overridden methods in a class that are missing an explicit `@override` decorator. The default value for this setting is `"none"`.
|
||||
|
||||
## Execution Environment Options
|
||||
|
||||
Pyright allows multiple “execution environments” to be defined for different portions of your source tree. For example, a subtree may be designed to run with different import search paths or a different version of the python interpreter than the rest of the source base.
|
||||
|
||||
The following settings can be specified for each execution environment. Each source file within a project is associated with at most one execution environment -- the first one whose root directory contains that file.
|
||||
|
||||
- **root** [string, required]: Root path for the code that will execute within this execution environment.
|
||||
|
||||
- **extraPaths** [array of strings, optional]: Additional search paths (in addition to the root path) that will be used when searching for modules imported by files within this execution environment. If specified, this overrides the default extraPaths setting when resolving imports for files within this execution environment. Note that each file’s execution environment mapping is independent, so if file A is in one execution environment and imports a second file B within a second execution environment, any imports from B will use the extraPaths in the second execution environment.
|
||||
|
||||
- **pythonVersion** [string, optional]: The version of Python used for this execution environment. If not specified, the global `pythonVersion` setting is used instead.
|
||||
|
||||
- **pythonPlatform** [string, optional]: Specifies the target platform that will be used for this execution environment. If not specified, the global `pythonPlatform` setting is used instead.
|
||||
|
||||
In addition, any of the [type check diagnostics settings](configuration.md#type-check-diagnostics-settings) listed above can be specified. These settings act as overrides for the files in this execution environment.
|
||||
|
||||
## Sample Config File
|
||||
|
||||
The following is an example of a pyright config file:
|
||||
|
||||
```json
|
||||
{
|
||||
"include": [
|
||||
"src"
|
||||
],
|
||||
|
||||
"exclude": [
|
||||
"**/node_modules",
|
||||
"**/__pycache__",
|
||||
"src/experimental",
|
||||
"src/typestubs"
|
||||
],
|
||||
|
||||
"ignore": [
|
||||
"src/oldstuff"
|
||||
],
|
||||
|
||||
"defineConstant": {
|
||||
"DEBUG": true
|
||||
},
|
||||
|
||||
"stubPath": "src/stubs",
|
||||
|
||||
"reportMissingImports": "error",
|
||||
"reportMissingTypeStubs": false,
|
||||
|
||||
"pythonVersion": "3.6",
|
||||
"pythonPlatform": "Linux",
|
||||
|
||||
"executionEnvironments": [
|
||||
{
|
||||
"root": "src/web",
|
||||
"pythonVersion": "3.5",
|
||||
"pythonPlatform": "Windows",
|
||||
"extraPaths": [
|
||||
"src/service_libs"
|
||||
],
|
||||
"reportMissingImports": "warning"
|
||||
},
|
||||
{
|
||||
"root": "src/sdk",
|
||||
"pythonVersion": "3.0",
|
||||
"extraPaths": [
|
||||
"src/backend"
|
||||
]
|
||||
},
|
||||
{
|
||||
"root": "src/tests",
|
||||
"extraPaths": [
|
||||
"src/tests/e2e",
|
||||
"src/sdk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"root": "src"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Sample pyproject.toml File
|
||||
|
||||
```toml
|
||||
[tool.pyright]
|
||||
include = ["src"]
|
||||
exclude = ["**/node_modules",
|
||||
"**/__pycache__",
|
||||
"src/experimental",
|
||||
"src/typestubs"
|
||||
]
|
||||
ignore = ["src/oldstuff"]
|
||||
defineConstant = { DEBUG = true }
|
||||
stubPath = "src/stubs"
|
||||
|
||||
reportMissingImports = "error"
|
||||
reportMissingTypeStubs = false
|
||||
|
||||
pythonVersion = "3.6"
|
||||
pythonPlatform = "Linux"
|
||||
|
||||
executionEnvironments = [
|
||||
{ root = "src/web", pythonVersion = "3.5", pythonPlatform = "Windows", extraPaths = [ "src/service_libs" ], reportMissingImports = "warning" },
|
||||
{ root = "src/sdk", pythonVersion = "3.0", extraPaths = [ "src/backend" ] },
|
||||
{ root = "src/tests", extraPaths = ["src/tests/e2e", "src/sdk" ]},
|
||||
{ root = "src" }
|
||||
]
|
||||
```
|
||||
|
||||
## Diagnostic Settings Defaults
|
||||
|
||||
Each diagnostic setting has a default that is dictated by the specified type checking mode. The default for each rule can be overridden in the configuration file or settings. In strict type checking mode, overrides may only increase the strictness (e.g. increase the severity level from `"warning"` to `"error"`).
|
||||
|
||||
The following table lists the default severity levels for each diagnostic rule within each type checking mode (`"off"`, `"basic"`, `"standard"` and `"strict"`).
|
||||
|
||||
| Diagnostic Rule | Off | Basic | Standard | Strict |
|
||||
| :---------------------------------------- | :--------- | :--------- | :--------- | :--------- |
|
||||
| analyzeUnannotatedFunctions | true | true | true | true |
|
||||
| disableBytesTypePromotions | true | true | true | true |
|
||||
| strictParameterNoneValue | true | true | true | true |
|
||||
| enableTypeIgnoreComments | true | true | true | true |
|
||||
| enableReachabilityAnalysis | false | true | true | true |
|
||||
| strictListInference | false | false | false | true |
|
||||
| strictDictionaryInference | false | false | false | true |
|
||||
| strictSetInference | false | false | false | true |
|
||||
| deprecateTypingAliases | false | false | false | false |
|
||||
| enableExperimentalFeatures | false | false | false | false |
|
||||
| reportMissingTypeStubs | "none" | "none" | "none" | "error" |
|
||||
| reportMissingModuleSource | "warning" | "warning" | "warning" | "warning" |
|
||||
| reportInvalidTypeForm | "warning" | "error" | "error" | "error" |
|
||||
| reportMissingImports | "warning" | "error" | "error" | "error" |
|
||||
| reportUndefinedVariable | "warning" | "error" | "error" | "error" |
|
||||
| reportAssertAlwaysTrue | "none" | "warning" | "warning" | "error" |
|
||||
| reportInvalidStringEscapeSequence | "none" | "warning" | "warning" | "error" |
|
||||
| reportInvalidTypeVarUse | "none" | "warning" | "warning" | "error" |
|
||||
| reportSelfClsParameterName | "none" | "warning" | "warning" | "error" |
|
||||
| reportUnsupportedDunderAll | "none" | "warning" | "warning" | "error" |
|
||||
| reportUnusedExpression | "none" | "warning" | "warning" | "error" |
|
||||
| reportWildcardImportFromLibrary | "none" | "warning" | "warning" | "error" |
|
||||
| reportAbstractUsage | "none" | "error" | "error" | "error" |
|
||||
| reportArgumentType | "none" | "error" | "error" | "error" |
|
||||
| reportAssertTypeFailure | "none" | "error" | "error" | "error" |
|
||||
| reportAssignmentType | "none" | "error" | "error" | "error" |
|
||||
| reportAttributeAccessIssue | "none" | "error" | "error" | "error" |
|
||||
| reportCallIssue | "none" | "error" | "error" | "error" |
|
||||
| reportGeneralTypeIssues | "none" | "error" | "error" | "error" |
|
||||
| reportInconsistentOverload | "none" | "error" | "error" | "error" |
|
||||
| reportIndexIssue | "none" | "error" | "error" | "error" |
|
||||
| reportInvalidTypeArguments | "none" | "error" | "error" | "error" |
|
||||
| reportNoOverloadImplementation | "none" | "error" | "error" | "error" |
|
||||
| reportOperatorIssue | "none" | "error" | "error" | "error" |
|
||||
| reportOptionalSubscript | "none" | "error" | "error" | "error" |
|
||||
| reportOptionalMemberAccess | "none" | "error" | "error" | "error" |
|
||||
| reportOptionalCall | "none" | "error" | "error" | "error" |
|
||||
| reportOptionalIterable | "none" | "error" | "error" | "error" |
|
||||
| reportOptionalContextManager | "none" | "error" | "error" | "error" |
|
||||
| reportOptionalOperand | "none" | "error" | "error" | "error" |
|
||||
| reportRedeclaration | "none" | "error" | "error" | "error" |
|
||||
| reportReturnType | "none" | "error" | "error" | "error" |
|
||||
| reportTypedDictNotRequiredAccess | "none" | "error" | "error" | "error" |
|
||||
| reportPrivateImportUsage | "none" | "error" | "error" | "error" |
|
||||
| reportUnboundVariable | "none" | "error" | "error" | "error" |
|
||||
| reportUnhashable | "none" | "error" | "error" | "error" |
|
||||
| reportUnusedCoroutine | "none" | "error" | "error" | "error" |
|
||||
| reportUnusedExcept | "none" | "error" | "error" | "error" |
|
||||
| reportFunctionMemberAccess | "none" | "none" | "error" | "error" |
|
||||
| reportIncompatibleMethodOverride | "none" | "none" | "error" | "error" |
|
||||
| reportIncompatibleVariableOverride | "none" | "none" | "error" | "error" |
|
||||
| reportOverlappingOverload | "none" | "none" | "error" | "error" |
|
||||
| reportPossiblyUnboundVariable | "none" | "none" | "error" | "error" |
|
||||
| reportConstantRedefinition | "none" | "none" | "none" | "error" |
|
||||
| reportDeprecated | "none" | "none" | "none" | "error" |
|
||||
| reportDuplicateImport | "none" | "none" | "none" | "error" |
|
||||
| reportIncompleteStub | "none" | "none" | "none" | "error" |
|
||||
| reportInconsistentConstructor | "none" | "none" | "none" | "error" |
|
||||
| reportInvalidStubStatement | "none" | "none" | "none" | "error" |
|
||||
| reportMatchNotExhaustive | "none" | "none" | "none" | "error" |
|
||||
| reportMissingParameterType | "none" | "none" | "none" | "error" |
|
||||
| reportMissingTypeArgument | "none" | "none" | "none" | "error" |
|
||||
| reportPrivateUsage | "none" | "none" | "none" | "error" |
|
||||
| reportTypeCommentUsage | "none" | "none" | "none" | "error" |
|
||||
| reportUnknownArgumentType | "none" | "none" | "none" | "error" |
|
||||
| reportUnknownLambdaType | "none" | "none" | "none" | "error" |
|
||||
| reportUnknownMemberType | "none" | "none" | "none" | "error" |
|
||||
| reportUnknownParameterType | "none" | "none" | "none" | "error" |
|
||||
| reportUnknownVariableType | "none" | "none" | "none" | "error" |
|
||||
| reportUnnecessaryCast | "none" | "none" | "none" | "error" |
|
||||
| reportUnnecessaryComparison | "none" | "none" | "none" | "error" |
|
||||
| reportUnnecessaryContains | "none" | "none" | "none" | "error" |
|
||||
| reportUnnecessaryIsInstance | "none" | "none" | "none" | "error" |
|
||||
| reportUnusedClass | "none" | "none" | "none" | "error" |
|
||||
| reportUnusedImport | "none" | "none" | "none" | "error" |
|
||||
| reportUnusedFunction | "none" | "none" | "none" | "error" |
|
||||
| reportUnusedVariable | "none" | "none" | "none" | "error" |
|
||||
| reportUntypedBaseClass | "none" | "none" | "none" | "error" |
|
||||
| reportUntypedClassDecorator | "none" | "none" | "none" | "error" |
|
||||
| reportUntypedFunctionDecorator | "none" | "none" | "none" | "error" |
|
||||
| reportUntypedNamedTuple | "none" | "none" | "none" | "error" |
|
||||
| reportCallInDefaultInitializer | "none" | "none" | "none" | "none" |
|
||||
| reportImplicitOverride | "none" | "none" | "none" | "none" |
|
||||
| reportImplicitStringConcatenation | "none" | "none" | "none" | "none" |
|
||||
| reportImportCycles | "none" | "none" | "none" | "none" |
|
||||
| reportMissingSuperCall | "none" | "none" | "none" | "none" |
|
||||
| reportPropertyTypeMismatch | "none" | "none" | "none" | "none" |
|
||||
| reportUninitializedInstanceVariable | "none" | "none" | "none" | "none" |
|
||||
| reportUnnecessaryTypeIgnoreComment | "none" | "none" | "none" | "none" |
|
||||
| reportUnreachable | "none" | "none" | "none" | "none" |
|
||||
| reportUnusedCallResult | "none" | "none" | "none" | "none" |
|
||||
|
||||
## Overriding settings (in VS Code)
|
||||
|
||||
If a pyproject.toml (with a pyright section) or a pyrightconfig.json exists, any pyright settings in a VS Code settings.json will be ignored. Pyrightconfig.json is prescribing the environment to be used for a particular project. Changing the environment configuration options per user is not supported.
|
||||
|
||||
If a pyproject.toml (with a pyright section) or a pyrightconfig.json does not exist, then the VS Code settings.json settings apply.
|
||||
|
||||
## Locale Configuration
|
||||
|
||||
Pyright provides diagnostic messages that are translated to multiple languages. By default, pyright uses the default locale of the operating system. You can override the desired locale through the use of one of the following environment variables, listed in priority order.
|
||||
|
||||
```text
|
||||
LC_ALL="de"
|
||||
LC_MESSAGES="en-us"
|
||||
LANG="zh-cn"
|
||||
LANGUAGE="fr"
|
||||
```
|
||||
|
||||
When running in VS Code, the editor's locale takes precedence. Setting these environment variables applies only when using pyright outside of VS Code.
|
||||
895
skills/python-code-quality/reference/ruff-configuration.md
Normal file
895
skills/python-code-quality/reference/ruff-configuration.md
Normal file
@@ -0,0 +1,895 @@
|
||||
# Configuring Ruff
|
||||
|
||||
Ruff can be configured through a `pyproject.toml`, `ruff.toml`, or `.ruff.toml` file.
|
||||
|
||||
Whether you're using Ruff as a linter, formatter, or both, the underlying configuration strategy and
|
||||
semantics are the same.
|
||||
|
||||
For a complete enumeration of the available configuration options, see [_Settings_](settings.md).
|
||||
|
||||
If left unspecified, Ruff's default configuration is equivalent to:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff]
|
||||
# Exclude a variety of commonly ignored directories.
|
||||
exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".ipynb_checkpoints",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pyenv",
|
||||
".pytest_cache",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
".vscode",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"build",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
"venv",
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
## Same as Black. # Same as Black
|
||||
|
||||
line-length = 88
|
||||
indent-width = 4
|
||||
|
||||
```text
|
||||
# Assume Python 3.9 # Assume Python 3.9
|
||||
target-version = "py39"
|
||||
|
||||
```
|
||||
|
||||
[tool.ruff.lint] [tool.ruff.lint]
|
||||
|
||||
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
|
||||
|
||||
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
|
||||
|
||||
# McCabe complexity (`C901`) by default.
|
||||
|
||||
select = ["E4", "E7", "E9", "F"]
|
||||
ignore = []
|
||||
|
||||
```text
|
||||
# Allow fix for all enabled rules (when `--fix`) is provided. # Allow fix for all enabled rules (when `--fix`) is provided.
|
||||
fixable = ["ALL"]
|
||||
unfixable = []
|
||||
|
||||
```
|
||||
|
||||
## Allow unused variables when underscore-prefixed. # Allow unused variables when underscore-prefixed
|
||||
|
||||
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
||||
|
||||
```text
|
||||
[tool.ruff.format] [tool.ruff.format]
|
||||
# Like Black, use double quotes for strings.
|
||||
quote-style = "double"
|
||||
|
||||
```
|
||||
|
||||
## Like Black, indent with spaces, rather than tabs. # Like Black, indent with spaces, rather than tabs
|
||||
|
||||
indent-style = "space"
|
||||
|
||||
```text
|
||||
# Like Black, respect magic trailing commas. # Like Black, respect magic trailing commas.
|
||||
skip-magic-trailing-comma = false
|
||||
|
||||
```
|
||||
|
||||
## Like Black, automatically detect the appropriate line ending. # Like Black, automatically detect the appropriate line ending
|
||||
|
||||
line-ending = "auto"
|
||||
|
||||
```text
|
||||
# Enable auto-formatting of code examples in docstrings. Markdown, # Enable auto-formatting of code examples in docstrings. Markdown,
|
||||
# reStructuredText code/literal blocks and doctests are all supported.
|
||||
#
|
||||
# This is currently disabled by default, but it is planned for this
|
||||
# to be opt-out in the future.
|
||||
docstring-code-format = false
|
||||
|
||||
```
|
||||
|
||||
## Set the line length limit used when formatting code snippets in # Set the line length limit used when formatting code snippets in
|
||||
|
||||
# docstrings.
|
||||
|
||||
# This only has an effect when the `docstring-code-format` setting is
|
||||
# enabled.
|
||||
docstring-code-line-length = "dynamic"
|
||||
|
||||
```text
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```
|
||||
|
||||
```toml
|
||||
# Exclude a variety of commonly ignored directories.
|
||||
exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".ipynb_checkpoints",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pyenv",
|
||||
".pytest_cache",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
".vscode",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"build",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
"venv",
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
# Same as Black. # Same as Black.
|
||||
line-length = 88
|
||||
indent-width = 4
|
||||
|
||||
```text
|
||||
|
||||
## Assume Python 3.9 # Assume Python 3.9
|
||||
|
||||
target-version = "py39"
|
||||
|
||||
```
|
||||
|
||||
[lint] [lint]
|
||||
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
|
||||
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
|
||||
# McCabe complexity (`C901`) by default.
|
||||
select = ["E4", "E7", "E9", "F"]
|
||||
ignore = []
|
||||
|
||||
```text
|
||||
|
||||
## Allow fix for all enabled rules (when `--fix`) is provided. # Allow fix for all enabled rules (when `--fix`) is provided
|
||||
|
||||
fixable = ["ALL"]
|
||||
unfixable = []
|
||||
|
||||
```
|
||||
|
||||
# Allow unused variables when underscore-prefixed. # Allow unused variables when underscore-prefixed.
|
||||
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
||||
|
||||
```text
|
||||
[format] [format]
|
||||
|
||||
# Like Black, use double quotes for strings.
|
||||
|
||||
quote-style = "double"
|
||||
|
||||
```
|
||||
|
||||
# Like Black, indent with spaces, rather than tabs. # Like Black, indent with spaces, rather than tabs.
|
||||
indent-style = "space"
|
||||
|
||||
```text
|
||||
|
||||
## Like Black, respect magic trailing commas. # Like Black, respect magic trailing commas
|
||||
|
||||
skip-magic-trailing-comma = false
|
||||
|
||||
```
|
||||
|
||||
# Like Black, automatically detect the appropriate line ending. # Like Black, automatically detect the appropriate line ending.
|
||||
line-ending = "auto"
|
||||
|
||||
```text
|
||||
|
||||
## Enable auto-formatting of code examples in docstrings. Markdown, # Enable auto-formatting of code examples in docstrings. Markdown
|
||||
|
||||
# reStructuredText code/literal blocks and doctests are all supported.
|
||||
|
||||
# This is currently disabled by default, but it is planned for this
|
||||
# to be opt-out in the future.
|
||||
docstring-code-format = false
|
||||
|
||||
```
|
||||
|
||||
# Set the line length limit used when formatting code snippets in # Set the line length limit used when formatting code snippets in
|
||||
# docstrings.
|
||||
#
|
||||
# This only has an effect when the `docstring-code-format` setting is
|
||||
# enabled.
|
||||
docstring-code-line-length = "dynamic"
|
||||
|
||||
```text
|
||||
|
||||
As an example, the following would configure Ruff to:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.lint]
|
||||
# 1. Enable flake8-bugbear (`B`) rules, in addition to the defaults.
|
||||
select = ["E4", "E7", "E9", "F", "B"]
|
||||
|
||||
```
|
||||
|
||||
## 2. Avoid enforcing line-length violations (`E501`) # 2. Avoid enforcing line-length violations (`E501`)
|
||||
|
||||
ignore = ["E501"]
|
||||
|
||||
```text
|
||||
# 3. Avoid trying to fix flake8-bugbear (`B`) violations. # 3. Avoid trying to fix flake8-bugbear (`B`) violations.
|
||||
unfixable = ["B"]
|
||||
|
||||
```
|
||||
|
||||
## 4. Ignore `E402` (import violations) in all `__init__.py` files, and in selected subdirectories. # 4. Ignore `E402` (import violations) in all `__init__.py` files, and in selected subdirectories
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"__init__.py" = ["E402"]
|
||||
"**/{tests,docs,tools}/*" = ["E402"]
|
||||
|
||||
```text
|
||||
[tool.ruff.format] [tool.ruff.format]
|
||||
# 5. Use single quotes in `ruff format`.
|
||||
quote-style = "single"
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[lint]
|
||||
# 1. Enable flake8-bugbear (`B`) rules, in addition to the defaults.
|
||||
select = ["E4", "E7", "E9", "F", "B"]
|
||||
|
||||
```
|
||||
|
||||
## 2. Avoid enforcing line-length violations (`E501`) # 2. Avoid enforcing line-length violations (`E501`)
|
||||
|
||||
ignore = ["E501"]
|
||||
|
||||
```text
|
||||
# 3. Avoid trying to fix flake8-bugbear (`B`) violations. # 3. Avoid trying to fix flake8-bugbear (`B`) violations.
|
||||
unfixable = ["B"]
|
||||
|
||||
```
|
||||
|
||||
## 4. Ignore `E402` (import violations) in all `__init__.py` files, and in selected subdirectories. # 4. Ignore `E402` (import violations) in all `__init__.py` files, and in selected subdirectories
|
||||
|
||||
[lint.per-file-ignores]
|
||||
"__init__.py" = ["E402"]
|
||||
"**/{tests,docs,tools}/*" = ["E402"]
|
||||
|
||||
```text
|
||||
[format] [format]
|
||||
# 5. Use single quotes in `ruff format`.
|
||||
quote-style = "single"
|
||||
```
|
||||
|
||||
Linter plugin configurations are expressed as subsections, e.g.:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.lint]
|
||||
# Add "Q" to the list of enabled codes.
|
||||
select = ["E4", "E7", "E9", "F", "Q"]
|
||||
|
||||
```
|
||||
|
||||
[tool.ruff.lint.flake8-quotes] [tool.ruff.lint.flake8-quotes]
|
||||
docstring-quotes = "double"
|
||||
|
||||
```text
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[lint]
|
||||
# Add "Q" to the list of enabled codes.
|
||||
select = ["E4", "E7", "E9", "F", "Q"]
|
||||
|
||||
```
|
||||
|
||||
[lint.flake8-quotes] [lint.flake8-quotes]
|
||||
docstring-quotes = "double"
|
||||
|
||||
```text
|
||||
|
||||
Ruff respects `pyproject.toml`, `ruff.toml`, and `.ruff.toml` files. All three implement an
|
||||
equivalent schema (though in the `ruff.toml` and `.ruff.toml` versions, the `[tool.ruff]` header and
|
||||
`tool.ruff` section prefix is omitted).
|
||||
|
||||
For a complete enumeration of the available configuration options, see [_Settings_](settings.md).
|
||||
|
||||
## Config file discovery
|
||||
|
||||
Similar to [ESLint](https://eslint.org/docs/latest/use/configure/configuration-files#cascading-configuration-objects),
|
||||
Ruff supports hierarchical configuration, such that the "closest" config file in the
|
||||
directory hierarchy is used for every individual file, with all paths in the config file
|
||||
(e.g., `exclude` globs, `src` paths) being resolved relative to the directory containing that
|
||||
config file.
|
||||
|
||||
There are a few exceptions to these rules:
|
||||
|
||||
1. In locating the "closest" `pyproject.toml` file for a given path, Ruff ignores any
|
||||
`pyproject.toml` files that lack a `[tool.ruff]` section.
|
||||
1. If a configuration file is passed directly via `--config`, those settings are used for _all_
|
||||
analyzed files, and any relative paths in that configuration file (like `exclude` globs or
|
||||
`src` paths) are resolved relative to the _current_ working directory.
|
||||
1. If no config file is found in the filesystem hierarchy, Ruff will fall back to using
|
||||
a default configuration. If a user-specific configuration file exists
|
||||
at `${config_dir}/ruff/pyproject.toml`, that file will be used instead of the default
|
||||
configuration, with `${config_dir}` being determined via [`etcetera`'s base strategy](https://docs.rs/etcetera/latest/etcetera/#native-strategy),
|
||||
and all relative paths being again resolved relative to the _current working directory_.
|
||||
1. Any config-file-supported settings that are provided on the command-line (e.g., via
|
||||
`--select`) will override the settings in _every_ resolved configuration file.
|
||||
|
||||
Unlike [ESLint](https://eslint.org/docs/latest/use/configure/configuration-files#cascading-configuration-objects),
|
||||
Ruff does not merge settings across configuration files; instead, the "closest" configuration file
|
||||
is used, and any parent configuration files are ignored. In lieu of this implicit cascade, Ruff
|
||||
supports an [`extend`](settings.md#extend) field, which allows you to inherit the settings from another
|
||||
config file, like so:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff]
|
||||
# Extend the `pyproject.toml` file in the parent directory...
|
||||
extend = "../pyproject.toml"
|
||||
|
||||
```
|
||||
|
||||
## ...but use a different line length. # ...but use a different line length
|
||||
|
||||
line-length = 100
|
||||
|
||||
```text
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
# Extend the `ruff.toml` file in the parent directory...
|
||||
extend = "../ruff.toml"
|
||||
|
||||
```
|
||||
|
||||
# ...but use a different line length. # ...but use a different line length.
|
||||
line-length = 100
|
||||
|
||||
```text
|
||||
|
||||
All of the above rules apply equivalently to `pyproject.toml`, `ruff.toml`, and `.ruff.toml` files.
|
||||
If Ruff detects multiple configuration files in the same directory, the `.ruff.toml` file will take
|
||||
precedence over the `ruff.toml` file, and the `ruff.toml` file will take precedence over
|
||||
the `pyproject.toml` file.
|
||||
|
||||
## Inferring the Python version
|
||||
|
||||
When no discovered configuration specifies a [`target-version`](settings.md#target-version), Ruff will attempt to fall back to the minimum version compatible with the `requires-python` field in a nearby `pyproject.toml`.
|
||||
The rules for this behavior are as follows:
|
||||
|
||||
1. If a configuration file is passed directly, Ruff does not attempt to infer a missing `target-version`.
|
||||
1. If a configuration file is found in the filesystem hierarchy, Ruff will infer a missing `target-version` from the `requires-python` field in a `pyproject.toml` file in the same directory as the found configuration.
|
||||
1. If we are using a user-level configuration from `${config_dir}/ruff/pyproject.toml`, the `requires-python` field in the first `pyproject.toml` file found in an ancestor of the current working directory takes precedence over the `target-version` in the user-level configuration.
|
||||
1. If no configuration files are found, Ruff will infer the `target-version` from the `requires-python` field in the first `pyproject.toml` file found in an ancestor of the current working directory.
|
||||
|
||||
Note that in these last two cases, the behavior of Ruff may differ depending on the working directory from which it is invoked.
|
||||
|
||||
## Python file discovery
|
||||
|
||||
When passed a path on the command-line, Ruff will automatically discover all Python files in that
|
||||
path, taking into account the [`exclude`](settings.md#exclude) and [`extend-exclude`](settings.md#extend-exclude)
|
||||
settings in each directory's configuration file.
|
||||
|
||||
Files can also be selectively excluded from linting or formatting by scoping the `exclude` setting
|
||||
to the tool-specific configuration tables. For example, the following would prevent `ruff` from
|
||||
formatting `.pyi` files, but would continue to include them in linting:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.format]
|
||||
exclude = ["*.pyi"]
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[format]
|
||||
exclude = ["*.pyi"]
|
||||
```
|
||||
|
||||
By default, Ruff will also skip any files that are omitted via `.ignore`, `.gitignore`,
|
||||
`.git/info/exclude`, and global `gitignore` files (see: [`respect-gitignore`](settings.md#respect-gitignore)).
|
||||
|
||||
Files that are passed to `ruff` directly are always analyzed, regardless of the above criteria.
|
||||
For example, `ruff check /path/to/excluded/file.py` will always lint `file.py`.
|
||||
|
||||
### Default inclusions
|
||||
|
||||
By default, Ruff will discover files matching `*.py`, `*.pyi`, `*.ipynb`, or `pyproject.toml`.
|
||||
|
||||
To lint or format files with additional file extensions, use the [`extend-include`](settings.md#extend-include) setting.
|
||||
You can also change the default selection using the [`include`](settings.md#include) setting.
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff]
|
||||
include = ["pyproject.toml", "src/**/*.py", "scripts/**/*.py"]
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
include = ["pyproject.toml", "src/**/*.py", "scripts/**/*.py"]
|
||||
```
|
||||
|
||||
!!! warning
|
||||
Paths provided to `include` _must_ match files. For example, `include = ["src"]` will fail since it
|
||||
|
||||
```text
|
||||
matches a directory. matches a directory.
|
||||
|
||||
## Jupyter Notebook discovery
|
||||
|
||||
Ruff has built-in support for linting and formatting [Jupyter Notebooks](https://jupyter.org/),
|
||||
which are linted and formatted by default on version `0.6.0` and higher.
|
||||
|
||||
If you'd prefer to either only lint or only format Jupyter Notebook files, you can use the
|
||||
section-specific `exclude` option to do so. For example, the following would only lint Jupyter
|
||||
Notebook files and not format them:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.format]
|
||||
exclude = ["*.ipynb"]
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[format]
|
||||
exclude = ["*.ipynb"]
|
||||
```
|
||||
|
||||
And, conversely, the following would only format Jupyter Notebook files and not lint them:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.lint]
|
||||
exclude = ["*.ipynb"]
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[lint]
|
||||
exclude = ["*.ipynb"]
|
||||
```
|
||||
|
||||
You can completely disable Jupyter Notebook support by updating the
|
||||
[`extend-exclude`](settings.md#extend-exclude) setting:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff]
|
||||
extend-exclude = ["*.ipynb"]
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
extend-exclude = ["*.ipynb"]
|
||||
```
|
||||
|
||||
If you'd like to ignore certain rules specifically for Jupyter Notebook files, you can do so by
|
||||
using the [`per-file-ignores`](settings.md#per-file-ignores) setting:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"*.ipynb" = ["T20"]
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[lint.per-file-ignores]
|
||||
"*.ipynb" = ["T20"]
|
||||
```
|
||||
|
||||
Some rules have different behavior when applied to Jupyter Notebook files. For
|
||||
example, when applied to `.py` files the
|
||||
[`module-import-not-at-top-of-file` (`E402`)](rules/module-import-not-at-top-of-file.md)
|
||||
rule detect imports at the top of a file, but for notebooks it detects imports at the top of a
|
||||
**cell**. For a given rule, the rule's documentation will always specify if it has different
|
||||
behavior when applied to Jupyter Notebook files.
|
||||
|
||||
## Command-line interface
|
||||
|
||||
Some configuration options can be provided or overridden via dedicated flags on the command line.
|
||||
This includes those related to rule enablement and disablement,
|
||||
file discovery, logging level, and more:
|
||||
|
||||
```console
|
||||
ruff check path/to/code/ --select F401 --select F403 --quiet
|
||||
```
|
||||
|
||||
All other configuration options can be set via the command line
|
||||
using the `--config` flag, detailed below.
|
||||
|
||||
### The `--config` CLI flag
|
||||
|
||||
The `--config` flag has two uses. It is most often used to point to the
|
||||
configuration file that you would like Ruff to use, for example:
|
||||
|
||||
```console
|
||||
ruff check path/to/directory --config path/to/ruff.toml
|
||||
```
|
||||
|
||||
However, the `--config` flag can also be used to provide arbitrary
|
||||
overrides of configuration settings using TOML `<KEY> = <VALUE>` pairs.
|
||||
This is mostly useful in situations where you wish to override a configuration setting
|
||||
that does not have a dedicated command-line flag.
|
||||
|
||||
In the below example, the `--config` flag is the only way of overriding the
|
||||
`dummy-variable-rgx` configuration setting from the command line,
|
||||
since this setting has no dedicated CLI flag. The `per-file-ignores` setting
|
||||
could also have been overridden via the `--per-file-ignores` dedicated flag,
|
||||
but using `--config` to override the setting is also fine:
|
||||
|
||||
```console
|
||||
ruff check path/to/file --config path/to/ruff.toml --config "lint.dummy-variable-rgx = '__.*'" --config "lint.per-file-ignores = {'some_file.py' = ['F841']}"
|
||||
```
|
||||
|
||||
Configuration options passed to `--config` are parsed in the same way
|
||||
as configuration options in a `ruff.toml` file.
|
||||
As such, options specific to the Ruff linter need to be prefixed with `lint.`
|
||||
(`--config "lint.dummy-variable-rgx = '__.*'"` rather than simply
|
||||
`--config "dummy-variable-rgx = '__.*'"`), and options specific to the Ruff formatter
|
||||
need to be prefixed with `format.`.
|
||||
|
||||
If a specific configuration option is simultaneously overridden by
|
||||
a dedicated flag and by the `--config` flag, the dedicated flag
|
||||
takes priority. In this example, the maximum permitted line length
|
||||
will be set to 90, not 100:
|
||||
|
||||
```console
|
||||
ruff format path/to/file --line-length=90 --config "line-length=100"
|
||||
```
|
||||
|
||||
Specifying `--config "line-length=90"` will override the `line-length`
|
||||
setting from _all_ configuration files detected by Ruff,
|
||||
including configuration files discovered in subdirectories.
|
||||
In this respect, specifying `--config "line-length=90"` has
|
||||
the same effect as specifying `--line-length=90`,
|
||||
which will similarly override the `line-length` setting from
|
||||
all configuration files detected by Ruff, regardless of where
|
||||
a specific configuration file is located.
|
||||
|
||||
### Full command-line interface
|
||||
|
||||
See `ruff help` for the full list of Ruff's top-level commands:
|
||||
|
||||
<!-- Begin auto-generated command help. -->
|
||||
|
||||
```text
|
||||
Ruff: An extremely fast Python linter and code formatter.
|
||||
|
||||
Usage: ruff [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
check Run Ruff on the given files or directories
|
||||
rule Explain a rule (or all rules)
|
||||
config List or describe the available configuration options
|
||||
linter List all supported upstream linters
|
||||
clean Clear any caches in the current directory and any subdirectories
|
||||
format Run the Ruff formatter on the given files or directories
|
||||
server Run the language server
|
||||
analyze Run analysis over Python source code
|
||||
version Display Ruff's version
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
-h, --help Print help
|
||||
-V, --version Print version
|
||||
|
||||
Log levels:
|
||||
-v, --verbose Enable verbose logging
|
||||
-q, --quiet Print diagnostics, but nothing else
|
||||
-s, --silent Disable all logging (but still exit with status code "1" upon
|
||||
detecting diagnostics)
|
||||
|
||||
Global options:
|
||||
--config <CONFIG_OPTION>
|
||||
Either a path to a TOML configuration file (`pyproject.toml` or
|
||||
`ruff.toml`), or a TOML `<KEY> = <VALUE>` pair (such as you might
|
||||
find in a `ruff.toml` configuration file) overriding a specific
|
||||
configuration option. Overrides of individual settings using this
|
||||
option always take precedence over all configuration files, including
|
||||
configuration files that were also specified using `--config`
|
||||
--isolated
|
||||
Ignore all configuration files
|
||||
|
||||
For help with a specific command, see: `ruff help <command>`.
|
||||
```
|
||||
|
||||
<!-- End auto-generated command help. -->
|
||||
|
||||
Or `ruff help check` for more on the linting command:
|
||||
|
||||
<!-- Begin auto-generated check help. -->
|
||||
|
||||
```text
|
||||
Run Ruff on the given files or directories
|
||||
|
||||
Usage: ruff check [OPTIONS] [FILES]...
|
||||
|
||||
Arguments:
|
||||
[FILES]... List of files or directories to check [default: .]
|
||||
|
||||
Options:
|
||||
--fix
|
||||
Apply fixes to resolve lint violations. Use `--no-fix` to disable or
|
||||
`--unsafe-fixes` to include unsafe fixes
|
||||
--unsafe-fixes
|
||||
Include fixes that may not retain the original intent of the code.
|
||||
Use `--no-unsafe-fixes` to disable
|
||||
--show-fixes
|
||||
Show an enumeration of all fixed lint violations. Use
|
||||
`--no-show-fixes` to disable
|
||||
--diff
|
||||
Avoid writing any fixed files back; instead, output a diff for each
|
||||
changed file to stdout, and exit 0 if there are no diffs. Implies
|
||||
`--fix-only`
|
||||
-w, --watch
|
||||
Run in watch mode by re-running whenever files change
|
||||
--fix-only
|
||||
Apply fixes to resolve lint violations, but don't report on, or exit
|
||||
non-zero for, leftover violations. Implies `--fix`. Use
|
||||
`--no-fix-only` to disable or `--unsafe-fixes` to include unsafe
|
||||
fixes
|
||||
--ignore-noqa
|
||||
Ignore any `# noqa` comments
|
||||
--output-format <OUTPUT_FORMAT>
|
||||
Output serialization format for violations. The default serialization
|
||||
format is "full" [env: RUFF_OUTPUT_FORMAT=] [possible values:
|
||||
concise, full, json, json-lines, junit, grouped, github, gitlab,
|
||||
pylint, rdjson, azure, sarif]
|
||||
-o, --output-file <OUTPUT_FILE>
|
||||
Specify file to write the linter output to (default: stdout) [env:
|
||||
RUFF_OUTPUT_FILE=]
|
||||
--target-version <TARGET_VERSION>
|
||||
The minimum Python version that should be supported [possible values:
|
||||
py37, py38, py39, py310, py311, py312, py313, py314]
|
||||
--preview
|
||||
Enable preview mode; checks will include unstable rules and fixes.
|
||||
Use `--no-preview` to disable
|
||||
--extension <EXTENSION>
|
||||
List of mappings from file extension to language (one of `python`,
|
||||
`ipynb`, `pyi`). For example, to treat `.ipy` files as IPython
|
||||
notebooks, use `--extension ipy:ipynb`
|
||||
--statistics
|
||||
Show counts for every rule with at least one violation
|
||||
--add-noqa
|
||||
Enable automatic additions of `noqa` directives to failing lines
|
||||
--show-files
|
||||
See the files Ruff will be run against with the current settings
|
||||
--show-settings
|
||||
See the settings Ruff will use to lint a given Python file
|
||||
-h, --help
|
||||
Print help
|
||||
|
||||
Rule selection:
|
||||
--select <RULE_CODE>
|
||||
Comma-separated list of rule codes to enable (or ALL, to enable all
|
||||
rules)
|
||||
--ignore <RULE_CODE>
|
||||
Comma-separated list of rule codes to disable
|
||||
--extend-select <RULE_CODE>
|
||||
Like --select, but adds additional rule codes on top of those already
|
||||
specified
|
||||
--per-file-ignores <PER_FILE_IGNORES>
|
||||
List of mappings from file pattern to code to exclude
|
||||
--extend-per-file-ignores <EXTEND_PER_FILE_IGNORES>
|
||||
Like `--per-file-ignores`, but adds additional ignores on top of
|
||||
those already specified
|
||||
--fixable <RULE_CODE>
|
||||
List of rule codes to treat as eligible for fix. Only applicable when
|
||||
fix itself is enabled (e.g., via `--fix`)
|
||||
--unfixable <RULE_CODE>
|
||||
List of rule codes to treat as ineligible for fix. Only applicable
|
||||
when fix itself is enabled (e.g., via `--fix`)
|
||||
--extend-fixable <RULE_CODE>
|
||||
Like --fixable, but adds additional rule codes on top of those
|
||||
already specified
|
||||
|
||||
File selection:
|
||||
--exclude <FILE_PATTERN>
|
||||
List of paths, used to omit files and/or directories from analysis
|
||||
--extend-exclude <FILE_PATTERN>
|
||||
Like --exclude, but adds additional files and directories on top of
|
||||
those already excluded
|
||||
--respect-gitignore
|
||||
Respect file exclusions via `.gitignore` and other standard ignore
|
||||
files. Use `--no-respect-gitignore` to disable
|
||||
--force-exclude
|
||||
Enforce exclusions, even for paths passed to Ruff directly on the
|
||||
command-line. Use `--no-force-exclude` to disable
|
||||
|
||||
Miscellaneous:
|
||||
-n, --no-cache
|
||||
Disable cache reads [env: RUFF_NO_CACHE=]
|
||||
--cache-dir <CACHE_DIR>
|
||||
Path to the cache directory [env: RUFF_CACHE_DIR=]
|
||||
--stdin-filename <STDIN_FILENAME>
|
||||
The name of the file when passing it through stdin
|
||||
-e, --exit-zero
|
||||
Exit with status code "0", even upon detecting lint violations
|
||||
--exit-non-zero-on-fix
|
||||
Exit with a non-zero status code if any files were modified via fix,
|
||||
even if no lint violations remain
|
||||
|
||||
Log levels:
|
||||
-v, --verbose Enable verbose logging
|
||||
-q, --quiet Print diagnostics, but nothing else
|
||||
-s, --silent Disable all logging (but still exit with status code "1" upon
|
||||
detecting diagnostics)
|
||||
|
||||
Global options:
|
||||
--config <CONFIG_OPTION>
|
||||
Either a path to a TOML configuration file (`pyproject.toml` or
|
||||
`ruff.toml`), or a TOML `<KEY> = <VALUE>` pair (such as you might
|
||||
find in a `ruff.toml` configuration file) overriding a specific
|
||||
configuration option. Overrides of individual settings using this
|
||||
option always take precedence over all configuration files, including
|
||||
configuration files that were also specified using `--config`
|
||||
--isolated
|
||||
Ignore all configuration files
|
||||
```
|
||||
|
||||
<!-- End auto-generated check help. -->
|
||||
|
||||
Or `ruff help format` for more on the formatting command:
|
||||
|
||||
<!-- Begin auto-generated format help. -->
|
||||
|
||||
```text
|
||||
Run the Ruff formatter on the given files or directories
|
||||
|
||||
Usage: ruff format [OPTIONS] [FILES]...
|
||||
|
||||
Arguments:
|
||||
[FILES]... List of files or directories to format [default: .]
|
||||
|
||||
Options:
|
||||
--check
|
||||
Avoid writing any formatted files back; instead, exit with a non-zero
|
||||
status code if any files would have been modified, and zero otherwise
|
||||
--diff
|
||||
Avoid writing any formatted files back; instead, exit with a non-zero
|
||||
status code and the difference between the current file and how the
|
||||
formatted file would look like
|
||||
--extension <EXTENSION>
|
||||
List of mappings from file extension to language (one of `python`,
|
||||
`ipynb`, `pyi`). For example, to treat `.ipy` files as IPython
|
||||
notebooks, use `--extension ipy:ipynb`
|
||||
--target-version <TARGET_VERSION>
|
||||
The minimum Python version that should be supported [possible values:
|
||||
py37, py38, py39, py310, py311, py312, py313, py314]
|
||||
--preview
|
||||
Enable preview mode; enables unstable formatting. Use `--no-preview`
|
||||
to disable
|
||||
--output-format <OUTPUT_FORMAT>
|
||||
Output serialization format for violations, when used with `--check`.
|
||||
The default serialization format is "full" [env: RUFF_OUTPUT_FORMAT=]
|
||||
[possible values: concise, full, json, json-lines, junit, grouped,
|
||||
github, gitlab, pylint, rdjson, azure, sarif]
|
||||
-h, --help
|
||||
Print help (see more with '--help')
|
||||
|
||||
Miscellaneous:
|
||||
-n, --no-cache
|
||||
Disable cache reads [env: RUFF_NO_CACHE=]
|
||||
--cache-dir <CACHE_DIR>
|
||||
Path to the cache directory [env: RUFF_CACHE_DIR=]
|
||||
--stdin-filename <STDIN_FILENAME>
|
||||
The name of the file when passing it through stdin
|
||||
--exit-non-zero-on-format
|
||||
Exit with a non-zero status code if any files were modified via
|
||||
format, even if all files were formatted successfully
|
||||
|
||||
File selection:
|
||||
--respect-gitignore
|
||||
Respect file exclusions via `.gitignore` and other standard ignore
|
||||
files. Use `--no-respect-gitignore` to disable
|
||||
--exclude <FILE_PATTERN>
|
||||
List of paths, used to omit files and/or directories from analysis
|
||||
--force-exclude
|
||||
Enforce exclusions, even for paths passed to Ruff directly on the
|
||||
command-line. Use `--no-force-exclude` to disable
|
||||
|
||||
Format configuration:
|
||||
--line-length <LINE_LENGTH> Set the line-length
|
||||
|
||||
Editor options:
|
||||
--range <RANGE> When specified, Ruff will try to only format the code in
|
||||
the given range.
|
||||
It might be necessary to extend the start backwards or
|
||||
the end forwards, to fully enclose a logical line.
|
||||
The `<RANGE>` uses the format
|
||||
`<start_line>:<start_column>-<end_line>:<end_column>`.
|
||||
|
||||
Log levels:
|
||||
-v, --verbose Enable verbose logging
|
||||
-q, --quiet Print diagnostics, but nothing else
|
||||
-s, --silent Disable all logging (but still exit with status code "1" upon
|
||||
detecting diagnostics)
|
||||
|
||||
Global options:
|
||||
--config <CONFIG_OPTION>
|
||||
Either a path to a TOML configuration file (`pyproject.toml` or
|
||||
`ruff.toml`), or a TOML `<KEY> = <VALUE>` pair (such as you might
|
||||
find in a `ruff.toml` configuration file) overriding a specific
|
||||
configuration option. Overrides of individual settings using this
|
||||
option always take precedence over all configuration files, including
|
||||
configuration files that were also specified using `--config`
|
||||
--isolated
|
||||
Ignore all configuration files
|
||||
```
|
||||
|
||||
<!-- End auto-generated format help. -->
|
||||
|
||||
## Shell autocompletion
|
||||
|
||||
Ruff supports autocompletion for most shells. A shell-specific completion script can be generated
|
||||
by `ruff generate-shell-completion <SHELL>`, where `<SHELL>` is one of `bash`, `elvish`, `fig`, `fish`,
|
||||
`powershell`, or `zsh`.
|
||||
|
||||
The exact steps required to enable autocompletion will vary by shell. For example instructions,
|
||||
see the [Poetry](https://python-poetry.org/docs/#enable-tab-completion-for-bash-fish-or-zsh) or
|
||||
[ripgrep FAQ](https://github.com/BurntSushi/ripgrep/blob/master/FAQ.md) documentation (see the "Does ripgrep have support for shell auto-completion?" section).
|
||||
|
||||
As an example: to enable autocompletion for Zsh, run
|
||||
`ruff generate-shell-completion zsh > ~/.zfunc/_ruff`. Then add the following line to your
|
||||
`~/.zshrc` file, if they're not already present:
|
||||
|
||||
```zsh
|
||||
fpath+=~/.zfunc
|
||||
autoload -Uz compinit && compinit
|
||||
```
|
||||
524
skills/python-code-quality/reference/ruff-formatting-settings.md
Normal file
524
skills/python-code-quality/reference/ruff-formatting-settings.md
Normal file
@@ -0,0 +1,524 @@
|
||||
# The Ruff Formatter
|
||||
|
||||
The Ruff formatter is an extremely fast Python code formatter designed as a drop-in replacement for
|
||||
[Black](https://pypi.org/project/black/), available as part of the `ruff` CLI via `ruff format`.
|
||||
|
||||
## `ruff format`
|
||||
|
||||
`ruff format` is the primary entrypoint to the formatter. It accepts a list of files or
|
||||
directories, and formats all discovered Python files:
|
||||
|
||||
```shell
|
||||
ruff format # Format all files in the current directory.
|
||||
ruff format path/to/code/ # Format all files in `path/to/code` (and any subdirectories).
|
||||
ruff format path/to/file.py # Format a single file.
|
||||
```
|
||||
|
||||
Similar to Black, running `ruff format /path/to/file.py` will format the given file or directory
|
||||
in-place, while `ruff format --check /path/to/file.py` will avoid writing any formatted files back,
|
||||
and instead exit with a non-zero status code upon detecting any unformatted files.
|
||||
|
||||
For the full list of supported options, run `ruff format --help`.
|
||||
|
||||
## Philosophy
|
||||
|
||||
The initial goal of the Ruff formatter is _not_ to innovate on code style, but rather, to innovate
|
||||
on performance, and provide a unified toolchain across Ruff's linter, formatter, and any and all
|
||||
future tools.
|
||||
|
||||
As such, the formatter is designed as a drop-in replacement for [Black](https://github.com/psf/black),
|
||||
but with an excessive focus on performance and direct integration with Ruff. Given Black's
|
||||
popularity within the Python ecosystem, targeting Black compatibility ensures that formatter
|
||||
adoption is minimally disruptive for the vast majority of projects.
|
||||
|
||||
Specifically, the formatter is intended to emit near-identical output when run over existing
|
||||
Black-formatted code. When run over extensive Black-formatted projects like Django and Zulip, > 99.9%
|
||||
of lines are formatted identically. (See: [_Style Guide_](#style-guide).)
|
||||
|
||||
Given this focus on Black compatibility, the formatter thus adheres to [Black's (stable) code style](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html),
|
||||
which aims for "consistency, generality, readability and reducing git diffs". To give you a sense
|
||||
for the enforced code style, here's an example:
|
||||
|
||||
```python
|
||||
# Input
|
||||
def _make_ssl_transport(
|
||||
rawsock, protocol, sslcontext, waiter=None,
|
||||
*, server_side=False, server_hostname=None,
|
||||
extra=None, server=None,
|
||||
ssl_handshake_timeout=None,
|
||||
call_connection_made=True):
|
||||
'''Make an SSL transport.'''
|
||||
if waiter is None:
|
||||
waiter = Future(loop=loop)
|
||||
|
||||
if extra is None:
|
||||
extra = {}
|
||||
|
||||
...
|
||||
|
||||
# Ruff
|
||||
def _make_ssl_transport(
|
||||
rawsock,
|
||||
protocol,
|
||||
sslcontext,
|
||||
waiter=None,
|
||||
*,
|
||||
server_side=False,
|
||||
server_hostname=None,
|
||||
extra=None,
|
||||
server=None,
|
||||
ssl_handshake_timeout=None,
|
||||
call_connection_made=True,
|
||||
):
|
||||
"""Make an SSL transport."""
|
||||
if waiter is None:
|
||||
waiter = Future(loop=loop)
|
||||
|
||||
if extra is None:
|
||||
extra = {}
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
Like Black, the Ruff formatter does _not_ support extensive code style configuration; however,
|
||||
unlike Black, it _does_ support configuring the desired quote style, indent style, line endings,
|
||||
and more. (See: [_Configuration_](#configuration).)
|
||||
|
||||
While the formatter is designed to be a drop-in replacement for Black, it is not intended to be
|
||||
used interchangeably with Black on an ongoing basis, as the formatter _does_ differ from
|
||||
Black in a few conscious ways (see: [_Known deviations_](formatter/black.md)). In general,
|
||||
deviations are limited to cases in which Ruff's behavior was deemed more consistent, or
|
||||
significantly simpler to support (with negligible end-user impact) given the differences in the
|
||||
underlying implementations between Black and Ruff.
|
||||
|
||||
Going forward, the Ruff Formatter will support Black's preview style under Ruff's own
|
||||
[preview](preview.md) mode.
|
||||
|
||||
## Configuration
|
||||
|
||||
The Ruff Formatter exposes a small set of configuration options, some of which are also supported
|
||||
by Black (like line width), some of which are unique to Ruff (like quote, indentation style and
|
||||
formatting code examples in docstrings).
|
||||
|
||||
For example, to configure the formatter to use single quotes, format code
|
||||
examples in docstrings, a line width of 100, and tab indentation, add the
|
||||
following to your configuration file:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff]
|
||||
line-length = 100
|
||||
|
||||
```
|
||||
|
||||
[tool.ruff.format] [tool.ruff.format]
|
||||
quote-style = "single"
|
||||
indent-style = "tab"
|
||||
docstring-code-format = true
|
||||
|
||||
```text
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```
|
||||
|
||||
```toml
|
||||
line-length = 100
|
||||
|
||||
```
|
||||
|
||||
[format] [format]
|
||||
quote-style = "single"
|
||||
indent-style = "tab"
|
||||
docstring-code-format = true
|
||||
|
||||
```text
|
||||
|
||||
For the full list of supported settings, see [_Settings_](settings.md#format). For more on
|
||||
configuring Ruff via `pyproject.toml`, see [_Configuring Ruff_](configuration.md).
|
||||
|
||||
Given the focus on Black compatibility (and unlike formatters like [YAPF](https://github.com/google/yapf)),
|
||||
Ruff does not currently expose any other configuration options.
|
||||
|
||||
## Docstring formatting
|
||||
|
||||
The Ruff formatter provides an opt-in feature for automatically formatting
|
||||
Python code examples in docstrings. The Ruff formatter currently recognizes
|
||||
code examples in the following formats:
|
||||
|
||||
* The Python [doctest] format.
|
||||
* CommonMark [fenced code blocks] with the following info strings: `python`,
|
||||
`py`, `python3`, or `py3`. Fenced code blocks without an info string are
|
||||
assumed to be Python code examples and also formatted.
|
||||
* reStructuredText [literal blocks]. While literal blocks may contain things
|
||||
other than Python, this is meant to reflect a long-standing convention in the
|
||||
|
||||
Python ecosystem where literal blocks often contain Python code.
|
||||
|
||||
* reStructuredText [`code-block` and `sourcecode` directives]. As with
|
||||
|
||||
Markdown, the language names recognized for Python are `python`, `py`,
|
||||
`python3`, or `py3`.
|
||||
|
||||
If a code example is recognized and treated as Python, the Ruff formatter will
|
||||
automatically skip it if the code does not parse as valid Python or if the
|
||||
reformatted code would produce an invalid Python program.
|
||||
|
||||
Users may also configure the line length limit used for reformatting Python
|
||||
code examples in docstrings. The default is a special value, `dynamic`, which
|
||||
instructs the formatter to respect the line length limit setting for the
|
||||
surrounding Python code. The `dynamic` setting ensures that even when code
|
||||
examples are found inside indented docstrings, the line length limit configured
|
||||
for the surrounding Python code will not be exceeded. Users may also configure
|
||||
a fixed line length limit for code examples in docstrings.
|
||||
|
||||
For example, this configuration shows how to enable docstring code formatting
|
||||
with a fixed line length limit:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.format]
|
||||
docstring-code-format = true
|
||||
docstring-code-line-length = 20
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[format]
|
||||
docstring-code-format = true
|
||||
docstring-code-line-length = 20
|
||||
```
|
||||
|
||||
With the above configuration, this code:
|
||||
|
||||
```python
|
||||
def f(x):
|
||||
'''
|
||||
Something about `f`. And an example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
foo, bar, quux = this_is_a_long_line(lion, hippo, lemur, bear)
|
||||
'''
|
||||
pass
|
||||
```
|
||||
|
||||
... will be reformatted (assuming the rest of the options are set
|
||||
to their defaults) as:
|
||||
|
||||
```python
|
||||
def f(x):
|
||||
"""
|
||||
Something about `f`. And an example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
(
|
||||
foo,
|
||||
bar,
|
||||
quux,
|
||||
) = this_is_a_long_line(
|
||||
lion,
|
||||
hippo,
|
||||
lemur,
|
||||
bear,
|
||||
)
|
||||
"""
|
||||
pass
|
||||
```
|
||||
|
||||
[doctest]: https://docs.python.org/3/library/doctest.html
|
||||
[fenced code blocks]: https://spec.commonmark.org/0.30/#fenced-code-blocks
|
||||
[literal blocks]: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks
|
||||
[`code-block` and `sourcecode` directives]: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block
|
||||
|
||||
## Format suppression
|
||||
|
||||
Like Black, Ruff supports `# fmt: on`, `# fmt: off`, and `# fmt: skip` pragma comments, which can
|
||||
be used to temporarily disable formatting for a given code block.
|
||||
|
||||
`# fmt: on` and `# fmt: off` comments are enforced at the statement level:
|
||||
|
||||
```python
|
||||
# fmt: off
|
||||
not_formatted=3
|
||||
also_not_formatted=4
|
||||
# fmt: on
|
||||
```
|
||||
|
||||
As such, adding `# fmt: on` and `# fmt: off` comments within expressions will have no effect. In
|
||||
the following example, both list entries will be formatted, despite the `# fmt: off`:
|
||||
|
||||
```python
|
||||
[
|
||||
# fmt: off
|
||||
'1',
|
||||
# fmt: on
|
||||
'2',
|
||||
]
|
||||
```
|
||||
|
||||
Instead, apply the `# fmt: off` comment to the entire statement:
|
||||
|
||||
```python
|
||||
# fmt: off
|
||||
[
|
||||
'1',
|
||||
'2',
|
||||
]
|
||||
# fmt: on
|
||||
```
|
||||
|
||||
Like Black, Ruff will _also_ recognize [YAPF](https://github.com/google/yapf)'s `# yapf: disable` and `# yapf: enable` pragma
|
||||
comments, which are treated equivalently to `# fmt: off` and `# fmt: on`, respectively.
|
||||
|
||||
`# fmt: skip` comments suppress formatting for a preceding statement, case header, decorator,
|
||||
function definition, or class definition:
|
||||
|
||||
```python
|
||||
if True:
|
||||
pass
|
||||
elif False: # fmt: skip
|
||||
pass
|
||||
|
||||
@Test
|
||||
@Test2 # fmt: skip
|
||||
def test(): ...
|
||||
|
||||
a = [1, 2, 3, 4, 5] # fmt: skip
|
||||
|
||||
def test(a, b, c, d, e, f) -> int: # fmt: skip
|
||||
pass
|
||||
```
|
||||
|
||||
As such, adding an `# fmt: skip` comment at the end of an expression will have no effect. In
|
||||
the following example, the list entry `'1'` will be formatted, despite the `# fmt: skip`:
|
||||
|
||||
```python
|
||||
a = call(
|
||||
[
|
||||
'1', # fmt: skip
|
||||
'2',
|
||||
],
|
||||
b
|
||||
)
|
||||
```
|
||||
|
||||
Instead, apply the `# fmt: skip` comment to the entire statement:
|
||||
|
||||
```python
|
||||
a = call(
|
||||
[
|
||||
'1',
|
||||
'2',
|
||||
],
|
||||
b
|
||||
) # fmt: skip
|
||||
```
|
||||
|
||||
## Conflicting lint rules
|
||||
|
||||
Ruff's formatter is designed to be used alongside the linter. However, the linter includes
|
||||
some rules that, when enabled, can cause conflicts with the formatter, leading to unexpected
|
||||
behavior. When configured appropriately, the goal of Ruff's formatter-linter compatibility is
|
||||
such that running the formatter should never introduce new lint errors.
|
||||
|
||||
When using Ruff as a formatter, we recommend avoiding the following lint rules:
|
||||
|
||||
* [`tab-indentation`](rules/tab-indentation.md) (`W191`)
|
||||
* [`indentation-with-invalid-multiple`](rules/indentation-with-invalid-multiple.md) (`E111`)
|
||||
* [`indentation-with-invalid-multiple-comment`](rules/indentation-with-invalid-multiple-comment.md) (`E114`)
|
||||
* [`over-indented`](rules/over-indented.md) (`E117`)
|
||||
* [`docstring-tab-indentation`](rules/docstring-tab-indentation.md) (`D206`)
|
||||
* [`triple-single-quotes`](rules/triple-single-quotes.md) (`D300`)
|
||||
* [`bad-quotes-inline-string`](rules/bad-quotes-inline-string.md) (`Q000`)
|
||||
* [`bad-quotes-multiline-string`](rules/bad-quotes-multiline-string.md) (`Q001`)
|
||||
* [`bad-quotes-docstring`](rules/bad-quotes-docstring.md) (`Q002`)
|
||||
* [`avoidable-escaped-quote`](rules/avoidable-escaped-quote.md) (`Q003`)
|
||||
* [`missing-trailing-comma`](rules/missing-trailing-comma.md) (`COM812`)
|
||||
* [`prohibited-trailing-comma`](rules/prohibited-trailing-comma.md) (`COM819`)
|
||||
* [`multi-line-implicit-string-concatenation`](rules/multi-line-implicit-string-concatenation.md) (`ISC002`) if used without `ISC001` and `flake8-implicit-str-concat.allow-multiline = false`
|
||||
|
||||
While the [`line-too-long`](rules/line-too-long.md) (`E501`) rule _can_ be used alongside the
|
||||
formatter, the formatter only makes a best-effort attempt to wrap lines at the configured
|
||||
[`line-length`](settings.md#line-length). As such, formatted code _may_ exceed the line length,
|
||||
leading to [`line-too-long`](rules/line-too-long.md) (`E501`) errors.
|
||||
|
||||
None of the above are included in Ruff's default configuration. However, if you've enabled
|
||||
any of these rules or their parent categories (like `Q`), we recommend disabling them via the
|
||||
linter's [`lint.ignore`](settings.md#lint_ignore) setting.
|
||||
|
||||
Similarly, we recommend avoiding the following isort settings, which are incompatible with the
|
||||
formatter's treatment of import statements when set to non-default values:
|
||||
|
||||
* [`force-single-line`](settings.md#lint_isort_force-single-line)
|
||||
* [`force-wrap-aliases`](settings.md#lint_isort_force-wrap-aliases)
|
||||
* [`lines-after-imports`](settings.md#lint_isort_lines-after-imports)
|
||||
* [`lines-between-types`](settings.md#lint_isort_lines-between-types)
|
||||
* [`split-on-trailing-comma`](settings.md#lint_isort_split-on-trailing-comma)
|
||||
|
||||
If you've configured any of these settings to take on non-default values, we recommend removing
|
||||
them from your Ruff configuration.
|
||||
|
||||
When an incompatible lint rule or setting is enabled, `ruff format` will emit a warning. If your
|
||||
`ruff format` is free of warnings, you're good to go!
|
||||
|
||||
## Exit codes
|
||||
|
||||
`ruff format` exits with the following status codes:
|
||||
|
||||
* `0` if Ruff terminates successfully, regardless of whether any files were formatted.
|
||||
* `2` if Ruff terminates abnormally due to invalid configuration, invalid CLI options, or an
|
||||
internal error.
|
||||
|
||||
Meanwhile, `ruff format --check` exits with the following status codes:
|
||||
|
||||
* `0` if Ruff terminates successfully, and no files would be formatted if `--check` were not
|
||||
specified.
|
||||
* `1` if Ruff terminates successfully, and one or more files would be formatted if `--check` were
|
||||
not specified.
|
||||
* `2` if Ruff terminates abnormally due to invalid configuration, invalid CLI options, or an
|
||||
internal error.
|
||||
|
||||
## Style Guide
|
||||
|
||||
The formatter is designed to be a drop-in replacement for [Black](https://github.com/psf/black).
|
||||
This section documents the areas where the Ruff formatter goes beyond Black in terms of code style.
|
||||
|
||||
### Intentional deviations
|
||||
|
||||
While the Ruff formatter aims to be a drop-in replacement for Black, it does differ from Black
|
||||
in a few known ways. Some of these differences emerge from conscious attempts to improve upon
|
||||
Black's code style, while others fall out of differences in the underlying implementations.
|
||||
|
||||
For a complete enumeration of these intentional deviations, see [_Known deviations_](formatter/black.md).
|
||||
|
||||
Unintentional deviations from Black are tracked in the [issue tracker](https://github.com/astral-sh/ruff/issues?q=is%3Aopen+is%3Aissue+label%3Aformatter).
|
||||
If you've identified a new deviation, please [file an issue](https://github.com/astral-sh/ruff/issues/new).
|
||||
|
||||
### Preview style
|
||||
|
||||
Similar to [Black](https://black.readthedocs.io/en/stable/the_black_code_style/future_style.html#preview-style), Ruff implements formatting changes
|
||||
under the [`preview`](https://docs.astral.sh/ruff/settings/#format_preview) flag, promoting them to stable through minor releases, in accordance with our [versioning policy](https://github.com/astral-sh/ruff/discussions/6998#discussioncomment-7016766).
|
||||
|
||||
### F-string formatting
|
||||
|
||||
_Stabilized in Ruff 0.9.0_
|
||||
|
||||
Unlike Black, Ruff formats the expression parts of f-strings which are the parts inside the curly
|
||||
braces `{...}`. This is a [known deviation](formatter/black.md#f-strings) from Black.
|
||||
|
||||
Ruff employs several heuristics to determine how an f-string should be formatted which are detailed
|
||||
below.
|
||||
|
||||
#### Quotes
|
||||
|
||||
Ruff will use the [configured quote style] for the f-string expression unless doing so would result in
|
||||
invalid syntax for the target Python version or requires more backslash escapes than the original
|
||||
expression. Specifically, Ruff will preserve the original quote style for the following cases:
|
||||
|
||||
When the target Python version is < 3.12 and a [self-documenting f-string] contains a string
|
||||
literal with the [configured quote style]:
|
||||
|
||||
```python
|
||||
# format.quote-style = "double"
|
||||
|
||||
f'{10 + len("hello")=}'
|
||||
# This f-string cannot be formatted as follows when targeting Python < 3.12
|
||||
f"{10 + len("hello")=}"
|
||||
```
|
||||
|
||||
When the target Python version is < 3.12 and an f-string contains any triple-quoted string, byte
|
||||
or f-string literal that contains the [configured quote style]:
|
||||
|
||||
```python
|
||||
# format.quote-style = "double"
|
||||
|
||||
f'{"""nested " """}'
|
||||
# This f-string cannot be formatted as follows when targeting Python < 3.12
|
||||
f"{'''nested " '''}"
|
||||
```
|
||||
|
||||
For all target Python versions, when a [self-documenting f-string] contains an expression between
|
||||
the curly braces (`{...}`) with a format specifier containing the [configured quote style]:
|
||||
|
||||
```python
|
||||
# format.quote-style = "double"
|
||||
|
||||
f'{1=:"foo}'
|
||||
# This f-string cannot be formatted as follows for all target Python versions
|
||||
f"{1=:"foo}"
|
||||
```
|
||||
|
||||
For nested f-strings, Ruff alternates quote styles, starting with the [configured quote style] for the
|
||||
outermost f-string. For example, consider the following f-string:
|
||||
|
||||
```python
|
||||
# format.quote-style = "double"
|
||||
|
||||
f"outer f-string {f"nested f-string {f"another nested f-string"} end"} end"
|
||||
```
|
||||
|
||||
Ruff formats it as:
|
||||
|
||||
```python
|
||||
f"outer f-string {f'nested f-string {f"another nested f-string"} end'} end"
|
||||
```
|
||||
|
||||
#### Line breaks
|
||||
|
||||
Starting with Python 3.12 ([PEP 701](https://peps.python.org/pep-0701/)), the expression parts of an f-string can
|
||||
span multiple lines. Ruff needs to decide when to introduce a line break in an f-string expression.
|
||||
This depends on the semantic content of the expression parts of an f-string - for example,
|
||||
introducing a line break in the middle of a natural-language sentence is undesirable. Since Ruff
|
||||
doesn't have enough information to make that decision, it adopts a heuristic similar to [Prettier](https://prettier.io/docs/en/next/rationale.html#template-literals):
|
||||
it will only split the expression parts of an f-string across multiple lines if there was already a line break
|
||||
within any of the expression parts.
|
||||
|
||||
For example, the following code:
|
||||
|
||||
```python
|
||||
f"this f-string has a multiline expression {
|
||||
['red', 'green', 'blue', 'yellow',]} and does not fit within the line length"
|
||||
```
|
||||
|
||||
... is formatted as:
|
||||
|
||||
```python
|
||||
# The list expression is split across multiple lines because of the trailing comma
|
||||
f"this f-string has a multiline expression {
|
||||
[
|
||||
'red',
|
||||
'green',
|
||||
'blue',
|
||||
'yellow',
|
||||
]
|
||||
} and does not fit within the line length"
|
||||
```
|
||||
|
||||
But, the following will not be split across multiple lines even though it exceeds the line length:
|
||||
|
||||
```python
|
||||
f"this f-string has a multiline expression {['red', 'green', 'blue', 'yellow']} and does not fit within the line length"
|
||||
```
|
||||
|
||||
If you want Ruff to split an f-string across multiple lines, ensure there's a linebreak somewhere within the
|
||||
`{...}` parts of an f-string.
|
||||
|
||||
[self-documenting f-string]: https://realpython.com/python-f-strings/#self-documenting-expressions-for-debugging
|
||||
[configured quote style]: settings.md/#format_quote-style
|
||||
|
||||
## Sorting imports
|
||||
|
||||
Currently, the Ruff formatter does not sort imports. In order to both sort imports and format,
|
||||
call the Ruff linter and then the formatter:
|
||||
|
||||
```shell
|
||||
ruff check --select I --fix
|
||||
ruff format
|
||||
```
|
||||
|
||||
A unified command for both linting and formatting is [planned](https://github.com/astral-sh/ruff/issues/8232).
|
||||
438
skills/python-code-quality/reference/ruff-linting-settings.md
Normal file
438
skills/python-code-quality/reference/ruff-linting-settings.md
Normal file
@@ -0,0 +1,438 @@
|
||||
# The Ruff Linter
|
||||
|
||||
The Ruff Linter is an extremely fast Python linter designed as a drop-in replacement for [Flake8](https://pypi.org/project/flake8/)
|
||||
(plus dozens of plugins), [isort](https://pypi.org/project/isort/), [pydocstyle](https://pypi.org/project/pydocstyle/),
|
||||
[pyupgrade](https://pypi.org/project/pyupgrade/), [autoflake](https://pypi.org/project/autoflake/),
|
||||
and more.
|
||||
|
||||
## `ruff check`
|
||||
|
||||
`ruff check` is the primary entrypoint to the Ruff linter. It accepts a list of files or
|
||||
directories, and lints all discovered Python files, optionally fixing any fixable errors.
|
||||
When linting a directory, Ruff searches for Python files recursively in that directory
|
||||
and all its subdirectories:
|
||||
|
||||
```console
|
||||
ruff check # Lint files in the current directory.
|
||||
ruff check --fix # Lint files in the current directory and fix any fixable errors.
|
||||
ruff check --watch # Lint files in the current directory and re-lint on change.
|
||||
ruff check path/to/code/ # Lint files in `path/to/code`.
|
||||
```
|
||||
|
||||
For the full list of supported options, run `ruff check --help`.
|
||||
|
||||
## Rule selection
|
||||
|
||||
The set of enabled rules is controlled via the [`lint.select`](settings.md#lint_select),
|
||||
[`lint.extend-select`](settings.md#lint_extend-select), and [`lint.ignore`](settings.md#lint_ignore) settings.
|
||||
|
||||
Ruff's linter mirrors Flake8's rule code system, in which each rule code consists of a one-to-three
|
||||
letter prefix, followed by three digits (e.g., `F401`). The prefix indicates that "source" of the rule
|
||||
(e.g., `F` for Pyflakes, `E` for pycodestyle, `ANN` for flake8-annotations).
|
||||
|
||||
Rule selectors like [`lint.select`](settings.md#lint_select) and [`lint.ignore`](settings.md#lint_ignore) accept either
|
||||
a full rule code (e.g., `F401`) or any valid prefix (e.g., `F`). For example, given the following
|
||||
configuration file:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.lint]
|
||||
select = ["E", "F"]
|
||||
ignore = ["F401"]
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[lint]
|
||||
select = ["E", "F"]
|
||||
ignore = ["F401"]
|
||||
```
|
||||
|
||||
Ruff would enable all rules with the `E` (pycodestyle) or `F` (Pyflakes) prefix, with the exception
|
||||
of `F401`. For more on configuring Ruff via `pyproject.toml`, see [_Configuring Ruff_](configuration.md).
|
||||
|
||||
As a special-case, Ruff also supports the `ALL` code, which enables all rules. Note that some
|
||||
pydocstyle rules conflict (e.g., `D203` and `D211`) as they represent alternative docstring
|
||||
formats. Ruff will automatically disable any conflicting rules when `ALL` is enabled.
|
||||
|
||||
If you're wondering how to configure Ruff, here are some **recommended guidelines**:
|
||||
|
||||
- Prefer [`lint.select`](settings.md#lint_select) over [`lint.extend-select`](settings.md#lint_extend-select) to make your rule set explicit.
|
||||
- Use `ALL` with discretion. Enabling `ALL` will implicitly enable new rules whenever you upgrade.
|
||||
- Start with a small set of rules (`select = ["E", "F"]`) and add a category at-a-time. For example,
|
||||
you might consider expanding to `select = ["E", "F", "B"]` to enable the popular flake8-bugbear
|
||||
extension.
|
||||
|
||||
For example, a configuration that enables some of the most popular rules (without being too
|
||||
pedantic) might look like the following:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.lint]
|
||||
```
|
||||
|
||||
select = [ select = [
|
||||
|
||||
# pycodestyle
|
||||
|
||||
"E",
|
||||
|
||||
# Pyflakes
|
||||
|
||||
"F",
|
||||
|
||||
# pyupgrade
|
||||
|
||||
"UP",
|
||||
|
||||
# flake8-bugbear
|
||||
|
||||
"B",
|
||||
|
||||
# flake8-simplify
|
||||
|
||||
"SIM",
|
||||
|
||||
# isort
|
||||
|
||||
"I",
|
||||
]
|
||||
|
||||
```text
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```
|
||||
|
||||
```toml
|
||||
[lint]
|
||||
select = [
|
||||
# pycodestyle
|
||||
"E",
|
||||
# Pyflakes
|
||||
"F",
|
||||
# pyupgrade
|
||||
"UP",
|
||||
# flake8-bugbear
|
||||
"B",
|
||||
# flake8-simplify
|
||||
"SIM",
|
||||
# isort
|
||||
"I",
|
||||
]
|
||||
```
|
||||
|
||||
To resolve the enabled rule set, Ruff may need to reconcile [`lint.select`](settings.md#lint_select) and
|
||||
[`lint.ignore`](settings.md#lint_ignore) from a variety of sources, including the current `pyproject.toml`,
|
||||
any inherited `pyproject.toml` files, and the CLI (e.g., [`--select`](settings.md#lint_select)).
|
||||
|
||||
In those scenarios, Ruff uses the "highest-priority" [`select`](settings.md#lint_select) as the basis for
|
||||
the rule set, and then applies [`extend-select`](settings.md#lint_extend-select) and
|
||||
[`ignore`](settings.md#lint_ignore) adjustments. CLI options are given higher priority than
|
||||
`pyproject.toml` options, and the current `pyproject.toml` file is given higher priority than any
|
||||
inherited `pyproject.toml` files.
|
||||
|
||||
For example, given the following configuration file:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.lint]
|
||||
select = ["E", "F"]
|
||||
ignore = ["F401"]
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[lint]
|
||||
select = ["E", "F"]
|
||||
ignore = ["F401"]
|
||||
```
|
||||
|
||||
Running `ruff check --select F401` would result in Ruff enforcing `F401`, and no other rules.
|
||||
|
||||
Running `ruff check --extend-select B` would result in Ruff enforcing the `E`, `F`, and `B` rules,
|
||||
with the exception of `F401`.
|
||||
|
||||
## Fixes
|
||||
|
||||
Ruff supports automatic fixes for a variety of lint errors. For example, Ruff can remove unused
|
||||
imports, reformat docstrings, rewrite type annotations to use newer Python syntax, and more.
|
||||
|
||||
To enable fixes, pass the `--fix` flag to `ruff check`:
|
||||
|
||||
```console
|
||||
ruff check --fix
|
||||
```
|
||||
|
||||
By default, Ruff will fix all violations for which safe fixes are available; to determine
|
||||
whether a rule supports fixing, see [_Rules_](rules.md).
|
||||
|
||||
### Fix safety
|
||||
|
||||
Ruff labels fixes as "safe" and "unsafe". The meaning and intent of your code will be retained when
|
||||
applying safe fixes, but the meaning could change when applying unsafe fixes.
|
||||
|
||||
Specifically, an unsafe fix could lead to a change in runtime behavior, the removal of comments, or both,
|
||||
while safe fixes are intended to preserve runtime behavior and will only remove comments when deleting
|
||||
entire statements or expressions (e.g., removing unused imports).
|
||||
|
||||
For example, [`unnecessary-iterable-allocation-for-first-element`](rules/unnecessary-iterable-allocation-for-first-element.md)
|
||||
(`RUF015`) is a rule which checks for potentially unperformant use of `list(...)[0]`. The fix
|
||||
replaces this pattern with `next(iter(...))` which can result in a drastic speedup:
|
||||
|
||||
```console
|
||||
$ python -m timeit "head = list(range(99999999))[0]"
|
||||
1 loop, best of 5: 1.69 sec per loop
|
||||
```
|
||||
|
||||
```console
|
||||
$ python -m timeit "head = next(iter(range(99999999)))"
|
||||
5000000 loops, best of 5: 70.8 nsec per loop
|
||||
```
|
||||
|
||||
However, when the collection is empty, this raised exception changes from an `IndexError` to `StopIteration`:
|
||||
|
||||
```console
|
||||
$ python -c 'list(range(0))[0]'
|
||||
Traceback (most recent call last):
|
||||
File "<string>", line 1, in <module>
|
||||
IndexError: list index out of range
|
||||
```
|
||||
|
||||
```console
|
||||
$ python -c 'next(iter(range(0)))[0]'
|
||||
Traceback (most recent call last):
|
||||
File "<string>", line 1, in <module>
|
||||
StopIteration
|
||||
```
|
||||
|
||||
Since the change in exception type could break error handling upstream, this fix is categorized as unsafe.
|
||||
|
||||
Ruff only enables safe fixes by default. Unsafe fixes can be enabled by settings [`unsafe-fixes`](settings.md#unsafe-fixes) in your configuration file or passing the `--unsafe-fixes` flag to `ruff check`:
|
||||
|
||||
```console
|
||||
|
||||
## Show unsafe fixes
|
||||
|
||||
ruff check --unsafe-fixes
|
||||
|
||||
## Apply unsafe fixes
|
||||
|
||||
ruff check --fix --unsafe-fixes
|
||||
```
|
||||
|
||||
By default, Ruff will display a hint when unsafe fixes are available but not enabled. The suggestion can be silenced
|
||||
by setting the [`unsafe-fixes`](settings.md#unsafe-fixes) setting to `false` or using the `--no-unsafe-fixes` flag.
|
||||
|
||||
The safety of fixes can be adjusted per rule using the [`lint.extend-safe-fixes`](settings.md#lint_extend-safe-fixes) and [`lint.extend-unsafe-fixes`](settings.md#lint_extend-unsafe-fixes) settings.
|
||||
|
||||
For example, the following configuration would promote unsafe fixes for `F601` to safe fixes and demote safe fixes for `UP034` to unsafe fixes:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.lint]
|
||||
extend-safe-fixes = ["F601"]
|
||||
extend-unsafe-fixes = ["UP034"]
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[lint]
|
||||
extend-safe-fixes = ["F601"]
|
||||
extend-unsafe-fixes = ["UP034"]
|
||||
```
|
||||
|
||||
You may use prefixes to select rules as well, e.g., `F` can be used to promote fixes for all rules in Pyflakes to safe.
|
||||
|
||||
!!! note
|
||||
All fixes will always be displayed by Ruff when using the `json` output format. The safety of each fix is available under the `applicability` field.
|
||||
|
||||
### Disabling fixes
|
||||
|
||||
To limit the set of rules that Ruff should fix, use the [`lint.fixable`](settings.md#lint_fixable)
|
||||
or [`lint.extend-fixable`](settings.md#lint_extend-fixable), and [`lint.unfixable`](settings.md#lint_unfixable) settings.
|
||||
|
||||
For example, the following configuration would enable fixes for all rules except
|
||||
[`unused-imports`](rules/unused-import.md) (`F401`):
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.lint]
|
||||
fixable = ["ALL"]
|
||||
unfixable = ["F401"]
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[lint]
|
||||
fixable = ["ALL"]
|
||||
unfixable = ["F401"]
|
||||
```
|
||||
|
||||
Conversely, the following configuration would only enable fixes for `F401`:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.ruff.lint]
|
||||
fixable = ["F401"]
|
||||
```
|
||||
|
||||
=== "ruff.toml"
|
||||
|
||||
```toml
|
||||
[lint]
|
||||
fixable = ["F401"]
|
||||
```
|
||||
|
||||
## Error suppression
|
||||
|
||||
Ruff supports several mechanisms for suppressing lint errors, be they false positives or
|
||||
permissible violations.
|
||||
|
||||
To omit a lint rule entirely, add it to the "ignore" list via the [`lint.ignore`](settings.md#lint_ignore)
|
||||
setting, either on the command-line or in your `pyproject.toml` or `ruff.toml` file.
|
||||
|
||||
To suppress a violation inline, Ruff uses a `noqa` system similar to [Flake8](https://flake8.pycqa.org/en/3.1.1/user/ignoring-errors.html).
|
||||
To ignore an individual violation, add `# noqa: {code}` to the end of the line, like so:
|
||||
|
||||
```python
|
||||
|
||||
## Ignore F841
|
||||
|
||||
x = 1 # noqa: F841
|
||||
|
||||
## Ignore E741 and F841
|
||||
|
||||
i = 1 # noqa: E741, F841
|
||||
|
||||
## Ignore _all_ violations
|
||||
|
||||
x = 1 # noqa
|
||||
```
|
||||
|
||||
For multi-line strings (like docstrings), the `noqa` directive should come at the end of the string
|
||||
(after the closing triple quote), and will apply to the entire string, like so:
|
||||
|
||||
```python
|
||||
"""Lorem ipsum dolor sit amet.
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.
|
||||
""" # noqa: E501
|
||||
```
|
||||
|
||||
For import sorting, the `noqa` should come at the end of the first line in the import block, and
|
||||
will apply to all imports in the block, like so:
|
||||
|
||||
```python
|
||||
import os # noqa: I001
|
||||
import abc
|
||||
```
|
||||
|
||||
To ignore all violations across an entire file, add the line `# ruff: noqa` anywhere in the file,
|
||||
preferably towards the top, like so:
|
||||
|
||||
```python
|
||||
|
||||
## ruff: noqa
|
||||
```
|
||||
|
||||
To ignore a specific rule across an entire file, add the line `# ruff: noqa: {code}` anywhere in the
|
||||
file, preferably towards the top, like so:
|
||||
|
||||
```python
|
||||
|
||||
## ruff: noqa: F841
|
||||
```
|
||||
|
||||
Or see the [`lint.per-file-ignores`](settings.md#lint_per-file-ignores) setting, which enables the same
|
||||
functionality from within your `pyproject.toml` or `ruff.toml` file.
|
||||
|
||||
Global `noqa` comments must be on their own line to disambiguate from comments which ignore
|
||||
violations on a single line.
|
||||
|
||||
Note that Ruff will also respect Flake8's `# flake8: noqa` directive, and will treat it as
|
||||
equivalent to `# ruff: noqa`.
|
||||
|
||||
### Full suppression comment specification
|
||||
|
||||
The full specification is as follows:
|
||||
|
||||
- An inline blanket `noqa` comment is given by a case-insensitive match for
|
||||
`#noqa` with optional whitespace after the `#` symbol, followed by either: the
|
||||
end of the comment, the beginning of a new comment (`#`), or whitespace
|
||||
followed by any character other than `:`.
|
||||
- An inline rule suppression is given by first finding a case-insensitive match
|
||||
for `#noqa` with optional whitespace after the `#` symbol, optional whitespace
|
||||
after `noqa`, and followed by the symbol `:`. After this we are expected to
|
||||
have a list of rule codes which is given by sequences of uppercase ASCII
|
||||
characters followed by ASCII digits, separated by whitespace or commas. The
|
||||
list ends at the last valid code. We will attempt to interpret rules with a
|
||||
missing delimiter (e.g. `F401F841`), though a warning will be emitted in this
|
||||
case.
|
||||
- A file-level exemption comment is given by a case-sensitive match for `#ruff:`
|
||||
or `#flake8:`, with optional whitespace after `#` and before `:`, followed by
|
||||
optional whitespace and a case-insensitive match for `noqa`. After this, the
|
||||
specification is as in the inline case.
|
||||
|
||||
### Detecting unused suppression comments
|
||||
|
||||
Ruff implements a special rule, [`unused-noqa`](https://docs.astral.sh/ruff/rules/unused-noqa/),
|
||||
under the `RUF100` code, to enforce that your `noqa` directives are "valid", in that the violations
|
||||
they _say_ they ignore are actually being triggered on that line (and thus suppressed). To flag
|
||||
unused `noqa` directives, run: `ruff check /path/to/file.py --extend-select RUF100`.
|
||||
|
||||
Ruff can also _remove_ any unused `noqa` directives via its fix functionality. To remove any
|
||||
unused `noqa` directives, run: `ruff check /path/to/file.py --extend-select RUF100 --fix`.
|
||||
|
||||
### Inserting necessary suppression comments
|
||||
|
||||
Ruff can _automatically add_ `noqa` directives to all lines that contain violations, which is
|
||||
useful when migrating a new codebase to Ruff. To automatically add `noqa` directives to all
|
||||
relevant lines (with the appropriate rule codes), run: `ruff check /path/to/file.py --add-noqa`.
|
||||
|
||||
### Action comments
|
||||
|
||||
Ruff respects isort's [action comments](https://pycqa.github.io/isort/docs/configuration/action_comments.html)
|
||||
(`# isort: skip_file`, `# isort: on`, `# isort: off`, `# isort: skip`, and `# isort: split`), which
|
||||
enable selectively enabling and disabling import sorting for blocks of code and other inline
|
||||
configuration.
|
||||
|
||||
Ruff will also respect variants of these action comments with a `# ruff:` prefix
|
||||
(e.g., `# ruff: isort: skip_file`, `# ruff: isort: on`, and so on). These variants more clearly
|
||||
convey that the action comment is intended for Ruff, but are functionally equivalent to the
|
||||
isort variants.
|
||||
|
||||
Unlike isort, Ruff does not respect action comments within docstrings.
|
||||
|
||||
See the [isort documentation](https://pycqa.github.io/isort/docs/configuration/action_comments.html)
|
||||
for more.
|
||||
|
||||
## Exit codes
|
||||
|
||||
By default, `ruff check` exits with the following status codes:
|
||||
|
||||
- `0` if no violations were found, or if all present violations were fixed automatically.
|
||||
- `1` if violations were found.
|
||||
- `2` if Ruff terminates abnormally due to invalid configuration, invalid CLI options, or an
|
||||
internal error.
|
||||
|
||||
This convention mirrors that of tools like ESLint, Prettier, and RuboCop.
|
||||
|
||||
`ruff check` supports two command-line flags that alter its exit code behavior:
|
||||
|
||||
- `--exit-zero` will cause Ruff to exit with a status code of `0` even if violations were found.
|
||||
Note that Ruff will still exit with a status code of `2` if it terminates abnormally.
|
||||
- `--exit-non-zero-on-fix` will cause Ruff to exit with a status code of `1` if violations were
|
||||
found, _even if_ all such violations were fixed automatically. Note that the use of
|
||||
`--exit-non-zero-on-fix` can result in a non-zero exit code even if no violations remain after
|
||||
fixing.
|
||||
Reference in New Issue
Block a user