diff --git a/.github/workflows/mypy_primer.yaml b/.github/workflows/mypy_primer.yaml
index 90c43c212c..d64aa00166 100644
--- a/.github/workflows/mypy_primer.yaml
+++ b/.github/workflows/mypy_primer.yaml
@@ -49,46 +49,12 @@ jobs:
- name: Run mypy_primer
shell: bash
env:
- TY_MEMORY_REPORT: mypy_primer
+ PRIMER_SELECTOR: crates/ty_python_semantic/resources/primer/good.txt
+ DIFF_FILE: mypy_primer.diff
run: |
cd ruff
-
- echo "Enabling mypy primer specific configuration overloads (see .github/mypy-primer-ty.toml)"
- mkdir -p ~/.config/ty
- cp .github/mypy-primer-ty.toml ~/.config/ty/ty.toml
-
- PRIMER_SELECTOR="$(paste -s -d'|' crates/ty_python_semantic/resources/primer/good.txt)"
-
- echo "new commit"
- git rev-list --format=%s --max-count=1 "$GITHUB_SHA"
-
- MERGE_BASE="$(git merge-base "$GITHUB_SHA" "origin/$GITHUB_BASE_REF")"
- git checkout -b base_commit "$MERGE_BASE"
- echo "base commit"
- git rev-list --format=%s --max-count=1 base_commit
-
- cd ..
-
- echo "Project selector: $PRIMER_SELECTOR"
- # Allow the exit code to be 0 or 1, only fail for actual mypy_primer crashes/bugs
- uvx \
- --from="git+https://github.com/hauntsaninja/mypy_primer@e5f55447969d33ae3c7ccdb183e2a37101867270" \
- mypy_primer \
- --repo ruff \
- --type-checker ty \
- --old base_commit \
- --new "$GITHUB_SHA" \
- --project-selector "/($PRIMER_SELECTOR)\$" \
- --output concise \
- --debug > mypy_primer.diff || [ $? -eq 1 ]
-
- # Output diff with ANSI color codes
- cat mypy_primer.diff
-
- # Remove ANSI color codes before uploading
- sed -ie 's/\x1b\[[0-9;]*m//g' mypy_primer.diff
-
- echo ${{ github.event.number }} > pr-number
+ scripts/mypy_primer.sh
+ echo ${{ github.event.number }} > ../pr-number
- name: Upload diff
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
@@ -101,3 +67,41 @@ jobs:
with:
name: pr-number
path: pr-number
+
+ memory_usage:
+ name: Run memory statistics
+ runs-on: depot-ubuntu-22.04-32
+ timeout-minutes: 20
+ steps:
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ path: ruff
+ fetch-depth: 0
+ persist-credentials: false
+
+ - name: Install the latest version of uv
+ uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba # v6.3.1
+
+ - uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
+ with:
+ workspaces: "ruff"
+
+ - name: Install Rust toolchain
+ run: rustup show
+
+ - name: Run mypy_primer
+ shell: bash
+ env:
+ TY_MAX_PARALLELISM: 1 # for deterministic memory numbers
+ TY_MEMORY_REPORT: mypy_primer
+ PRIMER_SELECTOR: crates/ty_python_semantic/resources/primer/memory.txt
+ DIFF_FILE: mypy_primer_memory.diff
+ run: |
+ cd ruff
+ scripts/mypy_primer.sh
+
+ - name: Upload diff
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
+ with:
+ name: mypy_primer_memory_diff
+ path: mypy_primer_memory.diff
diff --git a/.github/workflows/mypy_primer_comment.yaml b/.github/workflows/mypy_primer_comment.yaml
index 85c3367780..895956e766 100644
--- a/.github/workflows/mypy_primer_comment.yaml
+++ b/.github/workflows/mypy_primer_comment.yaml
@@ -45,15 +45,28 @@ jobs:
if_no_artifact_found: ignore
allow_forks: true
+ - uses: dawidd6/action-download-artifact@20319c5641d495c8a52e688b7dc5fada6c3a9fbc # v8
+ name: "Download mypy_primer memory results"
+ id: download-mypy_primer_memory_diff
+ if: steps.pr-number.outputs.pr-number
+ with:
+ name: mypy_primer_memory_diff
+ workflow: mypy_primer.yaml
+ pr: ${{ steps.pr-number.outputs.pr-number }}
+ path: pr/mypy_primer_memory_diff
+ workflow_conclusion: completed
+ if_no_artifact_found: ignore
+ allow_forks: true
+
- name: Generate comment content
id: generate-comment
- if: steps.download-mypy_primer_diff.outputs.found_artifact == 'true'
+ if: ${{ steps.download-mypy_primer_diff.outputs.found_artifact == 'true' && steps.download-mypy_primer_memory_diff.outputs.found_artifact == 'true' }}
run: |
# Guard against malicious mypy_primer results that symlink to a secret
# file on this runner
- if [[ -L pr/mypy_primer_diff/mypy_primer.diff ]]
+ if [[ -L pr/mypy_primer_diff/mypy_primer.diff ]] || [[ -L pr/mypy_primer_memory_diff/mypy_primer_memory.diff ]]
then
- echo "Error: mypy_primer.diff cannot be a symlink"
+ echo "Error: mypy_primer.diff and mypy_primer_memory.diff cannot be a symlink"
exit 1
fi
@@ -74,6 +87,18 @@ jobs:
echo 'No ecosystem changes detected ✅' >> comment.txt
fi
+ if [ -s "pr/mypy_primer_memory_diff/mypy_primer_memory.diff" ]; then
+ echo '' >> comment.txt
+ echo 'Memory usage changes were detected when running on open source projects
' >> comment.txt
+ echo '' >> comment.txt
+ echo '```diff' >> comment.txt
+ cat pr/mypy_primer_memory_diff/mypy_primer_memory.diff >> comment.txt
+ echo '```' >> comment.txt
+ echo ' ' >> comment.txt
+ else
+ echo 'No memory usage changes detected ✅' >> comment.txt
+ fi
+
echo 'comment<> "$GITHUB_OUTPUT"
cat comment.txt >> "$GITHUB_OUTPUT"
echo 'EOF' >> "$GITHUB_OUTPUT"
diff --git a/crates/ty/src/lib.rs b/crates/ty/src/lib.rs
index a83b946ea2..81305c45cb 100644
--- a/crates/ty/src/lib.rs
+++ b/crates/ty/src/lib.rs
@@ -296,6 +296,11 @@ impl MainLoop {
tracing::warn!("No python files found under the given path(s)");
}
+ // TODO: We should have an official flag to silence workspace diagnostics.
+ if std::env::var("TY_MEMORY_REPORT").as_deref() == Ok("mypy_primer") {
+ return Ok(ExitStatus::Success);
+ }
+
let mut stdout = stdout().lock();
if result.is_empty() {
diff --git a/crates/ty_project/src/db.rs b/crates/ty_project/src/db.rs
index cda81a9192..9f15d612dd 100644
--- a/crates/ty_project/src/db.rs
+++ b/crates/ty_project/src/db.rs
@@ -324,8 +324,8 @@ impl SalsaMemoryDump {
struct DisplayShort<'a>(&'a SalsaMemoryDump);
fn round_memory(total: usize) -> usize {
- // Round the number to the nearest power of 1.1. This gives us a
- // 5% threshold before the memory usage number is considered to have
+ // Round the number to the nearest power of 1.05. This gives us a
+ // 2.5% threshold before the memory usage number is considered to have
// changed.
//
// TODO: Small changes in memory usage may cause the number to be rounded
@@ -334,7 +334,7 @@ impl SalsaMemoryDump {
// over time that are unrelated to the current change. Ideally we could compare
// the exact numbers across runs and compute the difference, but we don't have
// the infrastructure for that currently.
- const BASE: f64 = 1.1;
+ const BASE: f64 = 1.05;
BASE.powf(bytes_to_mb(total).log(BASE).round()) as usize
}
diff --git a/crates/ty_python_semantic/resources/primer/memory.txt b/crates/ty_python_semantic/resources/primer/memory.txt
new file mode 100644
index 0000000000..ed55f3ea57
--- /dev/null
+++ b/crates/ty_python_semantic/resources/primer/memory.txt
@@ -0,0 +1,4 @@
+flake8
+sphinx
+prefect
+trio
diff --git a/scripts/mypy_primer.sh b/scripts/mypy_primer.sh
new file mode 100755
index 0000000000..4c45c9d6ee
--- /dev/null
+++ b/scripts/mypy_primer.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+
+echo "Enabling mypy primer specific configuration overloads (see .github/mypy-primer-ty.toml)"
+mkdir -p ~/.config/ty
+cp .github/mypy-primer-ty.toml ~/.config/ty/ty.toml
+
+PRIMER_SELECTOR="$(paste -s -d'|' $PRIMER_SELECTOR)"
+
+echo "new commit"
+git rev-list --format=%s --max-count=1 "$GITHUB_SHA"
+
+MERGE_BASE="$(git merge-base "$GITHUB_SHA" "origin/$GITHUB_BASE_REF")"
+git checkout -b base_commit "$MERGE_BASE"
+echo "base commit"
+git rev-list --format=%s --max-count=1 base_commit
+
+cd ..
+
+echo "Project selector: $PRIMER_SELECTOR"
+# Allow the exit code to be 0 or 1, only fail for actual mypy_primer crashes/bugs
+uvx \
+ --from="git+https://github.com/hauntsaninja/mypy_primer@e5f55447969d33ae3c7ccdb183e2a37101867270" \
+ mypy_primer \
+ --repo ruff \
+ --type-checker ty \
+ --old base_commit \
+ --new "$GITHUB_SHA" \
+ --project-selector "/($PRIMER_SELECTOR)\$" \
+ --output concise \
+ --debug > $DIFF_FILE || [ $? -eq 1 ]
+
+# Output diff with ANSI color codes
+cat $DIFF_FILE
+
+# Remove ANSI color codes before uploading
+sed -ie 's/\x1b\[[0-9;]*m//g' $DIFF_FILE