dependabot-python 0.393.0 → 0.395.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.
@@ -12,6 +12,7 @@ require "dependabot/python/name_normaliser"
12
12
  require "dependabot/package/package_release"
13
13
  require "dependabot/package/package_details"
14
14
  require "dependabot/python/package/package_registry_finder"
15
+ require "dependabot/python/package/simple_api_parser"
15
16
 
16
17
  # Stores metadata for a package, including all its available versions
17
18
  module Dependabot
@@ -21,6 +22,7 @@ module Dependabot
21
22
  CREDENTIALS_PASSWORD = "password"
22
23
 
23
24
  APPLICATION_JSON = "application/json"
25
+ APPLICATION_PYPI_SIMPLE_JSON = "application/vnd.pypi.simple.v1+json"
24
26
  APPLICATION_TEXT = "text/html"
25
27
  CPYTHON = "cpython"
26
28
  PYTHON = "python"
@@ -42,11 +44,7 @@ module Dependabot
42
44
  credentials: T::Array[Dependabot::Credential]
43
45
  ).void
44
46
  end
45
- def initialize(
46
- dependency:,
47
- dependency_files:,
48
- credentials:
49
- )
47
+ def initialize(dependency:, dependency_files:, credentials:)
50
48
  @dependency = dependency
51
49
  @dependency_files = dependency_files
52
50
  @credentials = credentials
@@ -70,7 +68,7 @@ module Dependabot
70
68
  .flat_map do |index_url|
71
69
  fetch_from_registry(index_url) || [] # Ensure it always returns an array
72
70
  rescue Excon::Error::Timeout, Excon::Error::Socket
73
- raise if MAIN_PYPI_INDEXES.include?(index_url)
71
+ raise if main_pypi_index?(index_url)
74
72
 
75
73
  raise PrivateSourceTimedOut, sanitized_url(index_url)
76
74
  rescue URI::InvalidURIError
@@ -90,15 +88,46 @@ module Dependabot
90
88
  .returns(T.nilable(T::Array[Dependabot::Package::PackageRelease]))
91
89
  end
92
90
  def fetch_from_registry(index_url)
93
- metadata = fetch_from_json_registry(index_url)
91
+ return fetch_from_simple_registry(index_url) unless main_pypi_index?(index_url)
94
92
 
95
- return metadata if metadata&.any?
93
+ begin
94
+ metadata = fetch_from_json_registry(index_url)
95
+
96
+ return metadata if metadata&.any?
96
97
 
97
- Dependabot.logger.warn("No valid versions found via JSON API. Falling back to HTML.")
98
- fetch_from_html_registry(index_url)
99
- rescue StandardError => e
100
- Dependabot.logger.warn("Unexpected error in JSON fetch: #{e.message}. Falling back to HTML.")
101
- fetch_from_html_registry(index_url)
98
+ Dependabot.logger.warn("No valid versions found via JSON API. Falling back to HTML.")
99
+ fetch_from_html_registry(index_url)
100
+ rescue Dependabot::DependencyFileNotResolvable
101
+ raise
102
+ rescue StandardError => e
103
+ Dependabot.logger.warn("Unexpected error in JSON fetch: #{e.message}. Falling back to HTML.")
104
+ fetch_from_html_registry(index_url)
105
+ end
106
+ end
107
+
108
+ sig { params(index_url: String).returns(T::Array[Dependabot::Package::PackageRelease]) }
109
+ def fetch_from_simple_registry(index_url)
110
+ Dependabot.logger.info(
111
+ "Fetching release information from simple registry at #{sanitized_url(index_url)} for #{dependency.name}"
112
+ )
113
+ response = registry_response_for_dependency(index_url, accept: simple_api_accept)
114
+ project_url = response.path ? Excon::Utils.request_uri(response.data) : index_url + normalised_name + "/"
115
+ check_authentication_response(response, index_url)
116
+
117
+ version_releases = if simple_json_response?(response)
118
+ SimpleApiParser.new(
119
+ dependency: dependency,
120
+ project_url: project_url
121
+ ).parse(response.body)
122
+ else
123
+ extract_release_details_json_from_html(response.body)
124
+ end
125
+
126
+ format_version_releases(version_releases, preserve_distributions: simple_json_response?(response))
127
+ .sort_by(&:version).reverse
128
+ rescue JSON::ParserError
129
+ Dependabot.logger.warn("JSON parsing error for #{sanitized_url(index_url)}.")
130
+ []
102
131
  end
103
132
 
104
133
  # Example JSON Response Format:
@@ -203,14 +232,8 @@ module Dependabot
203
232
  Dependabot.logger.info(
204
233
  "Fetching release information from html registry at #{sanitized_url(index_url)} for #{dependency.name}"
205
234
  )
206
- index_response = registry_response_for_dependency(index_url)
207
- if index_response.status == 401 || index_response.status == 403
208
- registry_index_response = registry_index_response(index_url)
209
-
210
- if registry_index_response.status == 401 || registry_index_response.status == 403
211
- raise PrivateSourceAuthenticationFailure, sanitized_url(index_url)
212
- end
213
- end
235
+ index_response = registry_response_for_dependency(index_url, accept: APPLICATION_TEXT)
236
+ check_authentication_response(index_response, index_url)
214
237
 
215
238
  version_releases = extract_release_details_json_from_html(index_response.body)
216
239
  releases = format_version_releases(version_releases)
@@ -218,6 +241,27 @@ module Dependabot
218
241
  releases.sort_by(&:version).reverse
219
242
  end
220
243
 
244
+ sig { params(response: Excon::Response).returns(T::Boolean) }
245
+ def simple_json_response?(response)
246
+ response.headers["Content-Type"].to_s.split(";", 2).first.to_s.strip.downcase == APPLICATION_PYPI_SIMPLE_JSON
247
+ end
248
+
249
+ sig { returns(String) }
250
+ def simple_api_accept
251
+ "application/vnd.pypi.simple.v1+json, " \
252
+ "application/vnd.pypi.simple.v1+html;q=0.2, text/html;q=0.01"
253
+ end
254
+
255
+ sig { params(response: Excon::Response, index_url: String).void }
256
+ def check_authentication_response(response, index_url)
257
+ return unless [401, 403].include?(response.status)
258
+
259
+ index_response = registry_index_response(index_url)
260
+ return unless [401, 403].include?(index_response.status)
261
+
262
+ raise PrivateSourceAuthenticationFailure, sanitized_url(index_url)
263
+ end
264
+
221
265
  sig do
222
266
  params(html_body: String)
223
267
  .returns(T::Hash[String, T::Array[T::Hash[String, T.untyped]]]) # Returns JSON-like format
@@ -266,23 +310,17 @@ module Dependabot
266
310
 
267
311
  sig do
268
312
  params(
269
- releases_json: T.nilable(T::Hash[String, T::Array[T::Hash[String, T.untyped]]])
313
+ releases_json: T.nilable(T::Hash[String, T::Array[T::Hash[String, T.untyped]]]),
314
+ preserve_distributions: T::Boolean
270
315
  )
271
316
  .returns(T::Array[Dependabot::Package::PackageRelease])
272
317
  end
273
- def format_version_releases(releases_json)
318
+ def format_version_releases(releases_json, preserve_distributions: false)
274
319
  return [] unless releases_json
275
320
 
276
321
  releases_json.each_with_object([]) do |(version, release_data_array), versions|
277
- release_data = release_data_array.last
278
-
279
- next unless release_data
280
-
281
- release = format_version_release(version, release_data)
282
-
283
- next unless release
284
-
285
- versions << release
322
+ release_data_array = [release_data_array.last].compact unless preserve_distributions
323
+ versions.concat(release_data_array.filter_map { |data| format_version_release(version, data) })
286
324
  end
287
325
  end
288
326
 
@@ -397,11 +435,11 @@ module Dependabot
397
435
  )
398
436
  end
399
437
 
