dependabot-python 0.280.0 → 0.281.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/dependabot/python/requirement.rb +14 -3
- data/lib/dependabot/python/version.rb +288 -26
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1273f0793f6c0432a5a66468ec19a460c854eda211c935c45af189d1c7b11e9d
|
4
|
+
data.tar.gz: c938f342ad448550e12036631ecefe4623d5d16afebf21aa01bfe85a0c048ab2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2ae4f68e9cdba267b00989165544e24384d8cd10b58c99802066214fb0b354a9c331af03e8b611a0195eda2d6d760c8cb354584b29b3a7b0d7f42e8e14067a7
|
7
|
+
data.tar.gz: 39a45d259c975b32debd5f3d21edd53622fb863630da7fe0bdafb6170f6adde5e3f556c36896cac357475b14797ac878855c4b9d171f7d29799bc8bd8ac20854
|
@@ -36,7 +36,17 @@ module Dependabot
|
|
36
36
|
line = matches[1]
|
37
37
|
end
|
38
38
|
|
39
|
-
|
39
|
+
pattern = PATTERN
|
40
|
+
|
41
|
+
if Dependabot::Experiments.enabled?(:python_new_version)
|
42
|
+
quoted = OPS.keys.sort_by(&:length).reverse
|
43
|
+
.map { |k| Regexp.quote(k) }.join("|")
|
44
|
+
version_pattern = Python::Version::NEW_VERSION_PATTERN
|
45
|
+
pattern_raw = "\\s*(?<op>#{quoted})?\\s*(?<version>#{version_pattern})\\s*".freeze
|
46
|
+
pattern = /\A#{pattern_raw}\z/
|
47
|
+
end
|
48
|
+
|
49
|
+
unless (matches = pattern.match(line))
|
40
50
|
msg = "Illformed requirement [#{obj.inspect}]"
|
41
51
|
raise BadRequirementError, msg
|
42
52
|
end
|
@@ -128,7 +138,8 @@ module Dependabot
|
|
128
138
|
upper_bound = parts.map.with_index do |part, i|
|
129
139
|
if i < first_non_zero_index then part
|
130
140
|
elsif i == first_non_zero_index then (part.to_i + 1).to_s
|
131
|
-
|
141
|
+
# .dev has lowest precedence: https://packaging.python.org/en/latest/specifications/version-specifiers/#summary-of-permitted-suffixes-and-relative-ordering
|
142
|
+
elsif i > first_non_zero_index && i == 2 then "0.dev"
|
132
143
|
else
|
133
144
|
0
|
134
145
|
end
|
@@ -151,7 +162,7 @@ module Dependabot
|
|
151
162
|
.first(req_string.split(".").index { |s| s.include?("*") } + 1)
|
152
163
|
.join(".")
|
153
164
|
.gsub(/\*(?!$)/, "0")
|
154
|
-
.gsub(/\*$/, "0.
|
165
|
+
.gsub(/\*$/, "0.dev")
|
155
166
|
.tap { |s| exact_op ? s.gsub!(/^(?<!!)=*/, "~>") : s }
|
156
167
|
end
|
157
168
|
end
|
@@ -4,71 +4,333 @@
|
|
4
4
|
require "dependabot/version"
|
5
5
|
require "dependabot/utils"
|
6
6
|
|
7
|
-
#
|
8
|
-
# parse. This class augments Gem::Version with local version identifier info.
|
9
|
-
# See https://www.python.org/dev/peps/pep-0440 for details.
|
7
|
+
# See https://packaging.python.org/en/latest/specifications/version-specifiers for spec details.
|
10
8
|
|
11
9
|
module Dependabot
|
12
10
|
module Python
|
13
11
|
class Version < Dependabot::Version
|
12
|
+
sig { returns(Integer) }
|
14
13
|
attr_reader :epoch
|
14
|
+
|
15
|
+
sig { returns(T::Array[Integer]) }
|
16
|
+
attr_reader :release_segment
|
17
|
+
|
18
|
+
sig { returns(T.nilable(T::Array[T.any(String, Integer)])) }
|
19
|
+
attr_reader :dev
|
20
|
+
|
21
|
+
sig { returns(T.nilable(T::Array[T.any(String, Integer)])) }
|
22
|
+
attr_reader :pre
|
23
|
+
|
24
|
+
sig { returns(T.nilable(T::Array[T.any(String, Integer)])) }
|
25
|
+
attr_reader :post
|
26
|
+
|
27
|
+
sig { returns(T.nilable(T::Array[T.any(String, Integer)])) }
|
28
|
+
attr_reader :local
|
29
|
+
|
15
30
|
attr_reader :local_version
|
16
31
|
attr_reader :post_release_version
|
17
32
|
|
33
|
+
INFINITY = 1000
|
34
|
+
NEGATIVE_INFINITY = -INFINITY
|
35
|
+
|
18
36
|
# See https://peps.python.org/pep-0440/#appendix-b-parsing-version-strings-with-regular-expressions
|
37
|
+
NEW_VERSION_PATTERN = /
|
38
|
+
v?
|
39
|
+
(?:
|
40
|
+
(?:(?<epoch>[0-9]+)!)? # epoch
|
41
|
+
(?<release>[0-9]+(?:\.[0-9]+)*) # release
|
42
|
+
(?<pre> # prerelease
|
43
|
+
[-_\.]?
|
44
|
+
(?<pre_l>(a|b|c|rc|alpha|beta|pre|preview))
|
45
|
+
[-_\.]?
|
46
|
+
(?<pre_n>[0-9]+)?
|
47
|
+
)?
|
48
|
+
(?<post> # post release
|
49
|
+
(?:-(?<post_n1>[0-9]+))
|
50
|
+
|
|
51
|
+
(?:
|
52
|
+
[-_\.]?
|
53
|
+
(?<post_l>post|rev|r)
|
54
|
+
[-_\.]?
|
55
|
+
(?<post_n2>[0-9]+)?
|
56
|
+
)
|
57
|
+
)?
|
58
|
+
(?<dev> # dev release
|
59
|
+
[-_\.]?
|
60
|
+
(?<dev_l>dev)
|
61
|
+
[-_\.]?
|
62
|
+
(?<dev_n>[0-9]+)?
|
63
|
+
)?
|
64
|
+
)
|
65
|
+
(?:\+(?<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
|
66
|
+
/ix
|
67
|
+
|
19
68
|
VERSION_PATTERN = 'v?([1-9][0-9]*!)?[0-9]+[0-9a-zA-Z]*(?>\.[0-9a-zA-Z]+)*' \
|
20
69
|
'(-[0-9A-Za-z]+(\.[0-9a-zA-Z]+)*)?' \
|
21
70
|
'(\+[0-9a-zA-Z]+(\.[0-9a-zA-Z]+)*)?'
|
22
|
-
ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/
|
23
71
|
|
72
|
+
ANCHORED_VERSION_PATTERN = /\A\s*#{VERSION_PATTERN}\s*\z/
|
73
|
+
|
74
|
+
sig { override.params(version: VersionParameter).returns(T::Boolean) }
|
24
75
|
def self.correct?(version)
|
25
76
|
return false if version.nil?
|
26
77
|
|
27
|
-
|
78
|
+
if Dependabot::Experiments.enabled?(:python_new_version)
|
79
|
+
version.to_s.match?(/\A\s*#{NEW_VERSION_PATTERN}\s*\z/o)
|
80
|
+
else
|
81
|
+
version.to_s.match?(ANCHORED_VERSION_PATTERN)
|
82
|
+
end
|
28
83
|
end
|
29
84
|
|
30
|
-
|
85
|
+
sig { override.params(version: VersionParameter).void }
|
86
|
+
def initialize(version) # rubocop:disable Metrics/AbcSize,Metrics/PerceivedComplexity
|
87
|
+
raise Dependabot::BadRequirementError, "Malformed version string - string is nil" if version.nil?
|
88
|
+
|
31
89
|
@version_string = version.to_s
|
32
|
-
|
33
|
-
version
|
34
|
-
|
35
|
-
|
36
|
-
|
90
|
+
|
91
|
+
raise Dependabot::BadRequirementError, "Malformed version string - string is empty" if @version_string.empty?
|
92
|
+
|
93
|
+
matches = anchored_version_pattern.match(@version_string.downcase)
|
94
|
+
|
95
|
+
unless matches
|
96
|
+
raise Dependabot::BadRequirementError,
|
97
|
+
"Malformed version string - #{@version_string} does not match regex"
|
98
|
+
end
|
99
|
+
|
100
|
+
if Dependabot::Experiments.enabled?(:python_new_version)
|
101
|
+
@epoch = matches["epoch"].to_i
|
102
|
+
@release_segment = matches["release"]&.split(".")&.map(&:to_i) || []
|
103
|
+
@pre = parse_letter_version(matches["pre_l"], matches["pre_n"])
|
104
|
+
@post = parse_letter_version(matches["post_l"], matches["post_n1"] || matches["post_n2"])
|
105
|
+
@dev = parse_letter_version(matches["dev_l"], matches["dev_n"])
|
106
|
+
@local = parse_local_version(matches["local"])
|
107
|
+
super(matches["release"] || "")
|
37
108
|
else
|
38
|
-
@
|
109
|
+
version, @local_version = @version_string.split("+")
|
110
|
+
version ||= ""
|
111
|
+
version = version.gsub(/^v/, "")
|
112
|
+
if version.include?("!")
|
113
|
+
epoch, version = version.split("!")
|
114
|
+
@epoch = epoch.to_i
|
115
|
+
else
|
116
|
+
@epoch = 0
|
117
|
+
end
|
118
|
+
version = normalise_prerelease(version)
|
119
|
+
version, @post_release_version = version.split(/\.r(?=\d)/)
|
120
|
+
version ||= ""
|
121
|
+
@local_version = normalise_prerelease(@local_version) if @local_version
|
122
|
+
super
|
39
123
|
end
|
40
|
-
version = normalise_prerelease(version)
|
41
|
-
version, @post_release_version = version.split(/\.r(?=\d)/)
|
42
|
-
version ||= ""
|
43
|
-
@local_version = normalise_prerelease(@local_version) if @local_version
|
44
|
-
super
|
45
124
|
end
|
46
125
|
|
126
|
+
sig { override.params(version: VersionParameter).returns(Dependabot::Python::Version) }
|
127
|
+
def self.new(version)
|
128
|
+
T.cast(super, Dependabot::Python::Version)
|
129
|
+
end
|
130
|
+
|
131
|
+
sig { returns(String) }
|
47
132
|
def to_s
|
48
133
|
@version_string
|
49
134
|
end
|
50
135
|
|
136
|
+
sig { returns(String) }
|
51
137
|
def inspect # :nodoc:
|
52
138
|
"#<#{self.class} #{@version_string}>"
|
53
139
|
end
|
54
140
|
|
55
|
-
|
56
|
-
|
141
|
+
sig { returns(T::Boolean) }
|
142
|
+
def prerelease?
|
143
|
+
return super unless Dependabot::Experiments.enabled?(:python_new_version)
|
57
144
|
|
58
|
-
|
59
|
-
|
145
|
+
!!(pre || dev)
|
146
|
+
end
|
147
|
+
|
148
|
+
sig { returns(T.any(Gem::Version, Dependabot::Python::Version)) }
|
149
|
+
def release
|
150
|
+
return super unless Dependabot::Experiments.enabled?(:python_new_version)
|
151
|
+
|
152
|
+
Dependabot::Python::Version.new(release_segment.join("."))
|
153
|
+
end
|
154
|
+
|
155
|
+
sig { params(other: VersionParameter).returns(Integer) }
|
156
|
+
def <=>(other) # rubocop:disable Metrics/AbcSize,Metrics/PerceivedComplexity
|
157
|
+
other = Dependabot::Python::Version.new(other.to_s) unless other.is_a?(Dependabot::Python::Version)
|
158
|
+
other = T.cast(other, Dependabot::Python::Version)
|
60
159
|
|
61
|
-
|
62
|
-
|
160
|
+
if Dependabot::Experiments.enabled?(:python_new_version)
|
161
|
+
epoch_comparison = epoch <=> other.epoch
|
162
|
+
return epoch_comparison unless epoch_comparison.zero?
|
63
163
|
|
64
|
-
|
65
|
-
|
164
|
+
release_comparison = release_version_comparison(other)
|
165
|
+
return release_comparison unless release_comparison.zero?
|
166
|
+
|
167
|
+
pre_comparison = compare_keys(pre_cmp_key, other.pre_cmp_key)
|
168
|
+
return pre_comparison unless pre_comparison.zero?
|
169
|
+
|
170
|
+
post_comparison = compare_keys(post_cmp_key, other.post_cmp_key)
|
171
|
+
return post_comparison unless post_comparison.zero?
|
172
|
+
|
173
|
+
dev_comparison = compare_keys(dev_cmp_key, other.dev_cmp_key)
|
174
|
+
return dev_comparison unless dev_comparison.zero?
|
175
|
+
|
176
|
+
compare_keys(local_cmp_key, other.local_cmp_key)
|
177
|
+
else
|
178
|
+
epoch_comparison = epoch_comparison(other)
|
179
|
+
return epoch_comparison unless epoch_comparison.zero?
|
66
180
|
|
67
|
-
|
181
|
+
version_comparison = super
|
182
|
+
return T.must(version_comparison) unless version_comparison&.zero?
|
183
|
+
|
184
|
+
post_version_comparison = post_version_comparison(other)
|
185
|
+
return post_version_comparison unless post_version_comparison.zero?
|
186
|
+
|
187
|
+
local_version_comparison(other)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
sig do
|
192
|
+
params(
|
193
|
+
key: T.any(Integer, T::Array[T.any(String, Integer)]),
|
194
|
+
other_key: T.any(Integer, T::Array[T.any(String, Integer)])
|
195
|
+
).returns(Integer)
|
196
|
+
end
|
197
|
+
def compare_keys(key, other_key)
|
198
|
+
if key.is_a?(Integer) && other_key.is_a?(Integer)
|
199
|
+
key <=> other_key
|
200
|
+
elsif key.is_a?(Array) && other_key.is_a?(Array)
|
201
|
+
key <=> other_key
|
202
|
+
elsif key.is_a?(Integer)
|
203
|
+
key == NEGATIVE_INFINITY ? -1 : 1
|
204
|
+
elsif other_key.is_a?(Integer)
|
205
|
+
other_key == NEGATIVE_INFINITY ? 1 : -1
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
sig { returns(T.any(Integer, T::Array[T.any(String, Integer)])) }
|
210
|
+
def pre_cmp_key
|
211
|
+
if pre.nil? && post.nil? && dev # sort 1.0.dev0 before 1.0a0
|
212
|
+
NEGATIVE_INFINITY
|
213
|
+
elsif pre.nil?
|
214
|
+
INFINITY # versions without a pre-release should sort after those with one.
|
215
|
+
else
|
216
|
+
T.must(pre)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
sig { returns(T.any(Integer, T::Array[T.any(String, Integer)])) }
|
221
|
+
def local_cmp_key
|
222
|
+
if local.nil?
|
223
|
+
# Versions without a local segment should sort before those with one.
|
224
|
+
NEGATIVE_INFINITY
|
225
|
+
else
|
226
|
+
# According to PEP440.
|
227
|
+
# - Alphanumeric segments sort before numeric segments
|
228
|
+
# - Alphanumeric segments sort lexicographically
|
229
|
+
# - Numeric segments sort numerically
|
230
|
+
# - Shorter versions sort before longer versions when the prefixes match exactly
|
231
|
+
local&.map do |token|
|
232
|
+
if token.is_a?(Integer)
|
233
|
+
[token, ""]
|
234
|
+
else
|
235
|
+
[NEGATIVE_INFINITY, token]
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
sig { returns(T.any(Integer, T::Array[T.any(String, Integer)])) }
|
242
|
+
def post_cmp_key
|
243
|
+
# Versions without a post segment should sort before those with one.
|
244
|
+
return NEGATIVE_INFINITY if post.nil?
|
245
|
+
|
246
|
+
T.must(post)
|
247
|
+
end
|
248
|
+
|
249
|
+
sig { returns(T.any(Integer, T::Array[T.any(String, Integer)])) }
|
250
|
+
def dev_cmp_key
|
251
|
+
# Versions without a dev segment should sort after those with one.
|
252
|
+
return INFINITY if dev.nil?
|
253
|
+
|
254
|
+
T.must(dev)
|
68
255
|
end
|
69
256
|
|
70
257
|
private
|
71
258
|
|
259
|
+
sig { params(other: Dependabot::Python::Version).returns(Integer) }
|
260
|
+
def release_version_comparison(other)
|
261
|
+
tokens, other_tokens = pad_for_comparison(release_segment, other.release_segment)
|
262
|
+
tokens <=> other_tokens
|
263
|
+
end
|
264
|
+
|
265
|
+
sig do
|
266
|
+
params(
|
267
|
+
tokens: T::Array[Integer],
|
268
|
+
other_tokens: T::Array[Integer]
|
269
|
+
).returns(T::Array[T::Array[Integer]])
|
270
|
+
end
|
271
|
+
def pad_for_comparison(tokens, other_tokens)
|
272
|
+
tokens = tokens.dup
|
273
|
+
other_tokens = other_tokens.dup
|
274
|
+
|
275
|
+
longer = [tokens, other_tokens].max_by(&:count)
|
276
|
+
shorter = [tokens, other_tokens].min_by(&:count)
|
277
|
+
|
278
|
+
difference = T.must(longer).length - T.must(shorter).length
|
279
|
+
|
280
|
+
difference.times { T.must(shorter) << 0 }
|
281
|
+
|
282
|
+
[tokens, other_tokens]
|
283
|
+
end
|
284
|
+
|
285
|
+
sig { params(local: T.nilable(String)).returns(T.nilable(T::Array[T.any(String, Integer)])) }
|
286
|
+
def parse_local_version(local)
|
287
|
+
return if local.nil?
|
288
|
+
|
289
|
+
# Takes a string like abc.1.twelve and turns it into ["abc", 1, "twelve"]
|
290
|
+
local.split(/[\._-]/).map { |s| /^\d+$/.match?(s) ? s.to_i : s }
|
291
|
+
end
|
292
|
+
|
293
|
+
sig do
|
294
|
+
params(
|
295
|
+
letter: T.nilable(String), number: T.nilable(String)
|
296
|
+
).returns(T.nilable(T::Array[T.any(String, Integer)]))
|
297
|
+
end
|
298
|
+
def parse_letter_version(letter = nil, number = nil)
|
299
|
+
return if letter.nil? && number.nil?
|
300
|
+
|
301
|
+
if letter
|
302
|
+
# Implicit 0 for cases where prerelease has no numeral
|
303
|
+
number ||= 0
|
304
|
+
|
305
|
+
# Normalize alternate spellings
|
306
|
+
if letter == "alpha"
|
307
|
+
letter = "a"
|
308
|
+
elsif letter == "beta"
|
309
|
+
letter = "b"
|
310
|
+
elsif %w(c pre preview).include? letter
|
311
|
+
letter = "rc"
|
312
|
+
elsif %w(rev r).include? letter
|
313
|
+
letter = "post"
|
314
|
+
end
|
315
|
+
|
316
|
+
return letter, number.to_i
|
317
|
+
end
|
318
|
+
|
319
|
+
# Number but no letter i.e. implicit post release syntax (e.g. 1.0-1)
|
320
|
+
letter = "post"
|
321
|
+
|
322
|
+
[letter, number.to_i]
|
323
|
+
end
|
324
|
+
|
325
|
+
sig { returns(Regexp) }
|
326
|
+
def anchored_version_pattern
|
327
|
+
if Dependabot::Experiments.enabled?(:python_new_version)
|
328
|
+
/\A\s*#{NEW_VERSION_PATTERN}\s*\z/o
|
329
|
+
else
|
330
|
+
ANCHORED_VERSION_PATTERN
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
72
334
|
def epoch_comparison(other)
|
73
335
|
epoch.to_i <=> other.epoch.to_i
|
74
336
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dependabot-python
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.281.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10-
|
11
|
+
date: 2024-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dependabot-common
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.281.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.281.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: debug
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -288,8 +288,8 @@ licenses:
|
|
288
288
|
- MIT
|
289
289
|
metadata:
|
290
290
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
291
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
292
|
-
post_install_message:
|
291
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.281.0
|
292
|
+
post_install_message:
|
293
293
|
rdoc_options: []
|
294
294
|
require_paths:
|
295
295
|
- lib
|
@@ -305,7 +305,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
305
305
|
version: 3.1.0
|
306
306
|
requirements: []
|
307
307
|
rubygems_version: 3.5.9
|
308
|
-
signing_key:
|
308
|
+
signing_key:
|
309
309
|
specification_version: 4
|
310
310
|
summary: Provides Dependabot support for Python
|
311
311
|
test_files: []
|