dependabot-python 0.300.0 → 0.301.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c66f1ad421fbc53cea7f4eafddfb4e31c0acb69876af1b3291407176d968e2fe
4
- data.tar.gz: f63f34f3be94781bce2e3471002b56df61b4fc8b04b0cf645f3e1d305749a302
3
+ metadata.gz: 28b4e62ed88202c96564365886f0ffe07f5554d10f77b965030e2285e7e3f63e
4
+ data.tar.gz: fed3c7384673233019c27016bac8b786b3ab54b6f0ef8abf7e9a1dee63ba7992
5
5
  SHA512:
6
- metadata.gz: 39ebf5bb262f04d910a81abbc28c48afefabd49731646289accccd9ac10d10686d180fc48ba7983ace19b06906f13eb9420202f906807d5c36a4c6caa75ea325
7
- data.tar.gz: 1435af159a0c50873c1ddfca6d335520411a3ea8e04ecef83e0c430abe20200c3e7949182c8225d60011175d1ca5876c258a628af97ef479d85608297dbeed64
6
+ metadata.gz: fdb559ea1b46ed73f5951c537b809efd9f27c5b740b15186641cc579a906a8e5f80a8779a00d09991b0e12f6d396ab37697ce0c046d0b7b2d530260ba1b0da37
7
+ data.tar.gz: 402608f1f8a90234938f732a821fff9729a20c6d4ce3b26aa4ee44fca2794c4c028eb4a8036518a7d0387430dd473cf52fe9f370b132492f3ffef8e2776a3a1c
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "toml-rb"
@@ -13,12 +13,17 @@ module Dependabot
13
13
  module Python
14
14
  class FileParser
15
15
  class PythonRequirementParser
16
+ extend T::Sig
17
+
18
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
16
19
  attr_reader :dependency_files
17
20
 
21
+ sig { params(dependency_files: T::Array[Dependabot::DependencyFile]).void }
18
22
  def initialize(dependency_files:)
19
23
  @dependency_files = dependency_files
20
24
  end
21
25
 
26
+ sig { returns(T::Array[String]) }
22
27
  def user_specified_requirements
23
28
  [
24
29
  pipfile_python_requirement,
@@ -32,22 +37,28 @@ module Dependabot
32
37
 
33
38
  # TODO: Add better Python version detection using dependency versions
34
39
  # (e.g., Django 2.x implies Python 3)
40
+ sig { returns(T::Array[String]) }
35
41
  def imputed_requirements
36
42
  requirement_files.flat_map do |file|
37
- file.content.lines
38
- .select { |l| l.include?(";") && l.include?("python") }
39
- .filter_map { |l| l.match(/python_version(?<req>.*?["'].*?['"])/) }
40
- .map { |re| re.named_captures.fetch("req").gsub(/['"]/, "") }
41
- .select { |r| valid_requirement?(r) }
43
+ T.must(file.content).lines
44
+ .select { |l| l.include?(";") && l.include?("python") }
45
+ .filter_map { |l| l.match(/python_version(?<req>.*?["'].*?['"])/) }
46
+ .map { |re| T.must(re.named_captures.fetch("req")).gsub(/['"]/, "") }
47
+ .select { |r| valid_requirement?(r) }
42
48
  end
43
49
  end
44
50
 
45
51
  private
46
52
 
53
+ # Parses the Pipfile content to extract the Python version requirement.
54
+ #
55
+ # @return [String, nil] the Python version requirement if specified in the Pipfile,
56
+ # or nil if the requirement is not present or does not start with a digit.
57
+ sig { returns(T.nilable(String)) }
47
58
  def pipfile_python_requirement
48
59
  return unless pipfile
49
60
 
50
- parsed_pipfile = TomlRB.parse(pipfile.content)
61
+ parsed_pipfile = TomlRB.parse(T.must(pipfile).content)
51
62
  requirement =
52
63
  parsed_pipfile.dig("requires", "python_full_version") ||
53
64
  parsed_pipfile.dig("requires", "python_version")
@@ -56,10 +67,11 @@ module Dependabot
56
67
  requirement
57
68
  end
58
69
 
70
+ sig { returns(T.nilable(String)) }
59
71
  def pyproject_python_requirement
60
72
  return unless pyproject
61
73
 
62
- pyproject_object = TomlRB.parse(pyproject.content)
74
+ pyproject_object = TomlRB.parse(T.must(pyproject).content)
63
75
 
64
76
  # Check for PEP621 requires-python
65
77
  pep621_python = pyproject_object.dig("project", "requires-python")
@@ -72,9 +84,10 @@ module Dependabot
72
84
  poetry_object&.dig("dev-dependencies", "python")
73
85
  end
74
86
 
87
+ sig { returns(T.nilable(String)) }
75
88
  def pip_compile_python_requirement
76
89
  requirement_files.each do |file|
77
- next unless pip_compile_file_matcher.lockfile_for_pip_compile_file?(file)
90
+ next unless T.must(pip_compile_file_matcher).lockfile_for_pip_compile_file?(file)
78
91
 
79
92
  marker = /^# This file is autogenerated by pip-compile with [pP]ython (?<version>\d+.\d+)$/m
80
93
  match = marker.match(file.content)
@@ -86,38 +99,41 @@ module Dependabot
86
99
  nil
87
100
  end
88
101
 
102
+ sig { returns(T.nilable(String)) }
89
103
  def python_version_file_version
90
104
  return unless python_version_file
91
105
 
92
106
  # read the content, split into lines and remove any lines with '#'
93
- content_lines = python_version_file.content.each_line.map do |line|
107
+ content_lines = T.must(T.must(python_version_file).content).each_line.map do |line|
94
108
  line.sub(/#.*$/, " ").strip
95
109
  end.reject(&:empty?)
96
110
 
97
111
  file_version = content_lines.first
98
112
  return if file_version&.empty?
99
- return unless pyenv_versions.include?("#{file_version}\n")
113
+ return unless T.must(pyenv_versions).include?("#{file_version}\n")
100
114
 
101
115
  file_version
102
116
  end
103
117
 
118
+ sig { returns(T.nilable(String)) }
104
119
  def runtime_file_python_version
105
120
  return unless runtime_file
106
121
 
107
- file_version = runtime_file.content
108
- .match(/(?<=python-).*/)&.to_s&.strip
122
+ file_version = T.must(T.must(runtime_file).content)
123
+ .match(/(?<=python-).*/)&.to_s&.strip
109
124
  return if file_version&.empty?
110
- return unless pyenv_versions.include?("#{file_version}\n")
125
+ return unless T.must(pyenv_versions).include?("#{file_version}\n")
111
126
 
112
127
  file_version
113
128
  end
114
129
 
130
+ sig { returns(T.nilable(String)) }
115
131
  def setup_file_requirement
116
132
  return unless setup_file
117
133
 
118
- req = setup_file.content
119
- .match(/python_requires\s*=\s*['"](?<req>[^'"]+)['"]/)
120
- &.named_captures&.fetch("req")&.strip
134
+ req = T.must(T.must(setup_file).content)
135
+ .match(/python_requires\s*=\s*['"](?<req>[^'"]+)['"]/)
136
+ &.named_captures&.fetch("req")&.strip
121
137
 
122
138
  requirement_class.new(req)
123
139
  req
@@ -125,22 +141,28 @@ module Dependabot
125
141
  nil
126
142
  end
127
143
 
144
+ sig { returns(T.nilable(String)) }
128
145
  def pyenv_versions
129
- @pyenv_versions ||= run_command("pyenv install --list")
146
+ @pyenv_versions = T.let(run_command("pyenv install --list"), T.nilable(String))
130
147
  end
131
148
 
149
+ sig { params(command: String, env: T::Hash[String, String]).returns(String) }
132
150
  def run_command(command, env: {})
133
151
  SharedHelpers.run_shell_command(command, env: env, stderr_to_stdout: true)
134
152
  end
135
153
 
154
+ sig { returns(T.nilable(PipCompileFileMatcher)) }
136
155
  def pip_compile_file_matcher
137
- @pip_compile_file_matcher ||= PipCompileFileMatcher.new(pip_compile_files)
156
+ @pip_compile_file_matcher = T.let(PipCompileFileMatcher.new(pip_compile_files),
157
+ T.nilable(PipCompileFileMatcher))
138
158
  end
139
159
 
160
+ sig { returns(T.class_of(Dependabot::Python::Requirement)) }
140
161
  def requirement_class
141
162
  Dependabot::Python::Requirement
142
163
  end
143
164
 
165
+ sig { params(req_string: String).returns(T::Boolean) }
144
166
  def valid_requirement?(req_string)
145
167
  requirement_class.new(req_string)
146
168
  true
@@ -148,36 +170,44 @@ module Dependabot
148
170
  false
149
171
  end
150
172
 
173
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
151
174
  def pipfile
152
175
  dependency_files.find { |f| f.name == "Pipfile" }
153
176
  end
154
177
 
178
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
155
179
  def pipfile_lock
156
180
  dependency_files.find { |f| f.name == "Pipfile.lock" }
157
181
  end
158
182
 
183
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
159
184
  def pyproject
160
185
  dependency_files.find { |f| f.name == "pyproject.toml" }
161
186
  end
162
187
 
188
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
163
189
  def setup_file
164
190
  dependency_files.find { |f| f.name == "setup.py" }
165
191
  end
166
192
 
193
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
167
194
  def python_version_file
168
195
  dependency_files.find { |f| f.name == ".python-version" }
169
196
  end
170
197
 
198
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
171
199
  def runtime_file
172
200
  dependency_files.find { |f| f.name.end_with?("runtime.txt") }
173
201
  end
174
202
 
203
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
175
204
  def requirement_files
176
205
  dependency_files.select { |f| f.name.end_with?(".txt") }
177
206
  end
178
207
 
208
+ sig { returns(T::Array[DependencyFile]) }
179
209
  def pip_compile_files
180
- dependency_files.select { |f| f.name.end_with?(".in") }
210
+ @pip_compile_files ||= T.let(dependency_files.select { |f| f.name.end_with?(".in") }, T.untyped)
181
211
  end
182
212
  end
183
213
  end
@@ -489,7 +489,7 @@ module Dependabot
489
489
  @setup_cfg_file ||= T.let(get_original_file("setup.cfg"), T.nilable(Dependabot::DependencyFile))
490
490
  end
491
491
 
492
- sig { returns(T::Array[Dependabot::Python::Requirement]) }
492
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
493
493
  def pip_compile_files
494
494
  @pip_compile_files ||= T.let(dependency_files.select { |f| f.name.end_with?(".in") }, T.untyped)
495
495
  end
@@ -268,11 +268,13 @@ module Dependabot
268
268
 
269
269
  sig do
270
270
  params(
271
- releases_json: T::Hash[String, T::Array[T::Hash[String, T.untyped]]]
271
+ releases_json: T.nilable(T::Hash[String, T::Array[T::Hash[String, T.untyped]]])
272
272
  )
273
273
  .returns(T::Array[Dependabot::Package::PackageRelease])
274
274
  end
275
275
  def format_version_releases(releases_json)
276
+ return [] unless releases_json
277
+
276
278
  releases_json.each_with_object([]) do |(version, release_data_array), versions|
277
279
  release_data = release_data_array.last
278
280
 
@@ -6,7 +6,7 @@ module Dependabot
6
6
  class PipCompileFileMatcher
7
7
  extend T::Sig
8
8
 
9
- sig { params(requirements_in_files: T::Array[Dependabot::Python::Requirement]).void }
9
+ sig { params(requirements_in_files: T::Array[DependencyFile]).void }
10
10
  def initialize(requirements_in_files)
11
11
  @requirements_in_files = requirements_in_files
12
12
  end
@@ -26,7 +26,7 @@ module Dependabot
26
26
 
27
27
  private
28
28
 
29
- sig { returns(T::Array[Dependabot::Python::Requirement]) }
29
+ sig { returns(T::Array[DependencyFile]) }
30
30
  attr_reader :requirements_in_files
31
31
 
32
32
  sig { params(filename: T.any(String, Symbol)).returns(String) }
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.300.0
4
+ version: 0.301.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-06 00:00:00.000000000 Z
11
+ date: 2025-03-14 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.300.0
19
+ version: 0.301.1
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.300.0
26
+ version: 0.301.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: debug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -291,7 +291,7 @@ licenses:
291
291
  - MIT
292
292
  metadata:
293
293
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
294
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.300.0
294
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.301.1
295
295
  post_install_message:
296
296
  rdoc_options: []
297
297
  require_paths: