Skip to main content

Pyrefly Configuration

Pyrefly has a basic configuration that can (or will) allow you to customize your Pyrefly runs without having to specify all of your arguments on the command line.

NOTE: this is early in its development, so the options listed here are subject to change in name, usage, type, quantity, and structure.

Configurations can be specified in a TOML file at the root of your project (or elsewhere, as long as the search_path is correct) named pyrefly.toml, with all configuration options in the top-level of the document. You can also specify a configuration in a pyproject.toml under a [tool.pyrefly] section. Other config names can be used when explicitly passing in the config file name with the --config/-c flag, but they will not be automatically found by Configuration Finding.

Both absolute and config-relative paths are supported.

Precedence in Options

The following is the order in which configuration options are selected:

  1. CLI flag
  2. Environment variable override -- This is the same as PYREFLY_<CLI flag name>
  3. Configuration option
  4. Hard-coded default

Configuration Finding

In both project checking mode (with no explicit configuration supplied) and single-file checking mode, we perform an upward file search to find a configuration file. We check each directory from the start location to the filesystem root, looking first for pyrefly.toml then pyproject.toml, in the same directory before looking at its parent.

For project checking mode, the start location is the CWD. We do not perform any searching if the --config/-c flag is used. For single-file checking mode, the start location is the directory containing the file to be type checked. No config flag can be passed into Pyrefly in single file checking mode.

If a pyrefly.toml is found, it is parsed and used for type checking, and will return an error to the user on invalid types, syntax, or values.

If a pyproject.toml is found, Pyrefly will stop searching, even if no [tool.pyrefly] section is found. The same errors will be returned as when loading a pyrefly.toml if the config is invalid.

