dependabot-python 0.333.0 → 0.335.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 (27) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/requirements.txt +1 -1
  3. data/lib/dependabot/python/file_fetcher.rb +48 -39
  4. data/lib/dependabot/python/file_parser/pipfile_files_parser.rb +26 -16
  5. data/lib/dependabot/python/file_parser/pyproject_files_parser.rb +21 -11
  6. data/lib/dependabot/python/file_parser/python_requirement_parser.rb +4 -2
  7. data/lib/dependabot/python/file_parser.rb +54 -24
  8. data/lib/dependabot/python/file_updater/pip_compile_file_updater.rb +14 -6
  9. data/lib/dependabot/python/file_updater/pipfile_file_updater.rb +5 -3
  10. data/lib/dependabot/python/file_updater/pipfile_manifest_updater.rb +1 -0
  11. data/lib/dependabot/python/file_updater/pipfile_preparer.rb +8 -4
  12. data/lib/dependabot/python/file_updater/poetry_file_updater.rb +11 -7
  13. data/lib/dependabot/python/file_updater/pyproject_preparer.rb +1 -0
  14. data/lib/dependabot/python/file_updater/requirement_replacer.rb +18 -6
  15. data/lib/dependabot/python/file_updater.rb +8 -6
  16. data/lib/dependabot/python/language.rb +6 -3
  17. data/lib/dependabot/python/metadata_finder.rb +6 -3
  18. data/lib/dependabot/python/name_normaliser.rb +1 -1
  19. data/lib/dependabot/python/package/package_details_fetcher.rb +5 -5
  20. data/lib/dependabot/python/pipenv_runner.rb +2 -0
  21. data/lib/dependabot/python/requirement.rb +7 -4
  22. data/lib/dependabot/python/update_checker/pip_compile_version_resolver.rb +4 -2
  23. data/lib/dependabot/python/update_checker/pip_version_resolver.rb +9 -2
  24. data/lib/dependabot/python/update_checker/poetry_version_resolver.rb +54 -35
  25. data/lib/dependabot/python/update_checker/requirements_updater.rb +18 -8
  26. data/lib/dependabot/python/version.rb +8 -4
  27. metadata +12 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb861b2b496cfd6879573eee03425670d74ec6fad92a93721b76f2d98392d8c9
4
- data.tar.gz: ba2b3dbcbedb42506cbb78884340ee0f7a38a39d67f9093f27c8b45d84ffae9b
3
+ metadata.gz: 535cedbc5cc0a4b3594a556be6563af3afa5b354b5d9a3e2d2af9af60c30c116
4
+ data.tar.gz: e2bd11041a92793ca4f0eb56b63377a6346ae105400b34658dd5b146701c41ff
5
5
  SHA512:
6
- metadata.gz: 9048dbfa79c5754a2ddb7fe88b72974d414155c7206fa25d1b4db274802ef10de60dd04bb9ad40fab7e5337c70becfffbff99d2487f2425524d3e26b0d4f4792
7
- data.tar.gz: b039ecae109ea713a2ef2669b3841ea8cb97a9e4854d1bf69ed93c993eb2240b89af5d9993d8dac92540da348dcb6e461d3e6f492df4e6fe081f3458f6fd8998
6
+ metadata.gz: 133569373fc3bddac801d7a8a8e5055f2897a69add2ab8fca7d6d1af104a669c637b3ccaba895ec5765f6369a51366e4461c6d24cdc41248449a3614bfe51512
7
+ data.tar.gz: 07c053fce5c40ae72981acd60c67add022bbe668bf3e2b0f2410aebac52b6a2115fbd31870fa1edcaf1303689808354c5551702053bd5cfbb166fe3f23bbe89f
@@ -4,7 +4,7 @@ flake8==7.3.0
4
4
  hashin==1.0.5
5
5
  pipenv==2024.4.1
6
6
  plette==2.1.0
7
- poetry==2.1.1
7
+ poetry==2.2.0
8
8
  # TODO: Replace 3p package `tomli` with 3.11's new stdlib `tomllib` once we drop support for Python 3.10.
9
9
  tomli==2.2.1
10
10
 
@@ -151,16 +151,19 @@ module Dependabot
151
151
 
152
152
  sig { returns(T.nilable(Dependabot::DependencyFile)) }
153
153
  def python_version_file
154
- @python_version_file ||= T.let(begin
155
- file = fetch_support_file(".python-version")
156
- return file if file
157
- return if [".", "/"].include?(directory)
158
-
159
- # Check the top-level for a .python-version file, too
160
- reverse_path = Pathname.new(directory[0]).relative_path_from(directory)
161
- fetch_support_file(File.join(reverse_path, ".python-version"))
162
- &.tap { |f| f.name = ".python-version" }
163
- end, T.nilable(Dependabot::DependencyFile))
154
+ @python_version_file ||= T.let(
155
+ begin
156
+ file = fetch_support_file(".python-version")
157
+ return file if file
158
+ return if [".", "/"].include?(directory)
159
+
160
+ # Check the top-level for a .python-version file, too
161
+ reverse_path = Pathname.new(directory[0]).relative_path_from(directory)
162
+ fetch_support_file(File.join(reverse_path, ".python-version"))
163
+ &.tap { |f| f.name = ".python-version" }
164
+ end,
165
+ T.nilable(Dependabot::DependencyFile)
166
+ )
164
167
  end
165
168
 
166
169
  sig { returns(T.nilable(Dependabot::DependencyFile)) }
@@ -240,23 +243,26 @@ module Dependabot
240
243
 
241
244
  sig { returns(T::Array[Dependabot::DependencyFile]) }
242
245
  def req_txt_and_in_files
243
- @req_txt_and_in_files ||= T.let(begin
244
- files = T.let([], T::Array[Dependabot::DependencyFile])
245
-
246
- repo_contents
247
- .select { |f| f.type == "file" }
248
- .select { |f| f.name.end_with?(".txt", ".in") }
249
- .reject { |f| f.size > 500_000 }
250
- .map { |f| fetch_file_from_host(f.name) }
251
- .select { |f| requirements_file?(f) }
252
- .each { |f| files << f }
253
-
254
- repo_contents
255
- .select { |f| f.type == "dir" }
256
- .each { |f| files.concat(req_files_for_dir(f)) }
257
-
258
- files
259
- end, T.nilable(T::Array[Dependabot::DependencyFile]))
246
+ @req_txt_and_in_files ||= T.let(
247
+ begin
248
+ files = T.let([], T::Array[Dependabot::DependencyFile])
249
+
250
+ repo_contents
251
+ .select { |f| f.type == "file" }
252
+ .select { |f| f.name.end_with?(".txt", ".in") }
253
+ .reject { |f| f.size > 500_000 }
254
+ .map { |f| fetch_file_from_host(f.name) }
255
+ .select { |f| requirements_file?(f) }
256
+ .each { |f| files << f }
257
+
258
+ repo_contents
259
+ .select { |f| f.type == "dir" }
260
+ .each { |f| files.concat(req_files_for_dir(f)) }
261
+
262
+ files
263
+ end,
264
+ T.nilable(T::Array[Dependabot::DependencyFile])
265
+ )
260
266
  end
261
267
 
262
268
  sig { params(requirements_dir: T.untyped).returns(T::Array[Dependabot::DependencyFile]) }
@@ -285,18 +291,21 @@ module Dependabot
285
291
 
286
292
  sig { returns(T::Array[Dependabot::DependencyFile]) }
287
293
  def child_requirement_files
288
- @child_requirement_files ||= T.let(begin
289
- fetched_files = req_txt_and_in_files.dup
290
- req_txt_and_in_files.flat_map do |requirement_file|
291
- child_files = fetch_child_requirement_files(
292
- file: requirement_file,
293
- previously_fetched_files: fetched_files
294
- )
295
-
296
- fetched_files += child_files
297
- child_files
298
- end
299
- end, T.nilable(T::Array[Dependabot::DependencyFile]))
294
+ @child_requirement_files ||= T.let(
295
+ begin
296
+ fetched_files = req_txt_and_in_files.dup
297
+ req_txt_and_in_files.flat_map do |requirement_file|
298
+ child_files = fetch_child_requirement_files(
299
+ file: requirement_file,
300
+ previously_fetched_files: fetched_files
301
+ )
302
+
303
+ fetched_files += child_files
304
+ child_files
305
+ end
306
+ end,
307
+ T.nilable(T::Array[Dependabot::DependencyFile])
308
+ )
300
309
  end
301
310
 
302
311
  sig do
@@ -15,16 +15,19 @@ module Dependabot
15
15
  class PipfileFilesParser
16
16
  extend T::Sig
17
17
 
18
- DEPENDENCY_GROUP_KEYS = T.let([
19
- {
20
- pipfile: "packages",
21
- lockfile: "default"
22
- },
23
- {
24
- pipfile: "dev-packages",
25
- lockfile: "develop"
26
- }
27
- ].freeze, T::Array[T::Hash[Symbol, String]])
18
+ DEPENDENCY_GROUP_KEYS = T.let(
19
+ [
20
+ {
21
+ pipfile: "packages",
22
+ lockfile: "default"
23
+ },
24
+ {
25
+ pipfile: "dev-packages",
26
+ lockfile: "develop"
27
+ }
28
+ ].freeze,
29
+ T::Array[T::Hash[Symbol, String]]
30
+ )
28
31
 
29
32
  sig { params(dependency_files: T::Array[Dependabot::DependencyFile]).void }
30
33
  def initialize(dependency_files:)
@@ -116,8 +119,11 @@ module Dependabot
116
119
  end
117
120
 
118
121
  sig do
119
- params(dep_name: String, requirement: T.any(String, T::Hash[String, T.untyped]),
120
- group: String).returns(T.nilable(String))
122
+ params(
123
+ dep_name: String,
124
+ requirement: T.any(String, T::Hash[String, T.untyped]),
125
+ group: String
126
+ ).returns(T.nilable(String))
121
127
  end
122
128
  def dependency_version(dep_name, requirement, group)
123
129
  req = version_from_hash_or_string(requirement)
@@ -171,8 +177,10 @@ module Dependabot
171
177
 
172
178
  sig { returns(T::Hash[String, T.untyped]) }
173
179
  def parsed_pipfile_lock
174
- @parsed_pipfile_lock ||= T.let(JSON.parse(T.must(T.must(pipfile_lock).content)),
175
- T.nilable(T::Hash[String, T.untyped]))
180
+ @parsed_pipfile_lock ||= T.let(
181
+ JSON.parse(T.must(T.must(pipfile_lock).content)),
182
+ T.nilable(T::Hash[String, T.untyped])
183
+ )
176
184
  rescue JSON::ParserError
177
185
  raise Dependabot::DependencyFileNotParseable, T.must(pipfile_lock).path
178
186
  end
@@ -184,8 +192,10 @@ module Dependabot
184
192
 
185
193
  sig { returns(T.nilable(Dependabot::DependencyFile)) }
186
194
  def pipfile_lock
187
- @pipfile_lock ||= T.let(dependency_files.find { |f| f.name == "Pipfile.lock" },
188
- T.nilable(Dependabot::DependencyFile))
195
+ @pipfile_lock ||= T.let(
196
+ dependency_files.find { |f| f.name == "Pipfile.lock" },
197
+ T.nilable(Dependabot::DependencyFile)
198
+ )
189
199
  end
190
200
  end
191
201
  end
@@ -107,9 +107,11 @@ module Dependabot
107
107
  end
108
108
 
109
109
  sig do
110
- params(type: String,
111
- deps_hash: T::Hash[String,
112
- T.untyped]).returns(Dependabot::FileParsers::Base::DependencySet)
110
+ params(
111
+ type: String,
112
+ deps_hash: T::Hash[String,
113
+ T.untyped]
114
+ ).returns(Dependabot::FileParsers::Base::DependencySet)
113
115
  end
114
116
  def parse_poetry_dependency_group(type, deps_hash)
