Merge upstream - #7
Closed
KotlinIsland wants to merge 694 commits into
Closed
Conversation
## Summary We record a reachability predicate for every statement-level call because the call may return `Never`. Predicate IDs follow source order, but reachability decision diagrams put later predicates before earlier ones. In a large generated method, analyzing a late call could infer its receiver, re-enter reachability for the preceding call, and continue backward through thousands of calls until the worker stack overflowed. For example, given: ```python call_a() # predicate 0 call_b() # predicate 1 call_c() # predicate 2 ``` Reachability previously discovered the dependencies backward: ```text analyze call_c └─ analyze call_b └─ analyze call_a ``` Before evaluating a reachability constraint, we now force analysis to process the relevant statement-level calls one by one in source order: ```text analyze call_a → cached analyze call_b → call_a is already cached analyze call_c → call_b is already cached ``` Non-terminal-call analysis is a tracked Salsa query, so each result is cached. When inferring a later call asks about an earlier call, it gets that cached result instead of adding another nested inference and reachability frame. Inferring a call can itself re-enter reachability, so a scope-keyed guard prevents the same source-order pass from starting again. A nested scope is still allowed to perform its own pass. The ordinary decision-diagram evaluation and `Never`-based narrowing behavior remain unchanged. The exact PySide6 reproduction now completes successfully instead of aborting with a stack overflow. Closes astral-sh/ty#3822.
Co-authored-by: Micha Reiser <micha@reiser.io>
## Summary This PR updates the parser README to: 1. Link the parser README's AST reference to the published `ruff_python_ast` crate 2. Remove the obsolete "Python version support" section now that version specific syntax errors are implemented Additionally, I've also updated the README generator to add a "Versioning" section while preserving the rest of the handwritten README and updated the generator to refresh marker-delimited versioning sections. Maybe this is not worth doing, let me know if that's the case. ### Review - astral-sh/ruff@5a4145a - updates the README manually as mentioned in (1) and (2) above - astral-sh/ruff@dcb5925 - updates the README generator to add the versioning section ## Test plan Here's the [Rendered README](https://github.com/astral-sh/ruff/blob/dcb59253c41ecbebacd919defcbb725461a95478/crates/ruff_python_parser/README.md) for preview. Ran `uv run --script scripts/generate-crate-readmes.py` twice and verified idempotent output
## Summary Adds generated versioning sections to three handwritten crate READMEs. Follow-up to [ruff#26315](astral-sh/ruff#26315). I've skipped `ruff_annotate_snippets` for now as it's a fork of the original crate.
This document explores the combination of generics and gradual set-theoretic types. In particular, we derive the following results that might be useful for implementing some union and intersection simplifications in ty, which in turn might help implement some features around `isinstance` and `TypeIs` narrowing (especially the last one): ```py Co[P] | Co[Any] = Co[P | Any] Co[P] & Co[Any] = Co[P & Any] Contra[P] | Contra[Any] = Contra[P & Any] Contra[P] & Contra[Any] = Contra[P | Any] Invariant[P] & Invariant[Any] = Invariant[P] ```
## Summary We already infer equality results for literal values of the same kind, but mismatched literal kinds fell through to dunder lookup and produced `bool`. As a result, direct comparisons such as `1 == ""` remained ambiguous, as did tuple comparisons whose corresponding elements had different literal kinds. This adds a narrow expression-inference case for mismatched built-in `int`, `bool`, `str`, and `bytes` literals. It also handles `LiteralString` compared with non-string literals while preserving `bool` for `LiteralString` compared with a particular string literal, since those values may be equal. ```python reveal_type(1 == "") # Literal[False] reveal_type(True != "") # Literal[True] left = (1, 2) right = (1, "two") reveal_type(left == right) # Literal[False] ``` --------- Co-authored-by: Carl Meyer <carl@astral.sh>
## Summary Avoid replacing the recursive occurrence when the current type is already a variadic tuple, which prevents unbounded growth in cases like `x = (*x, x)`. Closes astral-sh/ty#3838 ## Testing Added mdtest.
## Summary - Make `ty_python_semantic`, `ty_python_core`, and `ty_vendored` publishable; `ty_module_resolver` is already in the publishing set and remains unchanged. - Publish `ty_combine` as the required runtime dependency of `ty_python_core`. All other ty crates remain excluded from crates.io publishing. - Add the generated crate READMEs and make `ty_vendored`'s source-commit include package-relative so the packaged crate verifies outside the Ruff workspace. The complete new dependency chain passes Cargo's publish dry run, all 774 affected crate tests pass, and the repository hooks and dependency checks pass.
Co-authored-by: Micha Reiser <micha@reiser.io>
## Summary
We currently treat the members declared on every enum as its complete
runtime domain. That assumption does not hold for `Flag` and `IntFlag`,
which also have zero and unnamed combinations, or for enums whose custom
`_missing_` method or metaclass can create additional members. As a
result, we can incorrectly treat a one-member enum as a singleton, widen
all declared members to the nominal enum, erase a non-empty complement,
or consider a `match` over the declared members exhaustive.
This adds a `members_are_exhaustive` property to `EnumClassLiteral` and
uses it wherever we rely on an enum being a finite set: complement
construction, union simplification, singleton detection,
finite-alternative narrowing, and match exhaustiveness. Open enums
retain the nominal remainder after known members are excluded.
Explicit membership tests remain precise when the enum uses identity
comparison. For example, a metaclass may add `INJECTED`, but testing
against `ONLY` still establishes that exact member on the positive
branch and excludes only that member on the negative branch:
```python
class OpenEnum(Enum, metaclass=InjectingEnumMeta):
ONLY = 1
def check(value: OpenEnum):
if value in (OpenEnum.ONLY,):
reveal_type(value) # Literal[OpenEnum.ONLY]
else:
reveal_type(value) # OpenEnum & ~Literal[OpenEnum.ONLY]
```
This is the semantic foundation split out of #26270; that PR adds the
compact same-enum comparison path on top.
## Summary `@Todo` is a dynamic type that represents a known missing feature or incomplete implementation in ty, but it previously had no user-facing definition. As a result, go-to-type-definition on an inferred `@Todo` type returned no target, and users had no editor-visible explanation of what the type meant. This adds a documented `Todo` symbol to `ty_extensions` and routes all internal `@Todo` variants to that definition, following the existing `Divergent` pattern. Users can now command-click an inferred `@Todo` type to reach its documentation. `ty_extensions.Todo` remains an internal navigation target and is rejected in annotations. This complements astral-sh/ty#3847, which adds an FAQ entry. Closes astral-sh/ty#3209.
Summary -- This addresses another discrepancy Codex noticed between `noqa` and `ruff:ignore` while reviewing my `--add-ignore` PR. `noqa` had special handling for shebang lines, which allowed it to suppress a diagnostic with a 0..0 range, like `D100`, even when a shebang was present that prevented putting the suppression on the first line: ```py #!/usr/bin/python # noqa: D100 ``` [Playground](https://play.ruff.rs/5381b897-06d1-4d41-900b-cc85a40b2740) This was previously not the case for `ruff:ignore`. ```py #!/usr/bin/python # ruff:ignore[D100] ``` [Playground](https://play.ruff.rs/1d3dde25-2692-43f3-a6fb-54b2e156ba66) Test Plan -- A new mdtest covering this scenario
## Summary Record `ty_combine`, `ty_python_core`, `ty_python_semantic`, and `ty_vendored` as configured for crates.io trusted publishing after #26323 made them publishable. The bootstrap script uses `.known-crates` as a persistent checkpoint and skips entries on later runs. Checking in the generated result makes subsequent bootstrap runs a no-op until another workspace package becomes publishable. The generated file now matches all 36 publishable workspace packages.
## Summary
When a Pydantic model uses a `RootModel` as a field, that field can
either be passed as an instance of the class (`IntList`), or as the
underlying type directly (`list[int]`):
```py
class IntList(RootModel[list[int]]): ...
class Model(BaseModel):
int_list: IntList
Model(int_list=IntList([1, 2, 3])) # okay
Model(int_list=[1, 2, 3]) # also okay
Model(int_list=1) # error
```
Prior to this PR, we allowed `Any` type to be passed for `RootModel`
fields.
towards astral-sh/ty#2403
## Ecosystem
The new diagnostic on prefect looks like a true positive.
## Test Plan
Updated Markdown tests
…637)
## Summary
A Pydantic field which uses `...` (ellipsis) for the `default` argument
is actually required and provides no default value.
```py
class Model(BaseModel):
value: Any = Field(...)
Model() # error
```
towards astral-sh/ty#2403
## Ecosystem
The two new diagnostics are false positives due to missing support for
`AliasChoices`. I think they are acceptable. They were missing
previously because we were modeling something completely wrong, so it's
hardly a regression (we only recently removed those diagnostics when
adding support for `extra`).
## Test Plan
Updated Markdown tests
## Summary Report the actual and required read types for incompatible protocol attributes, distinguishing missing writable capabilities from members that reject the required write type. For the motivating case, the diagnostic now explains: ```text info: type `C` is not assignable to protocol `WithValue` info: └── protocol member `value` is incompatible info: └── the member does not accept writes of type `str | None` ``` Related to astral-sh/ty#3940. ## Testing Added mdtests with inline diagnostic snapshots.
## Summary Attach existing assignability error context when an explicit type argument fails a TypeVar upper bound. Closes astral-sh/ty#3940. For the motivating case in that issue, this now clarifies why the concrete type is not assignable to the protocol. ## Validation Added mdtest with inline diagnostic snapshot.
## Summary
Recognize frozen models that have `frozen=True` in their model config:
```py
class Person(BaseModel):
model_config = ConfigDict(frozen=True)
name: str
person = Person(name="Alice")
person.name = "Bob" # error: [invalid-assignment]
```
With this change, we can now also get rid of the
`DataclassTransformerParams` that were still stored in every Pydantic
model's metadata.
towards astral-sh/ty#2403
## Test Plan
Updated Markdown tests
Co-authored-by: Carl Meyer <carl@astral.sh>
<!-- Thank you for contributing to Ruff/ty! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? (Please prefix with `[ty]` for ty pull requests.) - Does this pull request include references to any relevant issues? - Does this PR follow our AI policy (https://github.com/astral-sh/.github/blob/main/AI_POLICY.md)? --> ## Summary <!-- What's the purpose of the change? What does it do, and why? --> This refactors how we extract parameter documentation from Google-style docstrings. It replaces the existing regex-based scanner in `ty_ide/src/docstring.rs` with a parser that should strictly improve parameter documentation extraction along the following dimensions: - We will now recognize parameters from `Keyword Args` and `Other Args` sections (as well their other common spellings), where previously we only recognized parameters from `Args` and `Parameters` sections. - We now respect PEP 257 indentation and container boundaries, thereby ignoring parameter-like text that appears inside Markdown fences/lists, doctests, and reStructuredText directives, field lists, and literal blocks. - We now recognize continuation prose in parameter documentation more consistently. - We now extract docs for all parameters in a comma-separated list. In addition, to those immediate improvements, this new section visitor provides the source text range tracking that will allow us to render Google-style docstring as markdown in an [upcoming change](astral-sh/ruff#26599). Please note that I have intentionally biased this parser towards successfully parsing shapes that were actually found in the wild during a corpus review of popular public repositories that use Google-style docstrings. As such, there are theoretically possible shapes that we do not bother to support because they are very unlikely to occur in real docstrings. I think this is an acceptable compromise in favour of maintainability. ## Test Plan Please see included tests. <!-- How was it tested? -->
## Summary Closes #20729. This marks `PYI061` fixes as unsafe in non-stub Python files. The fix can rewrite `Literal["foo", "bar", None]` into `Literal["foo", "bar"] | None`. That is equivalent for type checkers, but it is not fully equivalent at runtime: code that introspects annotations with `typing.get_args()` observes a different structure after the rewrite. Stub files keep the previous behavior, since they are not runtime Python files: fixes are still safe unless comments are removed. I also added a regression case to the existing `PYI061.py` fixture. While updating the snapshots, this also removes trailing whitespace from the affected diagnostic messages. ## Test Plan Reproduced the issue before the change: ```sh cargo run -p ruff -- check /tmp/pyi061_repro.py --select PYI061 --fix --diff --no-cache --isolated ``` Verified that after the change, the fix is no longer applied by default and is only available with `--unsafe-fixes`. Verified that the fix is still available with unsafe fixes enabled: ```sh cargo run -p ruff -- check /tmp/pyi061_repro.py --select PYI061 --fix --diff --unsafe-fixes --no-cache --isolated ``` Ran the targeted snapshot tests: ```sh CARGO_PROFILE_DEV_OPT_LEVEL=1 INSTA_FORCE_PASS=1 INSTA_UPDATE=always CARGO_PROFILE_DEV_DEBUG="line-tables-only" MDTEST_UPDATE_SNAPSHOTS=1 cargo test -p ruff_linter rule_redundantnoneliteral_path_new_pyi061 -- --nocapture ``` Also ran: ```sh cargo dev generate-all uv run --only-group dev --locked prek run --files crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI061.py crates/ruff_linter/src/rules/flake8_pyi/rules/redundant_none_literal.rs crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI061_PYI061.py.snap crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI061_PYI061.pyi.snap crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__py38_PYI061_PYI061.py.snap crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__py38_PYI061_PYI061.pyi.snap git diff --check ``` --------- Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
This showed a massive performance win for #25559; pulling it out into a separate PR. We have several operations that existentially quantify away a set of typevars. Before, we would do this one typevar at a time, producing an intermediate BDD after each. This was causing a big performance hit on #25559, where we are about to start deferring quantification until we start extracting solutions from a constraint set. That means that (a) we have a larger set of typevars to quantify at once, and (b) we've built up a larger, more complex BDD by the time we're ready to quantify. Quantifying the first typevar is fine, but that produces an even larger BDD, which then feeds into quantifying the second typevar, which produces an even larger...and so on. There _are_ opportunities for the quantification to _simplify_ things and produce a smaller BDD, but there's no guarantee where in the sequence of typevars that will happen. The main contribution of this PR is to quantify all of the typevars in a single pass through the original BDD. That change is actually pretty straightforward. But it identified an issue (that already had a TODO comment describing it) in our "nested subsitution" logic. That logic tries to identify runaway expansions in a constraint whose typevar appears recursively in its lower/upper bound. The detection logic was too simple, and could incorrectly flag unrelated expansions as being runaways. The new logic tracks a separate chain of expansions (called "histories" in the code) for each assignment in the path.
<!-- Thank you for contributing to Ruff/ty! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? (Please prefix with `[ty]` for ty pull requests.) - Does this pull request include references to any relevant issues? - Does this PR follow our AI policy (https://github.com/astral-sh/.github/blob/main/AI_POLICY.md)? --> ## Summary <!-- What's the purpose of the change? What does it do, and why? --> This is a minor refactor to remove some unnecessary duplication in tests. ## Test Plan See modified tests. <!-- How was it tested? -->
<!-- Thank you for contributing to Ruff/ty! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? (Please prefix with `[ty]` for ty pull requests.) - Does this pull request include references to any relevant issues? - Does this PR follow our AI policy (https://github.com/astral-sh/.github/blob/main/AI_POLICY.md)? --> ## Summary <!-- What's the purpose of the change? What does it do, and why? --> This adds additional Google-style section types to the ones that we recognize in a docstring. For the moment this is inert, but it will soon allow us to [render those additional section types as Markdown](astral-sh/ruff#26599). ## Test Plan Since this new code is inert, we are relying on existing regression coverage. <!-- How was it tested? -->
In the legacy solver, when a nominal instance is matched against a
(formal) `Callable`, use the `(Type::Callable(formal_callable), _)`
match arm which handles the transformation of a nominal instance into a
callable object. This allows us to solve cases like
```py
from typing import Callable
def call[R](callable: Callable[[], R]) -> R:
return callable()
class MyCallable:
def __call__(self) -> int:
return 1
my_callable = MyCallable()
reveal_type(call(my_callable)) # previously: Unknown, now: int
```
closes astral-sh/ty#3763
The ecosystem impact here shows the downstream fallout of type inference
becoming more precise. I didn't spot anything that would indicate a
problem with this particular change.
## Summary `float`s that were embedded in unions were not recognized by our lax mode mapping (since we were only looking for the expanded `float | int`), so they were mapped to `Any` instead of `LaxFloat`, which lead to overly permissive lax types. closes astral-sh/ty#3946 ## Test Plan Added a regression test
## Summary Minor cleanup to avoid all of the `matches!(...)`.
## Summary
In #25955, we started to reuse our equality logic to narrow membership
tests (`in`, `not in`). This PR then defines when the right-hand side of
an `in` or `not in` test has behavior that is precise enough for us to
use that reasoning.
For nominal types, we walk the statically visible MRO. `list`, `set`,
`frozenset`, `dict`, `tuple`, and `range` use the "containment domain"
of their specialized built-in base when we reach that base before any
custom `__contains__` implementation. Final classes that only define
`__iter__` can also use their iteration domain, while open iterable
classes remain conservative because a subclass could add `__contains__`.
A visible `__contains__` override on the class or an intermediate base
disables narrowing:
```python
from typing import Literal, TypedDict
class Payload(TypedDict):
value: int
class MissingList(list[Literal["missing"]]):
pass
class ContainsEverything(list[Literal["missing"]]):
def __contains__(self, value: object) -> bool:
return True
def inherited(value: Payload | Literal["missing"], values: MissingList) -> None:
if value in values:
reveal_type(value) # Literal["missing"]
def overridden(value: Payload | Literal["missing"], values: ContainsEverything) -> None:
if value in values:
reveal_type(value) # Payload | Literal["missing"]
```
The rule is intentionally unsound for open subclasses of built-ins. At
runtime, a `list[T]` could be a subclass that overrides `__contains__`,
but we assume it isn't. This matches our existing policy for tuple
dunder methods, where we assume unsafe overrides will eventually be
reported at the definition site.
## Summary Previously, rendering edits in preview mode involved taking a diff of the entire file (for non-notebooks) for each separate violation/fix. Instead, we now take a small context window around the edit, and diff that instead. This gives a **1.75-3.6x** speed up on real world cases. No AI was used in generating the code or PR text. ## Test Plan Correctness tested with `cargo nextest run`. Performance tested using the `profiling` profile on the python code in the `ruff` repo: - current `main`: ```console $ ./ruff_main version ruff 0.15.20+90 (40a62bc 2026-07-06) $ hyperfine -w 3 -i "./ruff_main check --preview --select=ALL" Benchmark 1: ./ruff_main check --preview --select=ALL Time (mean ± σ): 355.7 ms ± 2.0 ms [User: 559.8 ms, System: 45.0 ms] Range (min … max): 352.2 ms … 358.4 ms 10 runs ``` - this PR: ```console $ hyperfine -w 3 -i "target/profiling/ruff check --preview --select=ALL" Benchmark 1: target/profiling/ruff check --preview --select=ALL Time (mean ± σ): 205.0 ms ± 4.6 ms [User: 401.8 ms, System: 48.2 ms] Range (min … max): 200.2 ms … 213.9 ms 14 runs ``` Taking the min time for each, this is a 1.75x speedup. I tested other (real) projects, and this change was even faster on them. I think this is a solution for #24548 -- although this PR is not able to complete that extreme example within the timeout of 3 minutes, it does manage to render about 75% of the violations. With a timeout of 10s, current `main` gets to about `func_0_32` on my machine, whereas this PR gets to `func_0_415`. --------- Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
## Summary This represents parameter display names as the original `Name` plus a small display prefix instead of constructing synthetic names such as `*args` and `**kwargs`. Signature formatting now writes the prefix only when rendering, and diagnostic contexts retain an owned wrapper that clones or shares the underlying identifier without allocating a decorated `Name`.
## Summary This replaces the AST `Name` used by `ProjectMetadata` with a private `ProjectName` backed by `CompactString`. Project names can come from distribution metadata or directory names and are not necessarily Python identifiers. Keeping them in a dedicated type makes that distinction explicit while preserving compact storage and the existing string accessor.
## Summary
Metaclasses can declare instance variables that their construction hooks
populate in every class they create. We already exposed these attributes
on the class object, but instance lookup only searched the constructed
class's ordinary MRO. As a result, custom enum classes could fail
protocol checks even though their metaclass populated the required
attributes at runtime.
Treat an annotation-only instance declaration directly on the concrete
metaclass as a contract for an attribute stored in each constructed
class namespace:
```python
class Meta(type):
generated: int
def __new__(mcls, name: str, bases: tuple[type, ...], namespace: dict[str, object]):
namespace["generated"] = 1
return super().__new__(mcls, name, bases, namespace)
class C(metaclass=Meta): ...
reveal_type(C().generated) # int
```
The new lookup preserves normal class and instance precedence, including
data descriptors, dynamic bases, and implicit special-method lookup.
Bound metaclass attributes and inferred method writes remain excluded
from this contract. The mdtests cover the motivating protocol case along
with the relevant class, instance, and descriptor interactions.
Closes astral-sh/ty#3535.
…ions - sort pep695 typevar-removal iteration and merge rename frames via extend (new iter-over-hash-type lint) - regenerate uv.lock for the merged [dependency-groups] - accept ci-gate inline snapshots (.pyi->.byi paths, ty->by binary name, fork doc urls, 0.0.3 crate versions); rustfmt pass - pack class-header bools into ClassLiteralFlags (salsa 12-field limit), add IS_ENUM_VARIANT so upstream's has_type_params fast path doesn't skip variant generic-context inheritance - expand a payload-enum-bounded Self to its variant union in expand_type so match self stays exhaustive under upstream's new coverage analysis - gate upstream's ~T negation-type syntax and BitAnd runtime probe to standard python files - port covariant-projection write check into attribute_assignment.rs - rewire based payload-enum split from deleted narrow.rs helpers into type_expansion.rs - update mdtest expectations for fork divergences (covariant Mapping key, typeshed typevar names, is_subtype_of moved to ty_extensions._internal) - dedupe [dependency-groups] in pyproject.toml - regenerate ty docs (cargo dev generate-all)
- windows cli snapshot: the merged filter regex still matched `ty` while the binary is `by`, so `by.exe` wasn't normalized to `by` — retarget to `by` - restore primer/good.txt (upstream deleted it moving to all-projects); the fork's ecosystem-roundtrip harness reads it as its default project list
the standalone `crates/basedpython` wheel crate (its own workspace, built by maturin with --locked) had a stale Cargo.lock after the merge bumped workspace dependency versions; `maturin build --locked` refused to update it, failing every wheel-build platform. regenerate with `cargo update --workspace`
- remove the cargo-publish-dry-run job (upstream re-added it in a non-conflicting merge region; the fork had deleted it). the fork keeps ruff/ty crate versions in lock-step with astral's crates.io versions but modifies their apis, so `cargo publish --dry-run` resolves a published crate for a transitive dep and fails on api skew. the fork publishes only the basedpython wheel to pypi, never these crates - bump cargo-test-linux and cargo-test-(windows/macos) timeouts 20 -> 45 min: the merged test count overruns the depot-tuned 20-minute budget on the fork's slower ubuntu-latest/windows-latest runners (both timed out mid-suite)
the formatter ecosystem check intermittently failed with a single project error — `ruff format --preview` emitting many pathless `No such file or directory (os error 2)` from the parallel file walk on one large project (a different one each run: ibis, then airflow). root cause is load: ruff-ecosystem defaults to 50 concurrent projects, each running a 12-thread `buff format` walk plus git clone/reset. on the fork's small `ubuntu-latest` runner this massively oversubscribes cpu and fs and the parallel walk transiently races; astral's 32-core depot runner absorbs it, so upstream stays green. the walker code itself is byte-identical to upstream. add a `--max-parallelism` flag to the vendored ruff-ecosystem cli (default unchanged at 50) and pass `--max-parallelism 2` for the two `format` runs. the read-only `check` runs never errored, so they keep the default. not reproducible locally on macos (linux/load-specific); validated the flag plumbing end-to-end. the 360-minute job budget absorbs the slower run.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.