dependabot-python 0.212.0 → 0.214.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.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/build +5 -6
  3. data/helpers/lib/parser.py +59 -0
  4. data/helpers/requirements.txt +3 -3
  5. data/helpers/run.py +2 -0
  6. data/lib/dependabot/python/file_fetcher.rb +21 -12
  7. data/lib/dependabot/python/file_parser/{poetry_files_parser.rb → pyproject_files_parser.rb} +84 -2
  8. data/lib/dependabot/python/file_parser/setup_file_parser.rb +4 -4
  9. data/lib/dependabot/python/file_parser.rb +5 -29
  10. data/lib/dependabot/python/file_updater/pip_compile_file_updater.rb +7 -22
  11. data/lib/dependabot/python/file_updater/pipfile_file_updater.rb +11 -8
  12. data/lib/dependabot/python/file_updater/pipfile_preparer.rb +6 -4
  13. data/lib/dependabot/python/file_updater/poetry_file_updater.rb +15 -7
  14. data/lib/dependabot/python/file_updater/pyproject_preparer.rb +16 -1
  15. data/lib/dependabot/python/file_updater.rb +14 -1
  16. data/lib/dependabot/python/helpers.rb +37 -0
  17. data/lib/dependabot/python/metadata_finder.rb +2 -0
  18. data/lib/dependabot/python/python_versions.rb +11 -7
  19. data/lib/dependabot/python/requirement.rb +7 -4
  20. data/lib/dependabot/python/requirement_parser.rb +20 -23
  21. data/lib/dependabot/python/update_checker/index_finder.rb +1 -1
  22. data/lib/dependabot/python/update_checker/latest_version_finder.rb +2 -2
  23. data/lib/dependabot/python/update_checker/pip_compile_version_resolver.rb +19 -21
  24. data/lib/dependabot/python/update_checker/pipenv_version_resolver.rb +16 -18
  25. data/lib/dependabot/python/update_checker/poetry_version_resolver.rb +14 -12
  26. data/lib/dependabot/python/update_checker/requirements_updater.rb +17 -4
  27. data/lib/dependabot/python/update_checker.rb +82 -25
  28. data/lib/dependabot/python/version.rb +2 -2
  29. metadata +15 -56
@@ -26,7 +26,7 @@ module Dependabot
26
26
  https://pypi.python.org/simple/
27
27
  https://pypi.org/simple/
28
28
  ).freeze
29
- VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/.freeze
29
+ VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/
30
30
 
31
31
  def latest_version
32
32
  @latest_version ||= fetch_latest_version
@@ -89,7 +89,7 @@ module Dependabot
89
89
 
90
90
  def updated_requirements
91
91
  RequirementsUpdater.new(
92
- requirements: dependency.requirements,
92
+ requirements: requirements,
93
93
  latest_resolvable_version: preferred_resolvable_version&.to_s,
94
94
  update_strategy: requirements_update_strategy,
95
95
  has_lockfile: !(pipfile_lock || poetry_lock || pyproject_lock).nil?
@@ -100,8 +100,8 @@ module Dependabot
100
100
  # If passed in as an option (in the base class) honour that option
101
101
  return @requirements_update_strategy.to_sym if @requirements_update_strategy
102
102
 
103
- # Otherwise, check if this is a poetry library or not
104
- poetry_library? ? :widen_ranges : :bump_versions
103
+ # Otherwise, check if this is a library or not
104
+ library? ? :widen_ranges : :bump_versions
105
105
  end
106
106
 
107
107
  private
@@ -115,6 +115,17 @@ module Dependabot
115
115
  raise NotImplementedError
116
116
  end
117
117
 
118
+ def preferred_version_resolvable_with_unlock?
119
+ # Our requirements file updater doesn't currently support widening
120
+ # ranges, so avoid updating this dependency if widening ranges has been
121
+ # required and the dependency is present on a requirements file.
122
+ # Otherwise, we will crash later on. TODO: Consider what the correct
123
+ # behavior is in these cases.
124
+ return false if requirements_update_strategy == :widen_ranges && updating_requirements_file?
125
+
126
+ super
127
+ end
128
+
118
129
  def fetch_lowest_resolvable_security_fix_version
119
130
  fix_version = lowest_security_fix_version
120
131
  return latest_resolvable_version if fix_version.nil?
@@ -133,8 +144,7 @@ module Dependabot
133
144
  end
134
145
 
135
146
  def resolver_type
136
- reqs = dependency.requirements
137
- req_files = reqs.map { |r| r.fetch(:file) }
147
+ reqs = requirements
138
148
 
139
149
  # If there are no requirements then this is a sub-dependency. It
140
150
  # must come from one of Pipenv, Poetry or pip-tools, and can't come
@@ -143,9 +153,9 @@ module Dependabot
143
153
 
144
154
  # Otherwise, this is a top-level dependency, and we can figure out
145
155
  # which resolver to use based on the filename of its requirements
146
- return :pipenv if req_files.any?("Pipfile")
147
- return :poetry if req_files.any?("pyproject.toml")
148
- return :pip_compile if req_files.any? { |f| f.end_with?(".in") }
156
+ return :pipenv if updating_pipfile?
157
+ return pyproject_resolver if updating_pyproject?
158
+ return :pip_compile if updating_in_file?
149
159
 
150
160
  if dependency.version && !exact_requirement?(reqs)
151
161
  subdependency_resolver
@@ -162,6 +172,12 @@ module Dependabot
162
172
  raise "Claimed to be a sub-dependency, but no lockfile exists!"
163
173
  end
164
174
 
175
+ def pyproject_resolver
176
+ return :poetry if poetry_based?
177
+
178
+ :requirements
179
+ end
180
+
165
181
  def exact_requirement?(reqs)
166
182
  reqs = reqs.map { |r| r.fetch(:requirement) }
167
183
  reqs = reqs.compact
@@ -202,16 +218,14 @@ module Dependabot
202
218
  end
203
219
 
204
220
  def current_requirement_string
205
- reqs = dependency.requirements
221
+ reqs = requirements
206
222
  return if reqs.none?
207
223
 
208
- requirement =
209
- case resolver_type
210
- when :pipenv then reqs.find { |r| r[:file] == "Pipfile" }
211
- when :poetry then reqs.find { |r| r[:file] == "pyproject.toml" }
212
- when :pip_compile then reqs.find { |r| r[:file].end_with?(".in") }
213
- when :requirements then reqs.find { |r| r[:file].end_with?(".txt") }
214
- end
224
+ requirement = reqs.find do |r|
225
+ file = r[:file]
226
+
227
+ file == "Pipfile" || file == "pyproject.toml" || file.end_with?(".in") || file.end_with?(".txt")
228
+ end
215
229
 
216
230
  requirement&.fetch(:requirement)
217
231
  end
@@ -236,7 +250,7 @@ module Dependabot
236
250
  return ">= #{dependency.version}" if dependency.version
237
251
 
238
252
  version_for_requirement =
239
- dependency.requirements.filter_map { |r| r[:requirement] }.
253
+ requirements.filter_map { |r| r[:requirement] }.
240
254
  reject { |req_string| req_string.start_with?("<") }.
241
255
  select { |req_string| req_string.match?(VERSION_REGEX) }.
242
256
  map { |req_string| req_string.match(VERSION_REGEX) }.
@@ -261,26 +275,53 @@ module Dependabot
261
275
  )
262
276
  end
263
277
 
264
- def poetry_library?
265
- return false unless pyproject
278
+ def poetry_based?
279
+ updating_pyproject? && !poetry_details.nil?
280
+ end
281
+
282
+ def library?
283
+ return unless updating_pyproject?
266
284
 
267
285
  # Hit PyPi and check whether there are details for a library with a
268
286
  # matching name and description
269
- details = TomlRB.parse(pyproject.content).dig("tool", "poetry")
270
- return false unless details
271
-
272
287
  index_response = Dependabot::RegistryClient.get(
273
- url: "https://pypi.org/pypi/#{normalised_name(details['name'])}/json/"
288
+ url: "https://pypi.org/pypi/#{normalised_name(library_details['name'])}/json/"
274
289
  )
275
290
 
276
291
  return false unless index_response.status == 200
277
292
 
278
293
  pypi_info = JSON.parse(index_response.body)["info"] || {}
279
- pypi_info["summary"] == details["description"]
294
+ pypi_info["summary"] == library_details["description"]
295
+ rescue Excon::Error::Timeout
296
+ false
280
297
  rescue URI::InvalidURIError
281
298
  false
282
299
  end
283
300
 
301
+ def updating_pipfile?
302
+ requirement_files.any?("Pipfile")
303
+ end
304
+
305
+ def updating_pyproject?
306
+ requirement_files.any?("pyproject.toml")
307
+ end
308
+
309
+ def updating_in_file?
310
+ requirement_files.any? { |f| f.end_with?(".in") }
311
+ end
312
+
313
+ def updating_requirements_file?
314
+ requirement_files.any? { |f| f =~ /\.txt$|\.in$/ }
315
+ end
316
+
317
+ def requirement_files
318
+ requirements.map { |r| r.fetch(:file) }
319
+ end
320
+
321
+ def requirements
322
+ dependency.requirements
323
+ end
324
+
284
325
  def normalised_name(name)
285
326
  NameNormaliser.normalise(name)
286
327
  end
@@ -305,6 +346,22 @@ module Dependabot
305
346
  dependency_files.find { |f| f.name == "poetry.lock" }
306
347
  end
307
348
 
349
+ def library_details
350
+ @library_details ||= poetry_details || standard_details
351
+ end
352
+
353
+ def poetry_details
354
+ @poetry_details ||= toml_content.dig("tool", "poetry")
355
+ end
356
+
357
+ def standard_details
358
+ @standard_details ||= toml_content["project"]
359
+ end
360
+
361
+ def toml_content
362
+ @toml_content ||= TomlRB.parse(pyproject.content)
363
+ end
364
+
308
365
  def pip_compile_files
309
366
  dependency_files.select { |f| f.name.end_with?(".in") }
310
367
  end
@@ -16,9 +16,9 @@ module Dependabot
16
16
 
17
17
  # See https://peps.python.org/pep-0440/#appendix-b-parsing-version-strings-with-regular-expressions
18
18
  VERSION_PATTERN = 'v?([1-9][0-9]*!)?[0-9]+[0-9a-zA-Z]*(?>\.[0-9a-zA-Z]+)*' \
19
- '(-[0-9A-Za-z-]+(\.[0-9a-zA-Z-]+)*)?' \
19
+ '(-[0-9A-Za-z]+(\.[0-9a-zA-Z]+)*)?' \
20
20
  '(\+[0-9a-zA-Z]+(\.[0-9a-zA-Z]+)*)?'
21
- ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/.freeze
21
+ ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/
22
22
 
23
23
  def self.correct?(version)
24
24
  return false if version.nil?
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.212.0
4
+ version: 0.214.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-06 00:00:00.000000000 Z
11
+ date: 2022-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,42 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.212.0
19
+ version: 0.214.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.212.0
27
- - !ruby/object:Gem::Dependency
28
- name: debase
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
32
- - !ruby/object:Gem::Version
33
- version: 0.2.3
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '='
39
- - !ruby/object:Gem::Version
40
- version: 0.2.3
41
- - !ruby/object:Gem::Dependency
42
- name: debase-ruby_core_source
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '='
46
- - !ruby/object:Gem::Version
47
- version: 0.10.16
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '='
53
- - !ruby/object:Gem::Version
54
- version: 0.10.16
26
+ version: 0.214.0
55
27
  - !ruby/object:Gem::Dependency