115
117
  dependencies = Dependabot::FileParsers::Base::DependencySet.new
@@ -218,8 +220,10 @@ module Dependabot
218
220
 
219
221
  sig { returns(T::Array[T.nilable(String)]) }
220
222
  def production_dependency_names
221
- @production_dependency_names ||= T.let(parse_production_dependency_names,
222
- T.nilable(T::Array[T.nilable(String)]))
223
+ @production_dependency_names ||= T.let(
224
+ parse_production_dependency_names,
225
+ T.nilable(T::Array[T.nilable(String)])
226
+ )
223
227
  end
224
228
 
225
229
  sig { returns(T::Array[T.nilable(String)]) }
@@ -283,8 +287,10 @@ module Dependabot
283
287
 
284
288
  sig { returns(T.nilable(Dependabot::DependencyFile)) }
285
289
  def pyproject
286
- @pyproject ||= T.let(dependency_files.find { |f| f.name == "pyproject.toml" },
287
- T.nilable(Dependabot::DependencyFile))
290
+ @pyproject ||= T.let(
291
+ dependency_files.find { |f| f.name == "pyproject.toml" },
292
+ T.nilable(Dependabot::DependencyFile)
293
+ )
288
294
  end
289
295
 
290
296
  sig { returns(T.untyped) }
@@ -319,14 +325,18 @@ module Dependabot
319
325
 
320
326
  sig { returns(T.nilable(Dependabot::DependencyFile)) }
321
327
  def poetry_lock
322
- @poetry_lock ||= T.let(dependency_files.find { |f| f.name == "poetry.lock" },
323
- T.nilable(Dependabot::DependencyFile))
328
+ @poetry_lock ||= T.let(
329
+ dependency_files.find { |f| f.name == "poetry.lock" },
330
+ T.nilable(Dependabot::DependencyFile)
331
+ )
324
332
  end
325
333
 
326
334
  sig { returns(T.nilable(Dependabot::DependencyFile)) }
327
335
  def pdm_lock
328
- @pdm_lock ||= T.let(dependency_files.find { |f| f.name == "pdm.lock" },
329
- T.nilable(Dependabot::DependencyFile))
336
+ @pdm_lock ||= T.let(
337
+ dependency_files.find { |f| f.name == "pdm.lock" },
338
+ T.nilable(Dependabot::DependencyFile)
339
+ )
330
340
  end
331
341
  end
332
342
  end
@@ -153,8 +153,10 @@ module Dependabot
153
153
 
154
154
  sig { returns(T.nilable(PipCompileFileMatcher)) }
155
155
  def pip_compile_file_matcher
156
- @pip_compile_file_matcher = T.let(PipCompileFileMatcher.new(pip_compile_files),
157
- T.nilable(PipCompileFileMatcher))
156
+ @pip_compile_file_matcher = T.let(
157
+ PipCompileFileMatcher.new(pip_compile_files),
158
+ T.nilable(PipCompileFileMatcher)
159
+ )
158
160
  end
159
161
 
160
162
  sig { returns(T.class_of(Dependabot::Python::Requirement)) }
@@ -25,16 +25,19 @@ module Dependabot
25
25
  require_relative "file_parser/setup_file_parser"
26
26
  require_relative "file_parser/python_requirement_parser"
27
27
 
28
- DEPENDENCY_GROUP_KEYS = T.let([
29
- {
30
- pipfile: "packages",
31
- lockfile: "default"
32
- },
33
- {
34
- pipfile: "dev-packages",
35
- lockfile: "develop"
36
- }
37
- ].freeze, T::Array[T::Hash[Symbol, String]])
28
+ DEPENDENCY_GROUP_KEYS = T.let(
29
+ [
30
+ {
31
+ pipfile: "packages",
32
+ lockfile: "default"
33
+ },
34
+ {
35
+ pipfile: "dev-packages",
36
+ lockfile: "develop"
37
+ }
38
+ ].freeze,
39
+ T::Array[T::Hash[Symbol, String]]
40
+ )
38
41
  REQUIREMENT_FILE_EVALUATION_ERRORS = %w(
39
42
  InstallationError RequirementsFileParseError InvalidMarker
40
43
  InvalidRequirement ValueError RecursionError
@@ -76,14 +79,24 @@ module Dependabot
76
79
 
77
80
  sig { returns(Dependabot::Python::LanguageVersionManager) }
78
81
  def language_version_manager
79
- @language_version_manager ||= T.let(LanguageVersionManager.new(python_requirement_parser:
80
- python_requirement_parser), T.nilable(LanguageVersionManager))
82
+ @language_version_manager ||= T.let(
83
+ LanguageVersionManager.new(
84
+ python_requirement_parser:
85
+ python_requirement_parser
86
+ ),
87
+ T.nilable(LanguageVersionManager)
88
+ )
81
89
  end
82
90
 
83
91
  sig { returns(Dependabot::Python::FileParser::PythonRequirementParser) }
84
92
  def python_requirement_parser
85
- @python_requirement_parser ||= T.let(FileParser::PythonRequirementParser.new(dependency_files:
86
- dependency_files), T.nilable(FileParser::PythonRequirementParser))
93
+ @python_requirement_parser ||= T.let(
94
+ FileParser::PythonRequirementParser.new(
95
+ dependency_files:
96
+ dependency_files
97
+ ),
98
+ T.nilable(FileParser::PythonRequirementParser)
99
+ )
87
100
  end
88
101
 
89
102
  sig { returns(Ecosystem::VersionManager) }
@@ -240,14 +253,24 @@ module Dependabot
240
253
 
241
254
  sig { returns(DependencySet) }
242
255
  def pipenv_dependencies
243
- @pipenv_dependencies ||= T.let(PipfileFilesParser.new(dependency_files:
244
- dependency_files).dependency_set, T.nilable(DependencySet))
256
+ @pipenv_dependencies ||= T.let(
257
+ PipfileFilesParser.new(
258
+ dependency_files:
259
+ dependency_files
260
+ ).dependency_set,
261
+ T.nilable(DependencySet)
262
+ )
245
263
  end
246
264
 
247
265
  sig { returns(DependencySet) }
248
266
  def pyproject_file_dependencies
249
- @pyproject_file_dependencies ||= T.let(PyprojectFilesParser.new(dependency_files:
250
- dependency_files).dependency_set, T.nilable(DependencySet))
267
+ @pyproject_file_dependencies ||= T.let(
268
+ PyprojectFilesParser.new(
269
+ dependency_files:
270
+ dependency_files
271
+ ).dependency_set,
272
+ T.nilable(DependencySet)
273
+ )
251
274
  end
252
275
 
253
276
  sig { returns(DependencySet) }
@@ -347,8 +370,10 @@ module Dependabot
347
370
  end
348
371
 
349
372
  sig do
350
- params(condition: T.untyped,
351
- python_version: T.any(String, Integer, Gem::Version)).returns(T::Boolean)
373
+ params(
374
+ condition: T.untyped,
375
+ python_version: T.any(String, Integer, Gem::Version)
376
+ ).returns(T::Boolean)
352
377
  end
353
378
  def evaluate_condition(condition, python_version)
354
379
  operator, version = condition.match(/([<>=!]=?)\s*"?([\d.]+)"?/)&.captures
@@ -371,8 +396,11 @@ module Dependabot
371
396
 
372
397
  sig { returns(DependencySet) }
373
398
  def setup_file_dependencies
374
- @setup_file_dependencies ||= T.let(SetupFileParser.new(dependency_files: dependency_files)
375
- .dependency_set, T.nilable(DependencySet))
399
+ @setup_file_dependencies ||= T.let(
400
+ SetupFileParser.new(dependency_files: dependency_files)
401
+ .dependency_set,
402
+ T.nilable(DependencySet)
403
+ )
376
404
  end
377
405
 
378
406
  sig { returns(T.untyped) }
@@ -497,8 +525,10 @@ module Dependabot
497
525
 
498
526
  sig { returns(Dependabot::Python::PipCompileFileMatcher) }
499
527
  def pip_compile_file_matcher
500
- @pip_compile_file_matcher ||= T.let(PipCompileFileMatcher.new(pip_compile_files),
501
- T.nilable(Dependabot::Python::PipCompileFileMatcher))
528
+ @pip_compile_file_matcher ||= T.let(
529
+ PipCompileFileMatcher.new(pip_compile_files),
530
+ T.nilable(Dependabot::Python::PipCompileFileMatcher)
531
+ )
502
532
  end
503
533
  end
504
534
  end
@@ -25,8 +25,10 @@ module Dependabot
25
25
  require_relative "setup_file_sanitizer"
26
26
 
27
27
  UNSAFE_PACKAGES = T.let(%w(setuptools distribute pip).freeze, T::Array[String])
28
- INCOMPATIBLE_VERSIONS_REGEX = T.let(/not supported between instances of 'InstallationCandidate'.*\z/m,
29
- Regexp)
28
+ INCOMPATIBLE_VERSIONS_REGEX = T.let(
29
+ /not supported between instances of 'InstallationCandidate'.*\z/m,
30
+ Regexp
31
+ )
30
32
  WARNINGS = T.let(/\s*# WARNING:.*\Z/m, Regexp)
31
33
  UNSAFE_NOTE = T.let(/\s*# The following packages are considered to be unsafe.*\Z/m, Regexp)
32
34
  RESOLVER_REGEX = T.let(/(?<=--resolver=)(\w+)/, Regexp)
@@ -70,8 +72,10 @@ module Dependabot
70
72
 
71
73
  sig { returns(T.nilable(T::Array[Dependabot::DependencyFile])) }
72
74
  def updated_dependency_files
73
- @updated_dependency_files = T.let(fetch_updated_dependency_files,
74
- T.nilable(T::Array[Dependabot::DependencyFile]))
75
+ @updated_dependency_files = T.let(
76
+ fetch_updated_dependency_files,
77
+ T.nilable(T::Array[Dependabot::DependencyFile])
78
+ )
75
79
  end
76
80
 
77
81
  private
@@ -488,8 +492,12 @@ module Dependabot
488
492
  T.must(requirement_string.match(/#{hash_regex}((?<separator>\s*\\?\s*?)#{hash_regex})*/)).named_captures.fetch("separator")
489
493
 
490
494
  default_separator =
491
- T.must(T.must(requirement_string
492
- .match(RequirementParser::HASH)).pre_match.match(/(?<separator>\s*\\?\s*?)\z/)).named_captures.fetch("separator")
495
+ T.must(
496
+ T.must(
497
+ requirement_string
498
+ .match(RequirementParser::HASH)
499
+ ).pre_match.match(/(?<separator>\s*\\?\s*?)\z/)
500
+ ).named_captures.fetch("separator")
493
501
 
494
502
  # rubocop:enable Layout/LineLength
495
503
  current_separator || default_separator
@@ -334,9 +334,11 @@ module Dependabot
334
334
  pipfile_content: String
335
335
  ).returns(
336
336
  T.nilable(
337
- T.any(T::Hash[String, T.untyped],
338
- String,
339
- T::Array[T::Hash[String, T.untyped]])
337
+ T.any(
338
+ T::Hash[String, T.untyped],
339
+ String,
340
+ T::Array[T::Hash[String, T.untyped]]
341
+ )
340
342
  )
341
343
  )
342
344
  end
@@ -37,6 +37,7 @@ module Dependabot
37
37
 
38
38
  sig { returns(T::Array[Dependency]) }
39
39
  attr_reader :dependencies
40
+
40
41
  sig { returns(DependencyFile) }
41
42
  attr_reader :manifest
42
43
 
@@ -70,13 +70,17 @@ module Dependabot
70
70
 
71
71
  sig { returns(T::Array[T::Hash[String, String]]) }
72
72
  def pipfile_sources
73
- @pipfile_sources ||= T.let(TomlRB.parse(pipfile_content).fetch("source", []),
74
- T.nilable(T::Array[T::Hash[String, String]]))
73
+ @pipfile_sources ||= T.let(
74
+ TomlRB.parse(pipfile_content).fetch("source", []),
75
+ T.nilable(T::Array[T::Hash[String, String]])
76
+ )
75
77
  end
76
78
 
77
79
  sig do
78
- params(source: T::Hash[String, String],
79
- credentials: T::Array[Dependabot::Credential]).returns(T.nilable(T::Hash[String, String]))
80
+ params(
81
+ source: T::Hash[String, String],
82
+ credentials: T::Array[Dependabot::Credential]
83
+ ).returns(T.nilable(T::Hash[String, String]))
80
84
  end
81
85
  def sub_auth_url(source, credentials)
82
86
  if source["url"]&.include?("${")
@@ -126,8 +126,10 @@ module Dependabot
126
126
  content.sub(T.must(declaration), new_declaration)
127
127
  else
128
128
  content.gsub(table_declaration_regex(dep, new_r)) do |match|
129
- match.gsub(/(\s*version\s*=\s*["'])#{Regexp.escape(old_req)}/,
130
- '\1' + new_req)
129
+ match.gsub(
130
+ /(\s*version\s*=\s*["'])#{Regexp.escape(old_req)}/,
131
+ '\1' + new_req
132
+ )
131
133
  end
132
134
  end
133
135
  end
@@ -284,11 +286,13 @@ module Dependabot
284
286
  sig do
285
287
  params(
286
288
  pyproject_content: String
287
- ).returns(T.nilable(T.any(
288
- T::Hash[String, T.untyped],
289
- String,
290
- T::Array[T::Hash[String, T.untyped]]
291
- )))
289
+ ).returns(T.nilable(
290
+ T.any(
291
+ T::Hash[String, T.untyped],
292
+ String,
293
+ T::Array[T::Hash[String, T.untyped]]
294
+ )
295
+ ))
292
296
  end
293
297
  def pyproject_hash_for(pyproject_content)
294
298
  SharedHelpers.in_a_temporary_directory do |dir|
@@ -113,6 +113,7 @@ module Dependabot
113
113
 
114
114
  sig { returns(String) }
115
115
  attr_reader :pyproject_content
116
+
116
117
  sig { returns(T.nilable(Dependabot::DependencyFile)) }
117
118
  attr_reader :lockfile
118
119
 
@@ -29,8 +29,14 @@ module Dependabot
29
29
  index_urls: T.nilable(T::Array[T.nilable(String)])
30
30
  ).void
31
31
  end
32
- def initialize(content:, dependency_name:, old_requirement:,
33
- new_requirement:, new_hash_version: nil, index_urls: nil)
32
+ def initialize(
33
+ content:,
34
+ dependency_name:,
35
+ old_requirement:,
36
+ new_requirement:,
37
+ new_hash_version: nil,
38
+ index_urls: nil
39
+ )
34
40
  @content = T.let(content, String)
35
41
  @dependency_name = T.let(normalise(dependency_name), String)
36
42
  @old_requirement = T.let(old_requirement, T.nilable(String))
@@ -158,12 +164,18 @@ module Dependabot
158
164
  return "" unless requirement_includes_hashes?(requirement)
159
165
 
160
166
  hash_regex = RequirementParser::HASH
161
- matches = T.must(original_dependency_declaration_string(requirement)
162
- .match(/#{hash_regex}((?<separator>\s*\\?\s*?)#{hash_regex})*/))
167
+ matches = T.must(
168
+ original_dependency_declaration_string(requirement)
169
+ .match(/#{hash_regex}((?<separator>\s*\\?\s*?)#{hash_regex})*/)
170
+ )
163
171
  current_separator = matches.named_captures.fetch("separator")
164
172
 
165
- hash_matches = T.must(T.must(original_dependency_declaration_string(requirement)
166
- .match(RequirementParser::HASH)).pre_match.match(/(?<separator>\s*\\?\s*?)\z/))
173
+ hash_matches = T.must(
174
+ T.must(
175
+ original_dependency_declaration_string(requirement)
176
+ .match(RequirementParser::HASH)
177
+ ).pre_match.match(/(?<separator>\s*\\?\s*?)\z/)
178
+ )
167
179
  default_separator = hash_matches
168
180
  .named_captures.fetch("separator")
169
181
 
@@ -114,12 +114,14 @@ module Dependabot
114
114
 
115
115
  sig { returns(T::Array[DependencyFile]) }
116
116
  def updated_pip_compile_based_files
117
- T.must(PipCompileFileUpdater.new(
118
- dependencies: dependencies,
119
- dependency_files: dependency_files,
120
- credentials: credentials,
121
- index_urls: pip_compile_index_urls
122
- ).updated_dependency_files)
117
+ T.must(
118
+ PipCompileFileUpdater.new(
119
+ dependencies: dependencies,
120
+ dependency_files: dependency_files,
121
+ credentials: credentials,
122
+ index_urls: pip_compile_index_urls
123
+ ).updated_dependency_files
124
+ )
123
125
  end
124
126
 
125
127
  sig { returns(T::Array[DependencyFile]) }
@@ -23,9 +23,12 @@ module Dependabot
23
23
  3.9.23
24
24
  ).freeze
25
25
 
26
- PRE_INSTALLED_PYTHON_VERSIONS = T.let(PRE_INSTALLED_PYTHON_VERSIONS_RAW.map do |v|
27
- Version.new(v)
28
- end.sort, T::Array[Dependabot::Python::Version])
26
+ PRE_INSTALLED_PYTHON_VERSIONS = T.let(
27
+ PRE_INSTALLED_PYTHON_VERSIONS_RAW.map do |v|
28
+ Version.new(v)
29
+ end.sort,
30
+ T::Array[Dependabot::Python::Version]
31
+ )
29
32
 
30
33
  PRE_INSTALLED_VERSIONS_MAP = T.let(
31
34
  PRE_INSTALLED_PYTHON_VERSIONS.to_h do |v|
@@ -90,7 +90,8 @@ module Dependabot
90
90
  next unless response.status == 200
91
91
 
92
92
  response.body.include?(normalised_dependency_name)
93
- end, T.nilable(String)
93
+ end,
94
+ T.nilable(String)
94
95
  )
95
96
  end
96
97
  # rubocop:enable Metrics/PerceivedComplexity
@@ -122,7 +123,8 @@ module Dependabot
122
123
  next unless response.status == 200
123
124
 
124
125
  response.body.include?(normalised_dependency_name)
125
- end, T.nilable(String)
126
+ end,
127
+ T.nilable(String)
126
128
  )
127
129
  end
128
130
  # rubocop:enable Metrics/PerceivedComplexity
@@ -143,7 +145,8 @@ module Dependabot
143
145
  rescue Excon::Error::Timeout, Excon::Error::Socket,
144
146
  Excon::Error::TooManyRedirects, ArgumentError
145
147
  nil
146
- end, T.nilable(Excon::Response)
148
+ end,
149
+ T.nilable(Excon::Response)
147
150
  )
148
151
 
149
152
  return unless @homepage_response&.status == 200
@@ -1,4 +1,4 @@
1
- # typed: strict
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "sorbet-runtime"
@@ -69,12 +69,12 @@ module Dependabot
69
69
  .select { |index_url| validate_index(index_url) } # Ensure only valid URLs
70
70
  .flat_map do |index_url|
71
71
  fetch_from_registry(index_url) || [] # Ensure it always returns an array
72
- rescue Excon::Error::Timeout, Excon::Error::Socket
73
- raise if MAIN_PYPI_INDEXES.include?(index_url)
72
+ rescue Excon::Error::Timeout, Excon::Error::Socket
73
+ raise if MAIN_PYPI_INDEXES.include?(index_url)
74
74
 
75
- raise PrivateSourceTimedOut, sanitized_url(index_url)
76
- rescue URI::InvalidURIError
77
- raise DependencyFileNotResolvable, "Invalid URL: #{sanitized_url(index_url)}"
75
+ raise PrivateSourceTimedOut, sanitized_url(index_url)
76
+ rescue URI::InvalidURIError
77
+ raise DependencyFileNotResolvable, "Invalid URL: #{sanitized_url(index_url)}"
78
78
  end
79
79
 
80
80
  Dependabot::Package::PackageDetails.new(
@@ -57,8 +57,10 @@ module Dependabot
57
57
 
58
58
  sig { returns(Dependabot::Dependency) }
59
59
  attr_reader :dependency
60
+
60
61
  sig { returns(T.nilable(Dependabot::DependencyFile)) }
61
62
  attr_reader :lockfile
63
+
62
64
  sig { returns(LanguageVersionManager) }
63
65
  attr_reader :language_version_manager
64
66
 
@@ -15,10 +15,13 @@ module Dependabot
15
15
  OR_SEPARATOR = T.let(/(?<=[a-zA-Z0-9)*])\s*\|+/, Regexp)
16
16
 
17
17
  # Add equality and arbitrary-equality matchers
18
- OPS = T.let(OPS.merge(
19
- "==" => ->(v, r) { v == r },
20
- "===" => ->(v, r) { v.to_s == r.to_s }
21
- ), T::Hash[String, T.proc.params(arg0: T.untyped, arg1: T.untyped).returns(T.untyped)])
18
+ OPS = T.let(
19
+ OPS.merge(
20
+ "==" => ->(v, r) { v == r },
21
+ "===" => ->(v, r) { v.to_s == r.to_s }
22
+ ),
23
+ T::Hash[String, T.proc.params(arg0: T.untyped, arg1: T.untyped).returns(T.untyped)]
24
+ )
22
25
 
23
26
  quoted = OPS.keys.sort_by(&:length).reverse
24
27
  .map { |k| Regexp.quote(k) }.join("|")
@@ -532,7 +532,8 @@ module Dependabot
532
532
  @python_requirement_parser ||= T.let(
533
533
  FileParser::PythonRequirementParser.new(
534
534
  dependency_files: dependency_files
535
- ), T.nilable(FileParser::PythonRequirementParser)
535
+ ),
536
+ T.nilable(FileParser::PythonRequirementParser)
536
537
  )
537
538
  end
538
539
 
@@ -541,7 +542,8 @@ module Dependabot
541
542
  @language_version_manager ||= T.let(
542
543
  LanguageVersionManager.new(
543
544
  python_requirement_parser: python_requirement_parser
544
- ), T.nilable(LanguageVersionManager)
545
+ ),
546
+ T.nilable(LanguageVersionManager)
545
547
  )
546
548
  end
547
549
 
@@ -24,8 +24,15 @@ module Dependabot
24
24
  raise_on_ignored: T::Boolean
25
25
  ).void
26
26
  end
27
- def initialize(dependency:, dependency_files:, credentials:,
28
- ignored_versions:, security_advisories:, update_cooldown: nil, raise_on_ignored: false)
27
+ def initialize(
28
+ dependency:,
29
+ dependency_files:,
30
+ credentials:,
31
+ ignored_versions:,
32
+ security_advisories:,
33
+ update_cooldown: nil,
34
+ raise_on_ignored: false
35
+ )
29
36
  @dependency = T.let(dependency, Dependabot::Dependency)
30
37
  @dependency_files = T.let(dependency_files, T::Array[Dependabot::DependencyFile])
31
38
  @credentials = T.let(credentials, T::Array[Dependabot::Credential])
@@ -44,11 +44,14 @@ module Dependabot
44
44
 
45
45
  INCOMPATIBLE_CONSTRAINTS = /Incompatible constraints in requirements of (?<dep>.+?) ((?<ver>.+?)):/
46
46
 
47
- PACKAGE_RESOLVER_ERRORS = T.let({
48
- package_info_error: /Unable to determine package info/,
49
- self_dep_error: /Package '(?<path>.*)' is listed as a dependency of itself./,
50
- incompatible_constraints: /Incompatible constraints in requirements/
51
- }.freeze, T::Hash[T.nilable(String), Regexp])
47
+ PACKAGE_RESOLVER_ERRORS = T.let(
48
+ {
49
+ package_info_error: /Unable to determine package info/,
50
+ self_dep_error: /Package '(?<path>.*)' is listed as a dependency of itself./,
51
+ incompatible_constraints: /Incompatible constraints in requirements/
52
+ }.freeze,
53
+ T::Hash[T.nilable(String), Regexp]
54
+ )
52
55
 
53
56
  sig { returns(Dependabot::Dependency) }
54
57
  attr_reader :dependency
@@ -78,8 +81,10 @@ module Dependabot
78
81
  @dependency_files = T.let(dependency_files, T::Array[Dependabot::DependencyFile])
79
82
  @credentials = T.let(credentials, T::Array[Dependabot::Credential])
80
83
  @repo_contents_path = T.let(repo_contents_path, T.nilable(String))
81
- @error_handler = T.let(PoetryErrorHandler.new(dependencies: dependency, dependency_files: dependency_files),
82
- Dependabot::Python::PoetryErrorHandler)
84
+ @error_handler = T.let(
85
+ PoetryErrorHandler.new(dependencies: dependency, dependency_files: dependency_files),
86
+ Dependabot::Python::PoetryErrorHandler
87
+ )
83
88
  @resolvable = T.let({}, T::Hash[Gem::Version, T::Boolean])
84
89
  @latest_resolvable_version_string = T.let({}, T::Hash[T.nilable(String), T.nilable(String)])
85
90
  @original_reqs_resolvable = T.let(nil, T.nilable(T::Boolean))
@@ -233,8 +238,10 @@ module Dependabot
233
238
  update_pyproject: T::Boolean
234
239
  ).void
235
240
  end
236
- def write_temporary_dependency_files(updated_req: nil,
237
- update_pyproject: true)
241
+ def write_temporary_dependency_files(
242
+ updated_req: nil,
243
+ update_pyproject: true
244
+ )
238
245
  dependency_files.each do |file|
239
246
  path = file.name
240
247
  FileUtils.mkdir_p(Pathname.new(path).dirname)
@@ -409,21 +416,27 @@ module Dependabot
409
416
  PACKAGE_NOT_FOUND = /Package (?<pkg>.*) ((?<req_ver>.*)) not found./
410
417
 
411
418
  # client access error codes while accessing package index
412
- CLIENT_ERROR_CODES = T.let({
413
- error401: /401 Client Error/,
414
- error403: /403 Client Error/,
415
- error404: /404 Client Error/,
416
- http403: /HTTP error 403/,
417
- http404: /HTTP error 404/
418
- }.freeze, T::Hash[T.nilable(String), Regexp])
419
+ CLIENT_ERROR_CODES = T.let(
420
+ {
421
+ error401: /401 Client Error/,
422
+ error403: /403 Client Error/,
423
+ error404: /404 Client Error/,
424
+ http403: /HTTP error 403/,
425
+ http404: /HTTP error 404/
426
+ }.freeze,
427
+ T::Hash[T.nilable(String), Regexp]
428
+ )
419
429
 
420
430
  # server response error codes while accessing package index
421
- SERVER_ERROR_CODES = T.let({
422
- server500: /500 Server Error/,
423
- server502: /502 Server Error/,
424
- server503: /503 Server Error/,
425
- server504: /504 Server Error/
426
- }.freeze, T::Hash[T.nilable(String), Regexp])
431
+ SERVER_ERROR_CODES = T.let(
432
+ {
433
+ server500: /500 Server Error/,
434
+ server502: /502 Server Error/,
435
+ server503: /503 Server Error/,
436
+ server504: /504 Server Error/
437
+ }.freeze,
438
+ T::Hash[T.nilable(String), Regexp]
439
+ )
427
440
 
428
441
  # invalid configuration in pyproject.toml
429
442
  POETRY_VIRTUAL_ENV_CONFIG = %r{pypoetry/virtualenvs(.|\n)*list index out of range}
@@ -431,17 +444,23 @@ module Dependabot
431
444
  # error related to local project as dependency in pyproject.toml
432
445
  ERR_LOCAL_PROJECT_PATH = /Path (?<path>.*) for (?<dep>.*) does not exist/
433
446
 
434
- TIME_OUT_ERRORS = T.let({
435
- time_out_max_retries: /Max retries exceeded/,
436
- time_out_read_timed_out: /Read timed out/,
437
- time_out_inactivity: /Timed out due to inactivity/
438
- }.freeze, T::Hash[T.nilable(String), Regexp])
439
-
440
- PACKAGE_RESOLVER_ERRORS = T.let({
441
- package_info_error: /Unable to determine package info/,
442
- self_dep_error: /Package '(?<path>.*)' is listed as a dependency of itself./,
443
- incompatible_constraints: /Incompatible constraints in requirements/
444
- }.freeze, T::Hash[T.nilable(String), Regexp])
447
+ TIME_OUT_ERRORS = T.let(
448
+ {
449
+ time_out_max_retries: /Max retries exceeded/,
450
+ time_out_read_timed_out: /Read timed out/,
451
+ time_out_inactivity: /Timed out due to inactivity/
452
+ }.freeze,
453
+ T::Hash[T.nilable(String), Regexp]
454
+ )
455
+
456
+ PACKAGE_RESOLVER_ERRORS = T.let(
457
+ {
458
+ package_info_error: /Unable to determine package info/,
459
+ self_dep_error: /Package '(?<path>.*)' is listed as a dependency of itself./,
460
+ incompatible_constraints: /Incompatible constraints in requirements/
461
+ }.freeze,
462
+ T::Hash[T.nilable(String), Regexp]
463
+ )
445
464
 
446
465
  sig do
447
466
  params(
@@ -502,7 +521,7 @@ module Dependabot
502
521
  SERVER_ERROR_CODES.each do |(_error_codes, error_regex)|
503
522
  next unless error.message.match?(error_regex)
504
523
 
505
- index_url = URI.extract(error.message.to_s).last .then { sanitize_url(_1) }
524
+ index_url = URI.extract(error.message.to_s).last.then { sanitize_url(_1) }
506
525
  raise InconsistentRegistryResponse, index_url
507
526
  end
508
527
 
@@ -515,7 +534,7 @@ module Dependabot
515
534
  CLIENT_ERROR_CODES.each do |(_error_codes, error_regex)|
516
535
  next unless error.message.match?(error_regex)
517
536
 
518
- index_url = URI.extract(error.message.to_s).last .then { sanitize_url(_1) }
537
+ index_url = URI.extract(error.message.to_s).last.then { sanitize_url(_1) }
519
538
  raise PrivateSourceAuthenticationFailure, index_url
520
539
  end
521
540
 
@@ -39,8 +39,12 @@ module Dependabot
39
39
  latest_resolvable_version: T.nilable(String)
40
40
  ).void
41
41
  end
42
- def initialize(requirements:, update_strategy:, has_lockfile:,
43
- latest_resolvable_version:)
42
+ def initialize(
43
+ requirements:,
44
+ update_strategy:,
45
+ has_lockfile:,
46
+ latest_resolvable_version:
47
+ )
44
48
  @requirements = T.let(requirements, T::Array[T::Hash[Symbol, T.untyped]])
45
49
  @update_strategy = T.let(update_strategy, Dependabot::RequirementsUpdateStrategy)
46
50
  @has_lockfile = T.let(has_lockfile, T::Boolean)
@@ -172,9 +176,11 @@ module Dependabot
172
176
 
173
177
  sig { params(req_string: String).returns(String) }
174
178
  def add_new_requirement_option(req_string)
175
- option_to_copy = T.must(T.must(req_string.split(PYPROJECT_OR_SEPARATOR).last)
176
- .split(PYPROJECT_SEPARATOR).first).strip
177
- operator = option_to_copy.gsub(/\d.*/, "").strip
179
+ option_to_copy = T.must(
180
+ T.must(req_string.split(PYPROJECT_OR_SEPARATOR).last)
181
+ .split(PYPROJECT_SEPARATOR).first
182
+ ).strip
183
+ operator = option_to_copy.gsub(/\d.*/, "").strip
178
184
 
179
185
  new_option =
180
186
  case operator
@@ -335,9 +341,13 @@ module Dependabot
335
341
  # Updates the version in a constraint to be the given version
336
342
  sig { params(req_string: String, version_to_be_permitted: String).returns(String) }
337
343
  def bump_version(req_string, version_to_be_permitted)
338
- old_version = T.must(T.must(req_string
339
- .match(/(#{RequirementParser::VERSION})/o))
340
- .captures.first)
344
+ old_version = T.must(
345
+ T.must(
346
+ req_string
347
+ .match(/(#{RequirementParser::VERSION})/o)
348
+ )
349
+ .captures.first
350
+ )
341
351
 
342
352
  req_string.sub(
343
353
  old_version,
@@ -91,14 +91,18 @@ module Dependabot
91
91
 
92
92
  @epoch = T.let(matches["epoch"].to_i, Integer)
93
93
  @release_segment = T.let(matches["release"]&.split(".")&.map(&:to_i) || [], T::Array[Integer])
94
- @pre = T.let(parse_letter_version(matches["pre_l"], matches["pre_n"]),
95
- T.nilable(T::Array[T.any(String, Integer)]))
94
+ @pre = T.let(
95
+ parse_letter_version(matches["pre_l"], matches["pre_n"]),
96
+ T.nilable(T::Array[T.any(String, Integer)])
97
+ )
96
98
  @post = T.let(
97
99
  parse_letter_version(matches["post_l"], matches["post_n1"] || matches["post_n2"]),
98
100
  T.nilable(T::Array[T.any(String, Integer)])
99
101
  )
100
- @dev = T.let(parse_letter_version(matches["dev_l"], matches["dev_n"]),
101
- T.nilable(T::Array[T.any(String, Integer)]))
102
+ @dev = T.let(
103
+ parse_letter_version(matches["dev_l"], matches["dev_n"]),
104
+ T.nilable(T::Array[T.any(String, Integer)])
105
+ )
102
106
  @local = T.let(parse_local_version(matches["local"]), T.nilable(T::Array[T.any(String, Integer)]))
103
107
  super(matches["release"] || "")
104
108
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-python
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.333.0
4
+ version: 0.335.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.333.0
18
+ version: 0.335.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.333.0
25
+ version: 0.335.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -113,56 +113,56 @@ dependencies:
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: '1.67'
116
+ version: '1.80'
117
117
  type: :development
118
118
  prerelease: false
119
119
  version_requirements: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
- version: '1.67'
123
+ version: '1.80'
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: rubocop-performance
126
126
  requirement: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: '1.22'
130
+ version: '1.26'
131
131
  type: :development
132
132
  prerelease: false
133
133
  version_requirements: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '1.22'
137
+ version: '1.26'
138
138
  - !ruby/object:Gem::Dependency
139
139
  name: rubocop-rspec
140
140
  requirement: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '2.29'
144
+ version: '3.7'
145
145
  type: :development
146
146
  prerelease: false
147
147
  version_requirements: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - "~>"
150
150
  - !ruby/object:Gem::Version
151
- version: '2.29'
151
+ version: '3.7'
152
152
  - !ruby/object:Gem::Dependency
153
153
  name: rubocop-sorbet
154
154
  requirement: !ruby/object:Gem::Requirement
155
155
  requirements:
156
156
  - - "~>"
157
157
  - !ruby/object:Gem::Version
158
- version: '0.8'
158
+ version: '0.10'
159
159
  type: :development
160
160
  prerelease: false
161
161
  version_requirements: !ruby/object:Gem::Requirement
162
162
  requirements:
163
163
  - - "~>"
164
164
  - !ruby/object:Gem::Version
165
- version: '0.8'
165
+ version: '0.10'
166
166
  - !ruby/object:Gem::Dependency
167
167
  name: simplecov
168
168
  requirement: !ruby/object:Gem::Requirement
@@ -290,7 +290,7 @@ licenses:
290
290
  - MIT
291
291
  metadata:
292
292
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
293
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.333.0
293
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.335.0
294
294
  rdoc_options: []
295
295
  require_paths:
296
296
  - lib