400
- sig { params(index_url: String).returns(Excon::Response) }
401
- def registry_response_for_dependency(index_url)
438
+ sig { params(index_url: String, accept: String).returns(Excon::Response) }
439
+ def registry_response_for_dependency(index_url, accept:)
402
440
  Dependabot::RegistryClient.get(
403
441
  url: index_url + normalised_name + "/",
404
- headers: { "Accept" => APPLICATION_TEXT }
442
+ headers: { "Accept" => accept }
405
443
  )
406
444
  end
407
445
 
@@ -487,6 +525,14 @@ module Dependabot
487
525
  index_url.sub(%r{//([^/@]+)@}, "//redacted@")
488
526
  end
489
527
 
528
+ sig { params(index_url: String).returns(T::Boolean) }
529
+ def main_pypi_index?(index_url)
530
+ uri = URI.parse(index_url)
531
+ T.must(uri.scheme.to_s.casecmp("https")).zero? && uri.port == 443 &&
532
+ uri.path.to_s.split("/").reject(&:empty?) == ["simple"] &&
533
+ %w(pypi.org pypi.python.org).include?(uri.host.to_s.downcase)
534
+ end
535
+
490
536
  sig { params(dep_name: String).returns(String) }
491
537
  def remove_optional(dep_name)
492
538
  # Remove any optional dependencies postfix, e.g., "pyvista[io] "
@@ -193,7 +193,7 @@ module Dependabot
193
193
 
194
194
  sig { params(url: String).returns(String) }
195
195
  def clean_check_and_remove_environment_variables(url)
196
- url = url.strip.sub(%r{/+$}, "") + "/"
196
+ url = with_single_trailing_slash(url.strip)
197
197
 
198
198
  return authed_base_url(url) unless url.match?(ENVIRONMENT_VARIABLE_REGEX)
199
199
 
@@ -203,7 +203,7 @@ module Dependabot
203
203
  *config_variable_index_urls[:extra]
204
204
  ]
205
205
  .compact
206
- .map { |u| u.strip.gsub(%r{/*$}, "") + "/" }
206
+ .map { |u| with_single_trailing_slash(u.strip) }
207
207
 
208
208
  regexp = url
209
209
  .sub(%r{(?<=://).+@}, "")
@@ -226,7 +226,7 @@ module Dependabot
226
226
  cred = credential_for(base_url)
227
227
  return base_url unless cred
228
228
 
229
- AuthedUrlBuilder.authed_url(credential: cred).gsub(%r{/*$}, "") + "/"
229
+ with_single_trailing_slash(AuthedUrlBuilder.authed_url(credential: cred))
230
230
  end
231
231
 
232
232
  sig { params(url: String).returns(T.nilable(Dependabot::Credential)) }
@@ -234,11 +234,18 @@ module Dependabot
234
234
  credentials
235
235
  .select { |c| c["type"] == "python_index" }
236
236
  .find do |c|
237
- cred_url = c.fetch("index-url").gsub(%r{/*$}, "") + "/"
237
+ cred_url = with_single_trailing_slash(c.fetch("index-url"))
238
238
  cred_url.include?(url)
239
239
  end
240
240
  end
241
241
 
242
+ sig { params(url: String).returns(String) }
243
+ def with_single_trailing_slash(url)
244
+ normalized_url = url.dup
245
+ normalized_url.chop! while normalized_url.end_with?("/")
246
+ normalized_url + "/"
247
+ end
248
+
242
249
  sig { returns(T.nilable(Dependabot::DependencyFile)) }
243
250
  def pip_conf
244
251
  dependency_files.find { |f| f.name == "pip.conf" }
@@ -0,0 +1,91 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "json"
5
+ require "uri"
6
+ require "sorbet-runtime"
7
+ require "dependabot/errors"
8
+ require "dependabot/python/name_normaliser"
9
+
10
+ module Dependabot
11
+ module Python
12
+ module Package
13
+ class SimpleApiParser
14
+ extend T::Sig
15
+
16
+ ReleaseDetail = T.type_alias { T::Hash[String, T.nilable(T.any(String, T::Boolean))] }
17
+
18
+ sig { params(dependency: Dependabot::Dependency, project_url: String).void }
19
+ def initialize(dependency:, project_url:)
20
+ @dependency = dependency
21
+ @project_url = project_url
22
+ end
23
+
24
+ sig do
25
+ params(json_body: String)
26
+ .returns(T::Hash[String, T::Array[ReleaseDetail]])
27
+ end
28
+ def parse(json_body)
29
+ data = JSON.parse(json_body)
30
+ validate_api_version!(data.dig("meta", "api-version").to_s)
31
+
32
+ data.fetch("files", []).each_with_object({}) do |file, releases|
33
+ filename = file["filename"]
34
+ next unless filename&.match?(name_regex)
35
+
36
+ version = version_from_filename(filename)
37
+ next unless dependency.version_class.correct?(version)
38
+
39
+ yanked = file["yanked"] || false
40
+ details = {
41
+ "version" => version,
42
+ "requires_python" => file["requires-python"],
43
+ "yanked" => yanked != false,
44
+ "yanked_reason" => yanked.is_a?(String) ? yanked : nil,
45
+ "upload_time" => file["upload-time"],
46
+ "url" => resolve_url(file["url"])
47
+ }
48
+ releases[version] ||= []
49
+ releases[version] << details
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ sig { returns(Dependabot::Dependency) }
56
+ attr_reader :dependency
57
+
58
+ sig { returns(String) }
59
+ attr_reader :project_url
60
+
61
+ sig { params(url: T.nilable(String)).returns(T.nilable(String)) }
62
+ def resolve_url(url)
63
+ return unless url
64
+
65
+ resolved_url = URI.join(project_url, url)
66
+ resolved_url.user = nil
67
+ resolved_url.password = nil
68
+ resolved_url.to_s
69
+ end
70
+
71
+ sig { params(api_version: String).void }
72
+ def validate_api_version!(api_version)
73
+ return unless api_version.split(".").first.to_i > 1
74
+
75
+ raise Dependabot::DependencyFileNotResolvable, "Unsupported PEP 691 API version: #{api_version}"
76
+ end
77
+
78
+ sig { returns(Regexp) }
79
+ def name_regex
80
+ parts = NameNormaliser.normalise(dependency.name).split(/[\s_.-]/).map { |name| Regexp.quote(name) }
81
+ /#{parts.join("[\s_.-]")}/i
82
+ end
83
+
84
+ sig { params(filename: String).returns(T.nilable(String)) }
85
+ def version_from_filename(filename)
86
+ filename.strip.gsub(/#{name_regex}-/i, "").split(/-|\.tar\.|\.zip|\.whl/).first
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -249,8 +249,7 @@ module Dependabot
249
249
  next if previously_fetched_files.map(&:name).include?(path)
250
250
  next if file.name == path
251
251
 
252
- if Dependabot::Experiments.enabled?(:enable_exclude_paths_subdirectory_manifest_files) &&
253
- !@exclude_paths.empty? && Dependabot::FileFiltering.exclude_path?(path, @exclude_paths)
252
+ if !@exclude_paths.empty? && Dependabot::FileFiltering.exclude_path?(path, @exclude_paths)
254
253
  raise Dependabot::DependencyFileNotEvaluatable,
255
254
  "Cannot process requirements: '#{file.name}' references excluded file '#{path}'. " \
256
255
  "Please either remove the reference from '#{file.name}' " \
@@ -42,6 +42,22 @@ module Dependabot
42
42
  cooldown.semver_minor_days.to_i.positive? ||
43
43
  cooldown.semver_patch_days.to_i.positive?
44
44
  end
45
+
46
+ sig do
47
+ params(language_version: T.nilable(T.any(String, Dependabot::Version)))
48
+ .returns(T.nilable(T::Array[Dependabot::Package::PackageRelease]))
49
+ end
50
+ def eligible_releases(language_version: nil)
51
+ releases = available_versions
52
+ return unless releases
53
+
54
+ releases = filter_yanked_versions(releases)
55
+ releases = filter_by_cooldown(releases)
56
+ releases = filter_unsupported_versions(releases, language_version)
57
+ releases = filter_prerelease_versions(releases)
58
+ releases = filter_ignored_versions(releases)
59
+ apply_post_fetch_latest_versions_filter(releases)
60
+ end
45
61
  end
46
62
  end
47
63
  end
@@ -19,7 +19,7 @@ module Dependabot
19
19
  class UpdateChecker
20
20
  # This resolver intentionally co-locates resolution, marker handling, and
21
21
  # constraints matching to keep compatibility decisions in one place.
22
- # rubocop:disable Metrics/ClassLength
22
+ # rubocop:disable-next Metrics/ClassLength
23
23
  class PipVersionResolver
24
24
  extend T::Sig
25
25
 
@@ -575,7 +575,6 @@ module Dependabot
575
575
  T.must(@pyproject_content_cache[pyproject.name])
576
576
  end
577
577
  end
578
- # rubocop:enable Metrics/ClassLength
579
578
  end
580
579
  end
581
580
  end
@@ -12,7 +12,7 @@ require "dependabot/requirements_update_strategy"
12
12
  module Dependabot
13
13
  module Python
14
14
  class UpdateChecker
15
- # rubocop:disable Metrics/ClassLength
15
+ # rubocop:disable-next Metrics/ClassLength
16
16
  class RequirementsUpdater
17
17
  extend T::Sig
18
18
 
@@ -358,7 +358,7 @@ module Dependabot
358
358
  new_segments
359
359
  .first(count)
360
360
  .map.with_index { |s, i| i < precision ? s : "*" }
361
- .join(".")
361
+ .join(".")
362
362
  end
363
363
 
364
364
  sig { params(requirement_strings: T::Array[String]).returns(String) }
@@ -542,7 +542,6 @@ module Dependabot
542
542
  Python::Requirement
543
543
  end
544
544
  end
545
- # rubocop:enable Metrics/ClassLength
546
545
  end
547
546
  end
548
547
  end
@@ -2,12 +2,13 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "excon"
5
- require "toml-rb"
5
+ require "json"
6
6
  require "sorbet-runtime"
7
7
 
8
8
  require "dependabot/dependency"
9
9
  require "dependabot/dependency_requirement"
10
10
  require "dependabot/errors"
11
+ require "dependabot/python/file_parser"
11
12
  require "dependabot/python/name_normaliser"
12
13
  require "dependabot/python/requirement_parser"
13
14
  require "dependabot/python/requirement"
@@ -18,7 +19,7 @@ require "dependabot/update_checkers/base"
18
19
 
19
20
  module Dependabot
20
21
  module Python
21
- # rubocop:disable Metrics/ClassLength
22
+ # rubocop:disable-next Metrics/ClassLength
22
23
  class UpdateChecker < Dependabot::UpdateCheckers::Base
23
24
  extend T::Sig
24
25
 
@@ -29,6 +30,8 @@ module Dependabot
29
30
  require_relative "update_checker/requirements_updater"
30
31
  require_relative "update_checker/latest_version_finder"
31
32
 
33
+ PyprojectDocument = FileParser::PyprojectDocument
34
+
32
35
  MAIN_PYPI_INDEXES = %w(
33
36
  https://pypi.python.org/simple/
34
37
  https://pypi.org/simple/
@@ -248,7 +251,7 @@ module Dependabot
248
251
  # For hybrid projects with both [tool.poetry] and [project] sections but no lockfile,
249
252
  # use the requirements resolver to handle PEP 621 dependencies
250
253
  # For pure Poetry projects, use Poetry resolver even without lockfile
251
- return :poetry if poetry_based? && (poetry_lock || !standard_details)
254
+ return :poetry if poetry_based? && (poetry_lock || !pyproject_document.project?)
252
255
 
253
256
  :requirements
254
257
  end
@@ -395,7 +398,7 @@ module Dependabot
395
398
 
396
399
  sig { returns(T::Boolean) }
397
400
  def poetry_based?
398
- updating_pyproject? && !poetry_details.nil?
401
+ updating_pyproject? && pyproject_document.poetry?
399
402
  end
400
403
 
401
404
  sig { returns(T::Boolean) }
@@ -410,22 +413,41 @@ module Dependabot
410
413
  def check_pypi_for_library_match
411
414
  return false unless updating_pyproject?
412
415
 
413
- library_details_temp = library_details
414
- return false unless library_details_temp && !library_details_temp["name"].nil?
416
+ metadata = library_details
417
+ name = metadata&.name
418
+ return false unless name
415
419
 
416
- has_library_metadata = !library_details_temp["description"].nil?
420
+ local_description = metadata.description
421
+ has_library_metadata = !local_description.nil?
417
422
 
418
- response = Dependabot::RegistryClient.get(
419
- url: "https://pypi.org/pypi/#{normalised_name(library_details_temp['name'])}/json/"
420
- )
421
- return has_library_metadata unless response.status == 200
423
+ begin
424
+ response = Dependabot::RegistryClient.get(
425
+ url: "https://pypi.org/pypi/#{normalised_name(name)}/json/"
426
+ )
427
+ return has_library_metadata unless response.status == 200
422
428
 
423
- local_description = library_details_temp["description"]
424
- return true if local_description.nil?
429
+ return true if local_description.nil?
425
430
 
426
- (JSON.parse(response.body)["info"] || {})["summary"] == local_description
427
- rescue Excon::Error::Timeout, Excon::Error::Socket, URI::InvalidURIError
428
- has_library_metadata
431
+ pypi_summary(response.body) == local_description
432
+ rescue Excon::Error::Timeout, Excon::Error::Socket, URI::InvalidURIError
433
+ has_library_metadata
434
+ end
435
+ end
436
+
437
+ sig { params(body: String).returns(T.nilable(String)) }
438
+ def pypi_summary(body)
439
+ metadata = T.cast(JSON.parse(body), Object)
440
+ raise TypeError, "PyPI metadata must be an object" unless metadata.is_a?(Hash)
441
+
442
+ info = T.cast(metadata["info"], Object)
443
+ return if info.nil?
444
+ raise TypeError, "PyPI info must be an object" unless info.is_a?(Hash)
445
+
446
+ summary = T.cast(info["summary"], Object)
447
+ return if summary.nil?
448
+ return summary if summary.is_a?(String)
449
+
450
+ raise TypeError, "PyPI info.summary must be a string"
429
451
  end
430
452
 
431
453
  sig { returns(T::Boolean) }
@@ -483,43 +505,21 @@ module Dependabot
483
505
  dependency_files.find { |f| f.name == "poetry.lock" }
484
506
  end
485
507
 
486
- sig { returns(T.nilable(T::Hash[String, T.untyped])) }
508
+ sig { returns(T.nilable(PyprojectDocument::ProjectMetadata)) }
487
509
  def library_details
488
510
  @library_details ||= T.let(
489
- poetry_details || standard_details || build_system_details,
490
- T.nilable(T::Hash[String, T.untyped])
491
- )
492
- end
493
-
494
- sig { returns(T.nilable(T::Hash[String, T.untyped])) }
495
- def poetry_details
496
- @poetry_details ||= T.let(
497
- toml_content.dig("tool", "poetry"),
498
- T.nilable(T::Hash[String, T.untyped])
499
- )
500
- end
501
-
502
- sig { returns(T.nilable(T::Hash[String, T.untyped])) }
503
- def standard_details
504
- @standard_details ||= T.let(
505
- toml_content["project"],
506
- T.nilable(T::Hash[String, T.untyped])
507
- )
508
- end
509
-
510
- sig { returns(T.nilable(T::Hash[String, T.untyped])) }
511
- def build_system_details
512
- @build_system_details ||= T.let(
513
- toml_content["build-system"],
514
- T.nilable(T::Hash[String, T.untyped])
511
+ pyproject_document.poetry_metadata ||
512
+ pyproject_document.project_metadata ||
513
+ pyproject_document.build_system_metadata,
514
+ T.nilable(PyprojectDocument::ProjectMetadata)
515
515
  )
516
516
  end
517
517
 
518
- sig { returns(T::Hash[String, T.untyped]) }
519
- def toml_content
520
- @toml_content ||= T.let(
521
- TomlRB.parse(T.must(pyproject).content),
522
- T.nilable(T::Hash[String, T.untyped])
518
+ sig { returns(PyprojectDocument) }
519
+ def pyproject_document
520
+ @pyproject_document ||= T.let(
521
+ PyprojectDocument.from_content(T.must(T.must(pyproject).content)),
522
+ T.nilable(PyprojectDocument)
523
523
  )
524
524
  end
525
525
 
@@ -528,7 +528,6 @@ module Dependabot
528
528
  dependency_files.select { |f| f.name.end_with?(".in") }
529
529
  end
530
530
  end
531
- # rubocop:enable Metrics/ClassLength
532
531
  end
533
532
  end
534
533
 
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.393.0
4
+ version: 0.395.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.393.0
18
+ version: 0.395.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.393.0
25
+ version: 0.395.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -169,28 +169,28 @@ dependencies:
169
169
  requirements:
170
170
  - - "~>"
171
171
  - !ruby/object:Gem::Version
172
- version: '0.22'
172
+ version: '1.1'
173
173
  type: :development
174
174
  prerelease: false
175
175
  version_requirements: !ruby/object:Gem::Requirement
176
176
  requirements:
177
177
  - - "~>"
178
178
  - !ruby/object:Gem::Version
179
- version: '0.22'
179
+ version: '1.1'
180
180
  - !ruby/object:Gem::Dependency
181
- name: turbo_tests
181
+ name: turbo_tests2
182
182
  requirement: !ruby/object:Gem::Requirement
183
183
  requirements:
184
184
  - - "~>"
185
185
  - !ruby/object:Gem::Version
186
- version: 2.2.5
186
+ version: 3.2.7
187
187
  type: :development
188
188
  prerelease: false
189
189
  version_requirements: !ruby/object:Gem::Requirement
190
190
  requirements:
191
191
  - - "~>"
192
192
  - !ruby/object:Gem::Version
193
- version: 2.2.5
193
+ version: 3.2.7
194
194
  - !ruby/object:Gem::Dependency
195
195
  name: vcr
196
196
  requirement: !ruby/object:Gem::Requirement
@@ -280,7 +280,10 @@ files:
280
280
  - lib/dependabot/python/dependency_grapher/requirements_layers.rb
281
281
  - lib/dependabot/python/file_fetcher.rb
282
282
  - lib/dependabot/python/file_parser.rb
283
+ - lib/dependabot/python/file_parser/pep_dependency.rb
283
284
  - lib/dependabot/python/file_parser/pipfile_files_parser.rb
285
+ - lib/dependabot/python/file_parser/poetry_lock.rb
286
+ - lib/dependabot/python/file_parser/pyproject_document.rb
284
287
  - lib/dependabot/python/file_parser/pyproject_files_parser.rb
285
288
  - lib/dependabot/python/file_parser/python_requirement_parser.rb
286
289
  - lib/dependabot/python/file_parser/setup_file_parser.rb
@@ -302,6 +305,7 @@ files:
302
305
  - lib/dependabot/python/native_helpers.rb
303
306
  - lib/dependabot/python/package/package_details_fetcher.rb
304
307
  - lib/dependabot/python/package/package_registry_finder.rb
308
+ - lib/dependabot/python/package/simple_api_parser.rb
305
309
  - lib/dependabot/python/package_manager.rb
306
310
  - lib/dependabot/python/pip_compile_file_matcher.rb
307
311
  - lib/dependabot/python/pipenv_runner.rb
@@ -323,7 +327,7 @@ licenses:
323
327
  - MIT
324
328
  metadata:
325
329
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
326
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.393.0
330
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.395.0
327
331
  rdoc_options: []
328
332
  require_paths:
329
333
  - lib