Module: StillActive::Pep440Helper
Overview
Translates a PEP 440 requires_python specifier into a RubyGems requirement
STRING, so the generic RuntimeCeilingHelper can reason about a Python runtime
ceiling with no core change -- the same way Ruby's ruby_version already
feeds it. PEP 440 and RubyGems disagree on two operators that matter here:
- `~=` (compatible release) is a syntax error to Gem::Requirement, so a
naive parse raises and the ceiling is silently missed. It maps cleanly to
RubyGems `~>` for the major.minor.patch shapes `requires_python` uses.
- `== X.*` / `== X.Y.*` prefix wildcards are likewise unparseable and map to
a pessimistic `~>` over the prefix.
!= exclusions are dropped: a hole-punch can never create an upper bound, so
it cannot be a runtime ceiling, and dropping it can only ADMIT more runtimes
(fewer findings) -- conservative, never a false ceiling. Anything that still
won't parse degrades to a dropped clause (or nil overall), never a raise: this
feeds the core audit and must fail safe, matching RuntimeCeilingHelper's
best-effort contract.
Constant Summary collapse
- MAX_SPECIFIER_LENGTH =
Match ConstraintHelper / RuntimeCeilingHelper: bound pathological registry input before it reaches Gem::Requirement's own regex.
256- CLAUSE_PATTERN =
Operator, then the version as a run of non-space chars.
\s*(\S+)(not\s*(.+)) keeps the two groups over disjoint character classes so there's no polynomial backtracking on pathological input like "<" + many spaces (a PEP 440 version never contains internal spaces, so this loses nothing). /\A(===|==|~=|!=|<=|>=|<|>)\s*(\S+)\z/
Instance Method Summary collapse
-
#to_gem_requirement_string(specifier) ⇒ Object
=> a comma-joined RubyGems requirement string, or nil when nothing usable survives translation.
Instance Method Details
#to_gem_requirement_string(specifier) ⇒ Object
=> a comma-joined RubyGems requirement string, or nil when nothing usable
survives translation. The caller feeds the string to RuntimeCeilingHelper,
which splits and splats it exactly like a ruby_version string.
37 38 39 40 41 42 43 44 45 |
# File 'lib/helpers/pep440_helper.rb', line 37 def to_gem_requirement_string(specifier) spec = specifier.to_s return if spec.strip.empty? || spec.length > MAX_SPECIFIER_LENGTH clauses = spec.split(",").filter_map { |clause| translate_clause(clause.strip) } return if clauses.empty? clauses.join(", ") end |