56
28
  name: debug
57
29
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +58,14 @@ dependencies:
86
58
  requirements:
87
59
  - - "~>"
88
60
  - !ruby/object:Gem::Version
89
- version: 3.12.0
61
+ version: 4.0.0
90
62
  type: :development
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
66
  - - "~>"
95
67
  - !ruby/object:Gem::Version
96
- version: 3.12.0
68
+ version: 4.0.0
97
69
  - !ruby/object:Gem::Dependency
98
70
  name: rake
99
71
  requirement: !ruby/object:Gem::Requirement
@@ -142,42 +114,28 @@ dependencies:
142
114
  requirements:
143
115
  - - "~>"
144
116
  - !ruby/object:Gem::Version
145
- version: 1.36.0
117
+ version: 1.39.0
146
118
  type: :development
147
119
  prerelease: false
148
120
  version_requirements: !ruby/object:Gem::Requirement
149
121
  requirements:
150
122
  - - "~>"
151
123
  - !ruby/object:Gem::Version
152
- version: 1.36.0
124
+ version: 1.39.0
153
125
  - !ruby/object:Gem::Dependency
154
126
  name: rubocop-performance
155
127
  requirement: !ruby/object:Gem::Requirement
156
128
  requirements:
157
129
  - - "~>"
158
130
  - !ruby/object:Gem::Version
159
- version: 1.14.2
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: 1.14.2
167
- - !ruby/object:Gem::Dependency
168
- name: ruby-debug-ide
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: 0.7.3
131
+ version: 1.15.0
174
132
  type: :development
175
133
  prerelease: false
176
134
  version_requirements: !ruby/object:Gem::Requirement
177
135
  requirements:
178
136
  - - "~>"
179
137
  - !ruby/object:Gem::Version
180
- version: 0.7.3
138
+ version: 1.15.0
181
139
  - !ruby/object:Gem::Dependency
182
140
  name: simplecov
183
141
  requirement: !ruby/object:Gem::Requirement
@@ -266,7 +224,7 @@ files:
266
224
  - lib/dependabot/python/file_fetcher.rb
267
225
  - lib/dependabot/python/file_parser.rb
268
226
  - lib/dependabot/python/file_parser/pipfile_files_parser.rb
269
- - lib/dependabot/python/file_parser/poetry_files_parser.rb
227
+ - lib/dependabot/python/file_parser/pyproject_files_parser.rb
270
228
  - lib/dependabot/python/file_parser/python_requirement_parser.rb
271
229
  - lib/dependabot/python/file_parser/setup_file_parser.rb
272
230
  - lib/dependabot/python/file_updater.rb
@@ -279,6 +237,7 @@ files:
279
237
  - lib/dependabot/python/file_updater/requirement_file_updater.rb
280
238
  - lib/dependabot/python/file_updater/requirement_replacer.rb
281
239
  - lib/dependabot/python/file_updater/setup_file_sanitizer.rb
240
+ - lib/dependabot/python/helpers.rb
282
241
  - lib/dependabot/python/metadata_finder.rb
283
242
  - lib/dependabot/python/name_normaliser.rb
284
243
  - lib/dependabot/python/native_helpers.rb
@@ -306,14 +265,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
306
265
  requirements:
307
266
  - - ">="
308
267
  - !ruby/object:Gem::Version
309
- version: 2.7.0
268
+ version: 3.1.0
310
269
  required_rubygems_version: !ruby/object:Gem::Requirement
311
270
  requirements:
312
271
  - - ">="
313
272
  - !ruby/object:Gem::Version
314
- version: 2.7.0
273
+ version: 3.1.0
315
274
  requirements: []
316
- rubygems_version: 3.1.6
275
+ rubygems_version: 3.3.7
317
276
  signing_key:
318
277
  specification_version: 4
319
278
  summary: Python support for dependabot