Skip to content

fix: detect modern vyper version pragmas - #166

Merged
fubuloubu merged 1 commit into
ApeWorX:mainfrom
banteg:feat/vyper-pragma-version
May 9, 2026
Merged

fix: detect modern vyper version pragmas#166
fubuloubu merged 1 commit into
ApeWorX:mainfrom
banteg:feat/vyper-pragma-version

Conversation

@banteg

@banteg banteg commented May 9, 2026

Copy link
Copy Markdown
Contributor

Motivation

Current Vyper accepts source compiler constraints in both legacy # @version ... comments and modern # pragma version ... comments. ape-vyper only recognized the legacy spelling, so modern Vyper sources could be grouped with no-pragma sources and compiled with the wrong selected compiler before Vyper itself validated the source constraint.

Vyper also changed the version-pragma grammar across releases: v0.3.9 and earlier use npm-style semantic version specs, while v0.3.10 and newer use packaging.specifiers.SpecifierSet-style rules after caret translation. Ape needs to use the rules for each candidate compiler version, otherwise compiler selection can accept or reject a pragma differently than Vyper would.

Malformed present pragmas now fail early as VyperCompileError instead of being treated as missing pragmas.

Code References

Summary

  • Recognize both # @version ... and # pragma version ....
  • Preserve whitespace tolerance for #pragma version ....
  • Match candidate compiler versions using Vyper's release-specific grammar: npm-style for <0.3.10, PEP 440-style for >=0.3.10.
  • Add semantic-version for the legacy npm-style grammar.
  • Raise a clear VyperCompileError when a present version pragma cannot be parsed.
  • Add focused parser and version-map coverage, including cases adapted from Vyper's pre-parser tests.

Tests

  • git diff --check
  • uv run --group lint ruff check .
  • uv run --group lint ruff format --check .
  • uv run --group lint --group test mypy .
  • uv run --python 3.11 --group test python -m py_compile ape_vyper/_utils.py ape_vyper/compiler/api.py tests/functional/test_compiler.py
  • uv run --python 3.11 --group test pytest tests/functional/test_compiler.py -q -k "version_pragma_spec or version_map_modern_pragma or version_map_invalid_pragma" (29 passed, 102 deselected)

Note: uv run --python 3.11 --group test pytest tests/functional/test_compiler.py -q was also attempted locally. The compile-heavy cases failed after vvm.get_installable_vyper_versions() hit the GitHub API rate limit, leaving no installable 0.4.x compiler for the existing 0.4 fixtures. The focused parser/version-map coverage above passes.

@banteg
banteg force-pushed the feat/vyper-pragma-version branch 4 times, most recently from 8e58fba to 62c7358 Compare May 9, 2026 13:19
Comment thread ape_vyper/_utils.py Outdated
@banteg
banteg force-pushed the feat/vyper-pragma-version branch from 62c7358 to 866d4f2 Compare May 9, 2026 13:42
@fubuloubu
fubuloubu enabled auto-merge (squash) May 9, 2026 13:43
@fubuloubu
fubuloubu merged commit bf248da into ApeWorX:main May 9, 2026
15 checks passed
Comment thread ape_vyper/_utils.py


def _as_pep440_spec(pragma_str: str) -> str:
pragma_str = pragma_str.replace("^", "~=")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong for post 1.0 vyper

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a direct port of how vyper itself does it https://github.com/vyperlang/vyper/blob/c219e6be2f230931be19a8eb945dc432538f9245/vyper/ast/pre_parser.py#L30

from my understanding ^1.0.0 in semver is >=1.0.0 <2.0.0
while the rewritten ~=1.0.0 in pep440 becomes >=1.0.0 <1.1.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants