Skip to content

Commit

Permalink
Remove python_new_version feature flag
Browse files Browse the repository at this point in the history
  • Loading branch information
amazimbe committed Oct 23, 2024
1 parent eb77cb3 commit cfaeea1
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 151 deletions.
1 change: 1 addition & 0 deletions maven/spec/dependabot/maven/version_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
let(:err_msg) { "Malformed version string - string is nil" }

it "raises an exception" do
debugger
expect { version }.to raise_error(Dependabot::BadRequirementError, err_msg)
end
end
Expand Down
18 changes: 4 additions & 14 deletions python/lib/dependabot/python/requirement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Requirement < Dependabot::Requirement
.map { |k| Regexp.quote(k) }.join("|")
version_pattern = Python::Version::VERSION_PATTERN

PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{version_pattern})\\s*".freeze
PATTERN_RAW = "\\s*(?<op>#{quoted})?\\s*(?<version>#{version_pattern})\\s*".freeze
PATTERN = /\A#{PATTERN_RAW}\z/
PARENS_PATTERN = /\A\(([^)]+)\)\z/

Expand All @@ -36,24 +36,14 @@ def self.parse(obj)
line = matches[1]
end

pattern = PATTERN

if Dependabot::Experiments.enabled?(:python_new_version)
quoted = OPS.keys.sort_by(&:length).reverse
.map { |k| Regexp.quote(k) }.join("|")
version_pattern = Python::Version::NEW_VERSION_PATTERN
pattern_raw = "\\s*(?<op>#{quoted})?\\s*(?<version>#{version_pattern})\\s*".freeze
pattern = /\A#{pattern_raw}\z/
end

unless (matches = pattern.match(line))
unless (matches = PATTERN.match(line))
msg = "Illformed requirement [#{obj.inspect}]"
raise BadRequirementError, msg
end

return DefaultRequirement if matches[1] == ">=" && matches[2] == "0"
return DefaultRequirement if matches[:op] == ">=" && matches[:version] == "0"

[matches[1] || "=", Python::Version.new(T.must(matches[2]))]
[matches[:op] || "=", Python::Version.new(T.must(matches[:version]))]
end

# Returns an array of requirements. At least one requirement from the
Expand Down
152 changes: 24 additions & 128 deletions python/lib/dependabot/python/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,11 @@ class Version < Dependabot::Version
sig { returns(T.nilable(T::Array[T.any(String, Integer)])) }
attr_reader :local

attr_reader :local_version
attr_reader :post_release_version

INFINITY = 1000
NEGATIVE_INFINITY = -INFINITY

# See https://peps.python.org/pep-0440/#appendix-b-parsing-version-strings-with-regular-expressions
NEW_VERSION_PATTERN = /
VERSION_PATTERN = /
v?
(?:
(?:(?<epoch>[0-9]+)!)? # epoch
Expand Down Expand Up @@ -65,62 +62,37 @@ class Version < Dependabot::Version
(?:\+(?<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
/ix

VERSION_PATTERN = 'v?([1-9][0-9]*!)?[0-9]+[0-9a-zA-Z]*(?>\.[0-9a-zA-Z]+)*' \
'(-[0-9A-Za-z]+(\.[0-9a-zA-Z]+)*)?' \
'(\+[0-9a-zA-Z]+(\.[0-9a-zA-Z]+)*)?'

ANCHORED_VERSION_PATTERN = /\A\s*#{VERSION_PATTERN}\s*\z/

sig { override.params(version: VersionParameter).returns(T::Boolean) }
def self.correct?(version)
return false if version.nil?

if Dependabot::Experiments.enabled?(:python_new_version)
version.to_s.match?(/\A\s*#{NEW_VERSION_PATTERN}\s*\z/o)
else
version.to_s.match?(ANCHORED_VERSION_PATTERN)
end
version.to_s.match?(ANCHORED_VERSION_PATTERN)
end

sig { override.params(version: VersionParameter).void }
def initialize(version) # rubocop:disable Metrics/AbcSize,Metrics/PerceivedComplexity
def initialize(version)
raise Dependabot::BadRequirementError, "Malformed version string - string is nil" if version.nil?

@version_string = version.to_s

raise Dependabot::BadRequirementError, "Malformed version string - string is empty" if @version_string.empty?

matches = anchored_version_pattern.match(@version_string.downcase)
matches = ANCHORED_VERSION_PATTERN.match(@version_string.downcase)

unless matches
raise Dependabot::BadRequirementError,
"Malformed version string - #{@version_string} does not match regex"
end

if Dependabot::Experiments.enabled?(:python_new_version)
@epoch = matches["epoch"].to_i
@release_segment = matches["release"]&.split(".")&.map(&:to_i) || []
@pre = parse_letter_version(matches["pre_l"], matches["pre_n"])
@post = parse_letter_version(matches["post_l"], matches["post_n1"] || matches["post_n2"])
@dev = parse_letter_version(matches["dev_l"], matches["dev_n"])
@local = parse_local_version(matches["local"])
super(matches["release"] || "")
else
version, @local_version = @version_string.split("+")
version ||= ""
version = version.gsub(/^v/, "")
if version.include?("!")
epoch, version = version.split("!")
@epoch = epoch.to_i
else
@epoch = 0
end
version = normalise_prerelease(version)
version, @post_release_version = version.split(/\.r(?=\d)/)
version ||= ""
@local_version = normalise_prerelease(@local_version) if @local_version
super
end
@epoch = matches["epoch"].to_i
@release_segment = matches["release"]&.split(".")&.map(&:to_i) || []
@pre = parse_letter_version(matches["pre_l"], matches["pre_n"])
@post = parse_letter_version(matches["post_l"], matches["post_n1"] || matches["post_n2"])
@dev = parse_letter_version(matches["dev_l"], matches["dev_n"])
@local = parse_local_version(matches["local"])
super(matches["release"] || "")
end

sig { override.params(version: VersionParameter).returns(Dependabot::Python::Version) }
Expand All @@ -140,52 +112,35 @@ def inspect # :nodoc:

sig { returns(T::Boolean) }
def prerelease?
return super unless Dependabot::Experiments.enabled?(:python_new_version)

!!(pre || dev)
end

sig { returns(T.any(Gem::Version, Dependabot::Python::Version)) }
sig { returns(Dependabot::Python::Version) }
def release
return super unless Dependabot::Experiments.enabled?(:python_new_version)

Dependabot::Python::Version.new(release_segment.join("."))
end

sig { params(other: VersionParameter).returns(Integer) }
def <=>(other) # rubocop:disable Metrics/AbcSize,Metrics/PerceivedComplexity
def <=>(other)
other = Dependabot::Python::Version.new(other.to_s) unless other.is_a?(Dependabot::Python::Version)
other = T.cast(other, Dependabot::Python::Version)

if Dependabot::Experiments.enabled?(:python_new_version)
epoch_comparison = epoch <=> other.epoch
return epoch_comparison unless epoch_comparison.zero?
epoch_comparison = epoch <=> other.epoch
return epoch_comparison unless epoch_comparison.zero?

release_comparison = release_version_comparison(other)
return release_comparison unless release_comparison.zero?
release_comparison = release_version_comparison(other)
return release_comparison unless release_comparison.zero?

pre_comparison = compare_keys(pre_cmp_key, other.pre_cmp_key)
return pre_comparison unless pre_comparison.zero?
pre_comparison = compare_keys(pre_cmp_key, other.pre_cmp_key)
return pre_comparison unless pre_comparison.zero?

post_comparison = compare_keys(post_cmp_key, other.post_cmp_key)
return post_comparison unless post_comparison.zero?
post_comparison = compare_keys(post_cmp_key, other.post_cmp_key)
return post_comparison unless post_comparison.zero?

dev_comparison = compare_keys(dev_cmp_key, other.dev_cmp_key)
return dev_comparison unless dev_comparison.zero?
dev_comparison = compare_keys(dev_cmp_key, other.dev_cmp_key)
return dev_comparison unless dev_comparison.zero?

compare_keys(local_cmp_key, other.local_cmp_key)
else
epoch_comparison = epoch_comparison(other)
return epoch_comparison unless epoch_comparison.zero?

version_comparison = super
return T.must(version_comparison) unless version_comparison&.zero?

post_version_comparison = post_version_comparison(other)
return post_version_comparison unless post_version_comparison.zero?

local_version_comparison(other)
end
compare_keys(local_cmp_key, other.local_cmp_key)
end

sig do
Expand Down Expand Up @@ -321,65 +276,6 @@ def parse_letter_version(letter = nil, number = nil)

[letter, number.to_i]
end

sig { returns(Regexp) }
def anchored_version_pattern
if Dependabot::Experiments.enabled?(:python_new_version)
/\A\s*#{NEW_VERSION_PATTERN}\s*\z/o
else
ANCHORED_VERSION_PATTERN
end
end

def epoch_comparison(other)
epoch.to_i <=> other.epoch.to_i
end

def post_version_comparison(other)
unless other.post_release_version
return post_release_version.nil? ? 0 : 1
end

return -1 if post_release_version.nil?

post_release_version.to_i <=> other.post_release_version.to_i
end

def local_version_comparison(other)
# Local version comparison works differently in Python: `1.0.beta`
# compares as greater than `1.0`. To accommodate, we make the
# strings the same length before comparing.
lhsegments = local_version.to_s.split(".").map(&:downcase)
rhsegments = other.local_version.to_s.split(".").map(&:downcase)
limit = [lhsegments.count, rhsegments.count].min

lhs = ["1", *lhsegments.first(limit)].join(".")
rhs = ["1", *rhsegments.first(limit)].join(".")

local_comparison = Gem::Version.new(lhs) <=> Gem::Version.new(rhs)

return local_comparison unless local_comparison&.zero?

lhsegments.count <=> rhsegments.count
end

def normalise_prerelease(version)
# Python has reserved words for release states, which are treated
# as equal (e.g., preview, pre and rc).
# Further, Python treats dashes as a separator between version
# parts and treats the alphabetical characters in strings as the
# start of a new version part (so 1.1a2 == 1.1.alpha.2).
version
.gsub("alpha", "a")
.gsub("beta", "b")
.gsub("preview", "c")
.gsub("pre", "c")
.gsub("post", "r")
.gsub("rev", "r")
.gsub(/([\d.\-_])rc([\d.\-_])?/, '\1c\2')
.tr("-", ".")
.gsub(/(\d)([a-z])/i, '\1.\2')
end
end
end
end
Expand Down
10 changes: 1 addition & 9 deletions python/spec/dependabot/python/version_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
describe ".correct?" do
subject { described_class.correct?(version_string) }

before do
Dependabot::Experiments.register(:python_new_version, true)
end

context "with a valid version" do
let(:version_string) { "1.0.0" }

Expand Down Expand Up @@ -148,7 +144,7 @@
"1.0.0-rc.1",
"1",
"1.0.0+gc1",
# "1.0.0.post", TODO fails comparing to 1
"1.0.0.post", # TODO: fails comparing to 1
"1.post2",
"1.post2+gc1",
"1.post2+gc1.2",
Expand Down Expand Up @@ -239,10 +235,6 @@

let(:versions) { version_strings.map { |v| described_class.new(v) } }

before do
Dependabot::Experiments.register(:python_new_version, true)
end

it "returns list in the correct order" do
expect(versions.shuffle.sort).to eq versions
end
Expand Down

0 comments on commit cfaeea1

Please sign in to comment.