co-authored by OpenAI GPT-5.5
Problem
vyupgrade --target-version 0.5.0a2 --write currently rewrites source pragmas to an exact target pragma:
For migrated contracts, it would often be nicer to emit a looser accepted range, for example:
#pragma version >=0.5.0a2,<0.6.0
The tool already accepts a version spec as --target-version and validates against the resolved compiler version, so users can work around this today with:
vyupgrade --target-version '>=0.5.0a2,<0.6.0' --write contract.vy
But that behavior is not obvious, and it couples compiler target selection with the pragma text written to source.
Design options
1. Document the existing behavior
Document that --target-version accepts a version spec, not just an exact version.
Example:
vyupgrade --target-version '>=0.5.0a2,<0.6.0' --write contract.vy
Pros:
- Minimal implementation.
- Keeps current semantics.
- Existing validation path remains unchanged.
Cons:
- Still overloads
--target-version as both compiler selection and emitted pragma text.
- Users may expect
--target-version 0.5.0a2 to produce a practical loose pragma.
2. Add an output-only pragma option
Add a separate flag for the pragma text to write:
vyupgrade --target-version 0.5.0a2 \
--pragma-version '>=0.5.0a2,<0.6.0' \
--write contract.vy
Semantics:
--target-version selects the target compiler and migration rule context.
--pragma-version controls only the source pragma emitted by VY001 and target validation overlays.
Pros:
- Clean separation of compiler target vs source pragma policy.
- Keeps exact compiler-backed validation explicit.
- Backward compatible.
Cons:
- Adds another CLI/config option.
- Need to decide whether validation overlays use target compiler version or pragma output text.
3. Add a pragma policy option
Add a higher-level policy:
vyupgrade --target-version 0.5.0a2 --pragma-policy minor-range --write contract.vy
Possible policies:
exact -> #pragma version 0.5.0a2
minor-range -> #pragma version >=0.5.0a2,<0.6.0
preserve -> keep existing pragma if it admits the target; otherwise rewrite
none -> do not rewrite/add version pragmas
Pros:
- Easier common-case UX than manually writing specs.
- Can preserve old behavior with
exact as the default.
- Gives clear user intent.
Cons:
- More behavior to specify and test.
preserve requires careful version-spec satisfiability checks.
4. Change the default output to a compatible range
For exact target input, emit a range by default:
0.4.3 -> >=0.4.3,<0.5.0
0.5.0a2 -> >=0.5.0a2,<0.6.0
Pros:
- Best default output for many users.
- No extra flags.
Cons:
- Breaking output change.
- Some users may want exact, reproducible compiler pragmas.
- Needs careful prerelease semantics.
5. Preserve-compatible rewrite only
If an existing pragma already admits the target version, leave it alone. Only rewrite when the target is excluded.
Examples:
#pragma version >=0.4.0,<0.6.0
Target 0.5.0a2: leave unchanged.
#pragma version >=0.4.0,<0.5.0
Target 0.5.0a2: rewrite to a compatible target range.
Pros:
- Avoids unnecessary pragma churn.
- Aligns with least-surprise migration behavior.
Cons:
- Existing broad pragmas can still include source versions that no longer parse migrated syntax.
- Needs a clear safety rule for when preserving is valid.
Tentative preference
A conservative implementation could combine options 2 and 3:
- Keep
--target-version as the exact compiler/migration target.
- Add
--pragma-version for explicit emitted text.
- Add
--pragma-policy exact|minor-range|preserve|none, defaulting to current exact behavior.
That keeps the validation path precise while giving users direct control over source pragma looseness.
co-authored by OpenAI GPT-5.5
Problem
vyupgrade --target-version 0.5.0a2 --writecurrently rewrites source pragmas to an exact target pragma:#pragma version 0.5.0a2For migrated contracts, it would often be nicer to emit a looser accepted range, for example:
#pragma version >=0.5.0a2,<0.6.0The tool already accepts a version spec as
--target-versionand validates against the resolved compiler version, so users can work around this today with:vyupgrade --target-version '>=0.5.0a2,<0.6.0' --write contract.vyBut that behavior is not obvious, and it couples compiler target selection with the pragma text written to source.
Design options
1. Document the existing behavior
Document that
--target-versionaccepts a version spec, not just an exact version.Example:
vyupgrade --target-version '>=0.5.0a2,<0.6.0' --write contract.vyPros:
Cons:
--target-versionas both compiler selection and emitted pragma text.--target-version 0.5.0a2to produce a practical loose pragma.2. Add an output-only pragma option
Add a separate flag for the pragma text to write:
vyupgrade --target-version 0.5.0a2 \ --pragma-version '>=0.5.0a2,<0.6.0' \ --write contract.vySemantics:
--target-versionselects the target compiler and migration rule context.--pragma-versioncontrols only the source pragma emitted by VY001 and target validation overlays.Pros:
Cons:
3. Add a pragma policy option
Add a higher-level policy:
Possible policies:
Pros:
exactas the default.Cons:
preserverequires careful version-spec satisfiability checks.4. Change the default output to a compatible range
For exact target input, emit a range by default:
Pros:
Cons:
5. Preserve-compatible rewrite only
If an existing pragma already admits the target version, leave it alone. Only rewrite when the target is excluded.
Examples:
#pragma version >=0.4.0,<0.6.0Target
0.5.0a2: leave unchanged.#pragma version >=0.4.0,<0.5.0Target
0.5.0a2: rewrite to a compatible target range.Pros:
Cons:
Tentative preference
A conservative implementation could combine options 2 and 3:
--target-versionas the exact compiler/migration target.--pragma-versionfor explicit emitted text.--pragma-policy exact|minor-range|preserve|none, defaulting to current exact behavior.That keeps the validation path precise while giving users direct control over source pragma looseness.