Configuration Options

  • project_includes: the glob patterns used to describe which files to type check, typically understood as user-space files. This takes highest precedence in import resolution.
    • Type: list of Unix Glob patterns
    • Default: ["**/*.py"]
    • Flag equivalent: FILES... argument
    • Equivalent configs: include in Pyright, files/modules/packages in mypy
    • Notes:
      • When overridden by passing in FILES..., we do not consult the relevant config file for what to use for project_excludes. If project_excludes should not use the default value, override it with the flag as well.
      • When a project_includes pattern does not match any files, we will return an error.
  • project_excludes: the glob patterns used to describe which files to avoid type checking, usually as a more fine-grained way of controlling the files you get type errors on.
    • Type: list of Unix Glob patterns
    • Default: ["**/__pycache__/**", "**/.*"]
    • Flag equivalent: --project-excludes
    • Equivalent configs: exclude in Pyright and mypy
    • Notes:
      • We match on these patterns, unlike project_includes, where we enumerate all (Python) files under the directory. Because of this, project_excludes does not do directory matching unless a / is added at the end of your glob pattern. **/__pycache__/ will only match files under a directory named __pycache__/, but not a file named __pycache__. Likewise, **/__pycache__ will only match files named __pycache__, but not files under a directory named __pycache__/.
      • It is an error if no files are returned from any project_includes because they are filtered out by project_excludes entries.
      • When passing in FILES..., we also do not consult the config file for what to use for project_excludes. If project_excludes should not use the default value, override it with a flag as well.
  • search_path: a file path describing a root from which imports should be found and imported from (including modules in project_includes). This takes the highest precedence in import order, before typeshed and site_package_path. When a project_includes type checked file is imported by another type checked file, we check all search roots to determine how to import it.
    • Type: list of directories
    • Default: ["."]
    • Flag equivalent: --search-path
    • ENV equivalent: PYREFLY_SEARCH_PATH
    • Equivalent configs: extraPaths in Pyright, mypy_path in mypy
    • Notes: we automatically append "." (the directory containing the configuration file) to the search_roots when type checking as a sensible default and last attempt at an import.
  • site_package_path: a file path describing a root from which imports should be found and imported from. This takes the lowest priority in import resolution, after project_includes, typeshed, and search_roots.
    • Type: list of directories
    • Default: result from Environment Autoconfiguration or []
    • Flag equivalent: --site-package-path
    • ENV equivalent: PYREFLY_SITE_PACKAGE_PATH
    • Equivalent configs: none
  • python_platform: the value used with conditions based on type checking against sys.platform values.
    • Type: string
    • Default: result from Environment Autoconfiguration or "linux"
    • Flag equivalent: --python-platform
    • ENV equivalent: PYREFLY_PYTHON_PLATFORM
    • Equivalent configs: pythonPlatform in Pyright, platform in mypy
  • python_version: the value used with conditions based on type checking against sys.version values. The format should be <major>[.<minor>[.<micro>]], where minor and micro can be omitted to take the default positional value.
    • Type: string
    • Default: result from Environment Autoconfiguration or 3.13.0
    • Flag equivalent: --python-version
    • ENV equivalent: PYREFLY_PYTHON_VERSION
    • Equivalent configs: pythonVersion in Pyright, python_version in mypy
  • python_interpreter: the Python interpreter to query when attempting to autoconfigure Python environment values (site_package_path, python_platform, python_version). See the Environment Autoconfiguration section for more information.
    • Type: string of executable or path to executable
    • Default: python3
    • Flag equivalent: --python-interpreter
    • ENV equivalent: PYREFLY_PYTHON_INTERPRETER
    • Equivalent configs: python_executable in mypy
    • Notes:
      • This executes the value present in the python_interpreter field without any checks. It could be a security risk if your python_interpreter executes an arbitrary executable.
      • If you are working on a project shared between multiple people, it is likely best not to use this option, since there might be different Python interpreter versions used on different systems. Instead, we recommend explicitly setting python_version, python_platform, and site_package_path, or using alternative methods of environment autoconfiguration (coming soon).
  • errors: configure (enable and disable) the errors Pyrefly shows
    • Type: Table of error code name to boolean representing enabled status
    • Default: errors = {}
    • Flag equivalent: none
    • ENV equivalent: none
    • Equivalent configs: type check rule overrides and type evaluation settings in Pyright, enable_error_code and disable_error_code in mypy
    • Notes: setting <error-code> = true is the same as having no error code configuration present, which means the error will be shown. Setting <error-code> = false will disable the error for type checking.
  • replace_imports_with_any: ModuleGlobs of modules from which import errors should be ignored, and the module should be replaced with typing.Any. For example, with from x.y import z in a file, adding x.*, *.y, or x.y to this config will silence those import errors and replace the module with typing.Any. If the module can be found, its type information will still be replaced with typing.Any.
    • Type: list of regex
    • Default: []
    • Flag equivalent: none
    • ENV equivalent: none
    • Equivalent configs: ignore_missing_imports in mypy
    • Notes:
      • errors = {import-error = false} (TOML inline table for errors) has similar behavior in Pyrefly, but ignores all import errors instead of import errors from specific modules, and won't replace findable modules with typing.Any.
  • ignore_errors_in_generated_code: Whether to ignore type errors in generated code. If enabled, generated files will be treated as if they are included in project_excludes. Generated code are determined by checking if the file contents contain the substring {'@' + 'generated'}.
    • Type: bool
    • Default: false
    • Flag equivalent: --ignore-errors-in-generated-code
    • ENV equivalent: IGNORE_ERRORS_IN_GENERATED_CODE

Environment Autoconfiguration

If any of python_platform, python_version, or site_package_path are empty, we attempt to query an interpreter for the missing values. By default we query python3 if it's available on the path, but the interpreter can be overridden with the python_interpreter config option and flag. If the interpreter does not exist, we fall back to Pyrefly's defaults for all unspecified values.

The values queried from the interpreter are:

  • python_platform: sys.platform
  • python_version: sys.version_info[:3]
  • site_package_path: site.getsitepackages()

Module globbing

In some functionality, we've added globbing for module paths. This is different from both path globs and regex, in the sense that we're performing a match on a Python dotted import, such as this.is.any.module. The only wildcard we recognize is *, which represents zero or more segments of a module path, unless it starts a glob, in which case it must match one or more segments. The wildcard must be surrounded by ., unless it is at the start or end of a module glob.

Examples:

  • this.is.a.module would be equivalent to a regex like ^this\.is\.a\.module. It will only match imports that look like this.is.a.module.
  • this.is.*.module would become ^this\.is(\..+)*\.module$. It would match:
    • this.is.module
    • this.is.a.module
    • this.is.a.really.long.path.to.a.module
  • *.my.module would be equivalent to a regex like ^.+\.my\.module$.
    • It would match:
      • this.is.my.module
      • heres.my.module
    • It will not match:
      • my.module
  • this.is.* would be equivalent to a regex like ^this\.is(\..+)*. It would match:
    • this.is.my.module
    • this.is