Skip to content

Commit 0a6ae92

Browse files
committed
docs(version-scanner): merge migration guide into README.md
1 parent a1188c8 commit 0a6ae92

1 file changed

Lines changed: 126 additions & 0 deletions

File tree

scripts/version_scanner/README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,129 @@ You can create a `.scannerignore` file in the directory you are scanning (usuall
3232

3333
## Known Issues & Future Investigations
3434
- **Binary Ignores in `.scannerignore`**: Recursive wildcard ignores (e.g., `*.jpg`) currently do not effectively ignore deeply nested binary files. The scanner logic should be investigated to support robust globbing or full-path suffix matching.
35+
36+
---
37+
38+
## Universal Prompt for EOL Runtime & Dependency Migration
39+
40+
### Context & Overview
41+
42+
#### Overview
43+
This plan outlines the approach to update Python packages to drop support for end-of-life Python runtimes (3.7, 3.8, 3.9) OR for deprecated dependencies, and ensure the packages are configured for modern Python.
44+
45+
#### High-Level Strategy
46+
- **One Branch Per Package**: To keep PRs manageable and isolated, we suggest a dedicated worktree and branch for each package (e.g., `feat/drop-<dependency>-<version>-<package-name>` i.e. `feat/drop-protobuf-4.25.8-google-cloud-bigquery`).
47+
- **Small & Reversible Commits**: Group changes into logical commits (Metadata, Nox, Docs, Cleanup, Tests) following Conventional Commits.
48+
49+
---
50+
51+
### Per-Package Workflow
52+
53+
Follow these steps for each package in the target list. Context and warnings are provided inline before the steps where they apply.
54+
55+
#### Step 1: Sync & Branch
56+
1. Ensure `main` branch is up to date.
57+
2. Create the feature branch: `git checkout -b feat/drop-<dependency>-<version>-<package-name>`.
58+
59+
#### Step 2: Scan (Baseline)
60+
1. Run the `version_scanner` for the package to get a list of all occurrences of the dependency and version.
61+
> [!TIP]
62+
> Use `# version-scanner: ignore` or `ignore-next-line` in code to silence true false-positives and maintain clean reports.
63+
64+
---
65+
66+
#### 💡 Context for Step 3: Standards & Cleanup
67+
*Before applying changes, review these standards to ensure consistency:*
68+
69+
##### Runtime Version Checks
70+
- **Standard**: Use `sys.version_info < (X, Y)`.
71+
- **Rationale**: Python compares tuples lexicographically, making this robust.
72+
- **Avoid**: `sys.version_info.minor < Y` or string conversions.
73+
74+
##### Pytest Skips
75+
- **Standard**: `@pytest.mark.skipif(sys.version_info < (X, Y), reason="Requires Python X.Y+")`.
76+
- **Avoid**: String-based conditions like `@pytest.mark.skipif("sys.version_info < ...")`.
77+
78+
##### Noxfile Version Matches
79+
- **Standard**: `session.python == "X.Y"` (Nox uses strings).
80+
- **Avoid**: `float(session.python) < X.Y` (fails for `3.10`).
81+
82+
##### Cleanup Rules
83+
- **Polyfills**: Remove dead `try/except` blocks guarding polyfills for features now standard in 3.10+.
84+
- **Obsolete Skips**: Remove pytest skips for features now universally available.
85+
86+
##### Dependency Specific rules
87+
- Use idiomatic python references to detect dependency versions and to compare against the target version.
88+
89+
---
90+
91+
#### 💡 Context for Step 3: Disposition Rules
92+
*Every reference to the dependency version found by the scanner must be dispositioned in one of these ways:*
93+
94+
1. **Update**: Update the reference if still necessary (e.g., changing `3.9` to `3.10` in support files).
95+
2. **Delete**: Delete if no longer relevant (dead code, obsolete comments).
96+
3. **Pragma Ignore**: Use `# version-scanner: ignore` or `# version-scanner: ignore-next-line` but ONLY for immutable historical facts or true false positives. Do NOT use for things that might change in future upgrades.
97+
98+
#### Step 3: Apply Changes
99+
1. Update `setup.py` or `pyproject.toml` metadata and `requires-python`.
100+
2. Update `noxfile.py` to remove old versions from sessions.
101+
3. Update `README.rst` and `CONTRIBUTING.rst` documentation.
102+
4. Remove compatibility code and skips based on the standards above.
103+
5. **Sync Documentation**: If the package has a `docs` folder containing a `README.rst`, copy the updated top-level `README.rst` to overwrite it (unless it is a symlink).
104+
6. Continue with the update process until all rows from the scan have been properly dispositioned.
105+
106+
---
107+
108+
#### Step 4: Verify (Post-Scan)
109+
1. Run the `version_scanner` again. The result should be 0 matches (or only valid ignores).
110+
111+
---
112+
113+
#### 💡 Context for Step 5: Constraints & Conflicts
114+
*Review these lessons learned when dealing with constraints:*
115+
116+
- **Lowest Runtime Constraints**: The file for the lowest accepted runtime (e.g., `constraints-3.10.txt`) must have pins matching the lowest acceptable versions in `setup.py` or `pyproject.toml`.
117+
- **Philosophy on Warnings**: Do not simply block warnings (like `six` or `pkg_resources`) to make tests pass. **Bump the lower bounds** of dependencies to versions that don't trigger warnings on the current lowest acceptable runtime. This protects customers who use strict warning filters.
118+
- **SQLAlchemy Transition**: For libraries supporting both 1.4 and 2.0, use `SQLALCHEMY_SILENCE_UBER_WARNING=1` in specific legacy Nox sessions rather than silencing globally.
119+
120+
---
121+
122+
#### Step 5: Local Test
123+
1. Run unit tests using Nox (e.g., `nox -s unit`).
124+
> [!TIP]
125+
> Use `nox -s unit-3.10` to save time when debugging specific runtime failures.
126+
2. Run `blacken` and `lint` sessions.
127+
128+
#### Step 6: Push & PR
129+
1. Push the branch and create the PR using the template in the Appendix.
130+
131+
---
132+
133+
## Appendix
134+
135+
### PR Template [^1]
136+
```text
137+
This PR updates `<dependency>` to establish version x.y.z as the minimum supported version.
138+
139+
### Changes
140+
* Configuration: Updated `setup.py` and `noxfile.py` to require <dependency> <version> and remove references to older versions.
141+
* Cleanup: Removed dead code and polyfills no longer needed.
142+
143+
Fixes internal issue: http://b/482126936 🦕
144+
```
145+
146+
---
147+
148+
## Candidates for `.conductor` or `gemini.md`
149+
150+
*The following guidelines are universal for AI assistants workin' in this repo and should be moved to `.conductor` files or Gemini memories:*
151+
152+
1. **AI & LLM Guidelines for Verification**:
153+
- Use Git Worktrees to scan branches without switching.
154+
- Run scanner from main branch pointing to worktree.
155+
- Bypass env artifacts by worktree only checking out tracked files.
156+
2. **Automated Bisection**:
157+
- Use `version_bisector.py` to find lowest workable versions.
158+
- Abort tests early as soon as collection succeeds to save time.
159+
160+
[^1]: Adapted from the standard PR template used in this repository.

0 commit comments

Comments
 (0)