Allow int for truncation_limit_lines and truncation_limit_chars in TOML#14692
Allow int for truncation_limit_lines and truncation_limit_chars in TOML#14692Pierre-Sassoulas wants to merge 2 commits into
truncation_limit_lines and truncation_limit_chars in TOML#14692Conversation
bluetech
left a comment
There was a problem hiding this comment.
We can't just change to int, as that would be a breaking change. We need to allow both, unfortunately.
I will write in the issue how I think we can do it.
7706185 to
6cf3e85
Compare
addini now accepts a tuple of the existing type tags, e.g.
type=("int", "string"), meaning the option accepts a value of any of
those types. getini tries each tag in order and returns the first that
accepts the value: in TOML config the native value may be of any member
type, and string-based formats (INI files, -o overrides) coerce it to
the first member that accepts it.
This reuses the existing per-tag coercion, and single-tag registration is
unchanged (its original error is re-raised as-is).
The truncation_limit_lines and truncation_limit_chars options were registered without a type (defaulting to 'string'), so integer values in native TOML config raised a TypeError (pytest-dev#14675). They are now registered with type=('int', 'string'), accepting both int and string values in TOML while keeping the string form working for backward compatibility. TruncationBudget.from_config reads the two options and owns default handling: None (option unset) falls back to the DEFAULT_MAX_* limits, which live next to the class; other values are coerced with int(). truncate_if_required short-circuits on verbosity/CI before reading the options at all. 0 still means 'unbounded'; None means 'use default'. Fixes pytest-dev#14675
4010bfd to
007af70
Compare
nicoddemus
left a comment
There was a problem hiding this comment.
Overall nice work.
It is different than the original proposal of using the types directly (str | int vs ("str", "int")), but I suspect this is good enough and aligns well with the original API.
| #: a value of any of these types" (e.g. ``("int", "string")``). | ||
| IniType = _IniTypeTag | tuple[_IniTypeTag, ...] | ||
|
|
||
| _INI_TYPE_TAGS: tuple[str, ...] = ( |
There was a problem hiding this comment.
| _INI_TYPE_TAGS: tuple[str, ...] = ( | |
| #: Runtime list tags accepted by :meth:`Parser.addini` for its ``type`` argument. | |
| #: Keep in sync with _IniTypeTag. | |
| _INI_TYPE_TAGS: tuple[str, ...] = ( |
|
|
||
| FILE_OR_DIR = "file_or_dir" | ||
|
|
||
| #: The string tags accepted by :meth:`Parser.addini` for its ``type`` argument. |
There was a problem hiding this comment.
| #: The string tags accepted by :meth:`Parser.addini` for its ``type`` argument. | |
| #: The string tags accepted by :meth:`Parser.addini` for its ``type`` argument. | |
| #: Keep in sync with _INI_TYPE_TAGS. |
| if type is None: | ||
| type = "string" | ||
| tags = type if isinstance(type, tuple) else (type,) | ||
| assert tags and all(tag in _INI_TYPE_TAGS for tag in tags), type |
There was a problem hiding this comment.
We probably should use an exception here, given this might be an user-provided value.
asserts should be used for internal checks/consistency only.
| if type in ("paths", "pathlist", "args", "linelist"): | ||
| if isinstance(type, tuple): | ||
| # A union has no unambiguous implicit default; require an explicit one. | ||
| return None |
There was a problem hiding this comment.
IIUC, None will be used as default, contrary to the comment. Perhaps raise an exception instead?
The truncation_limit_lines and truncation_limit_chars ini options were registered without a type, defaulting to 'string'. In native TOML config ([tool.pytest]), integer values then raised a TypeError instead of being accepted, despite being numeric limits.
Register both options with type='int' so TOML integer values are accepted (INI string values keep working via the existing int coercion).
Basically #14689 but without unwanted AI to human conversation.
Fixes #14675