dependabot-python 0.320.0 → 0.320.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: f0702ead6e162d8ab1c6c3312b16620169ce2dd6cd30c04fa937e3909d22a245
4
- data.tar.gz: 365947fe59fd061e56a5426029ed48380eafa2b23aa7ded3e9695d815ef74ee9
3
+ metadata.gz: 00d45a37835e5785c9841a4475f87a754fb3f2800daaf89d15e34d78e5e416c5
4
+ data.tar.gz: dac9639715dc1660dc9d9c50b3e08b4e22ac8f655046c7a991e4f53e3351ef60
5
5
  SHA512:
6
- metadata.gz: 8166aafb40a4af86a00f166bc19b7cf24557d960a91e7415e4d26ef30447308fcd6c7e17fd9076fdce46e34a7f51a90c6a9161af9daf40a4fe34500a22fa4dfa
7
- data.tar.gz: 424b4db8fd30478428bbc18c7031e61724d1daec06179b5cc1c1c0f695f6c142beef4b70e5544be9ef0a8a60bc82293690b1e3c5b216c6fe39865c1e52a567fd
6
+ metadata.gz: 2b33c038c1cee0219c806f572586163fc96b18d3492be731cf700b94fa6e6e65794be0b7e4fb2055ca9e27307f43468a2ed21fad3d7a404bdddf6370bf4cf5c7
7
+ data.tar.gz: 994c93fb24321b05f54c0d15434421123c7ef735ec59c945e059fd76e60aba447dd291a496e4f1db930b14086434f984309c0483fffcee9d4d511cec96d34af7
@@ -1,12 +1,17 @@
1
- # typed: true
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
5
+
4
6
  module Dependabot
5
7
  module Python
6
8
  class AuthedUrlBuilder
9
+ extend T::Sig
10
+
11
+ sig { params(credential: Credential).returns(String) }
7
12
  def self.authed_url(credential:)
8
- token = credential.fetch("token", nil)
9
- url = credential.fetch("index-url", nil)
13
+ token = T.let(credential.fetch("token", nil), T.nilable(String))
14
+ url = T.let(credential.fetch("index-url", nil), T.nilable(String))
10
15
  return "" unless url
11
16
  return url unless token
12
17
 
@@ -48,13 +48,13 @@ module Dependabot
48
48
  dependencies: T::Array[Dependabot::Dependency],
49
49
  dependency_files: T::Array[Dependabot::DependencyFile],
50
50
  credentials: T::Array[Dependabot::Credential],
51
- index_urls: T.nilable(T::Array[String])
51
+ index_urls: T.nilable(T::Array[T.nilable(String)])
52
52
  ).void
53
53
  end
54
- def initialize(dependencies:, dependency_files:, credentials:, index_urls: nil)
54
+ def initialize(dependencies:, dependency_files:, credentials:, index_urls: nil) # rubocop:disable Metrics/AbcSize
55
55
  @dependencies = T.let(dependencies, T::Array[Dependabot::Dependency])
56
56
  @dependency_files = T.let(dependency_files, T::Array[Dependabot::DependencyFile])
57
- @index_urls = T.let(index_urls, T.nilable(T::Array[String]))
57
+ @index_urls = T.let(index_urls, T.nilable(T::Array[T.nilable(String)]))
58
58
  @build_isolation = T.let(true, T::Boolean)
59
59
  @sanitized_setup_file_content = T.let({}, T::Hash[String, String])
60
60
  @requirement_map = T.let(nil, T.nilable(T::Hash[String, T::Array[String]]))
@@ -312,7 +312,7 @@ module Dependabot
312
312
  return file.content if old_req == "==#{T.must(dependency).version}"
313
313
 
314
314
  RequirementReplacer.new(
315
- content: file.content,
315
+ content: T.must(file.content),
316
316
  dependency_name: T.must(dependency).name,
317
317
  old_requirement: old_req[:requirement],
318
318
  new_requirement: "==#{T.must(dependency).version}",
@@ -332,7 +332,7 @@ module Dependabot
332
332
  return file.content if old_req == new_req
333
333
 
334
334
  RequirementReplacer.new(
335
- content: file.content,
335
+ content: T.must(file.content),
336
336
  dependency_name: T.must(dependency).name,
337
337
  old_requirement: old_req[:requirement],
338
338
  new_requirement: T.must(new_req)[:requirement],
@@ -1,6 +1,7 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
4
5
  require "dependabot/python/requirement_parser"
5
6
  require "dependabot/python/file_updater"
6
7
  require "dependabot/shared_helpers"
@@ -10,37 +11,56 @@ module Dependabot
10
11
  module Python
11
12
  class FileUpdater
12
13
  class RequirementFileUpdater
14
+ extend T::Sig
15
+
13
16
  require_relative "requirement_replacer"
14
17
 
18
+ sig { returns(T::Array[Dependabot::Dependency]) }
15
19
  attr_reader :dependencies
20
+
21
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
16
22
  attr_reader :dependency_files
23
+
24
+ sig { returns(T::Array[Dependabot::Credential]) }
17
25
  attr_reader :credentials
18
26
 
27
+ sig do
28
+ params(
29
+ dependencies: T::Array[Dependabot::Dependency],
30
+ dependency_files: T::Array[Dependabot::DependencyFile],
31
+ credentials: T::Array[Dependabot::Credential],
32
+ index_urls: T.nilable(T::Array[T.nilable(String)])
33
+ ).void
34
+ end
19
35
  def initialize(dependencies:, dependency_files:, credentials:, index_urls: nil)
20
- @dependencies = dependencies
21
- @dependency_files = dependency_files
22
- @credentials = credentials
23
- @index_urls = index_urls
36
+ @dependencies = T.let(dependencies, T::Array[Dependabot::Dependency])
37
+ @dependency_files = T.let(dependency_files, T::Array[Dependabot::DependencyFile])
38
+ @credentials = T.let(credentials, T::Array[Dependabot::Credential])
39
+ @index_urls = T.let(index_urls, T.nilable(T::Array[T.nilable(String)]))
40
+ @updated_dependency_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
24
41
  end
25
42
 
43
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
26
44
  def updated_dependency_files
27
45
  @updated_dependency_files ||= fetch_updated_dependency_files
28
46
  end
29
47
 
30
48
  private
31
49
 
50
+ sig { returns(Dependabot::Dependency) }
32
51
  def dependency
33
52
  # For now, we'll only ever be updating a single dependency
34
- dependencies.first
53
+ T.must(dependencies.first)
35
54
  end
36
55
 
56
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
37
57
  def fetch_updated_dependency_files
38
- reqs = dependency.requirements.zip(dependency.previous_requirements)
58
+ reqs = dependency.requirements.zip(dependency.previous_requirements || [])
39
59
 
40
60
  reqs.filter_map do |(new_req, old_req)|
41
61
  next if new_req == old_req
42
62
 
43
- file = get_original_file(new_req.fetch(:file)).dup
63
+ file = T.must(get_original_file(new_req.fetch(:file))).dup
44
64
  updated_content =
45
65
  updated_requirement_or_setup_file_content(new_req, old_req)
46
66
  next if updated_content == file.content
@@ -50,20 +70,27 @@ module Dependabot
50
70
  end
51
71
  end
52
72
 
73
+ sig do
74
+ params(
75
+ new_req: T::Hash[Symbol, T.untyped],
76
+ old_req: T.nilable(T::Hash[Symbol, T.untyped])
77
+ ).returns(String)
78
+ end
53
79
  def updated_requirement_or_setup_file_content(new_req, old_req)
54
80
  original_file = get_original_file(new_req.fetch(:file))
55
81
  raise "Could not find a dependency file for #{new_req}" unless original_file
56
82
 
57
83
  RequirementReplacer.new(
58
- content: original_file.content,
84
+ content: T.must(original_file.content),
59
85
  dependency_name: dependency.name,
60
- old_requirement: old_req.fetch(:requirement),
86
+ old_requirement: old_req&.fetch(:requirement),
61
87
  new_requirement: new_req.fetch(:requirement),
62
88
  new_hash_version: dependency.version,
63
89
  index_urls: @index_urls
64
90
  ).updated_content
65
91
  end
66
92
 
93
+ sig { params(filename: String).returns(T.nilable(Dependabot::DependencyFile)) }
67
94
  def get_original_file(filename)
68
95
  dependency_files.find { |f| f.name == filename }
69
96
  end
@@ -1,6 +1,7 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
4
5
  require "dependabot/dependency"
5
6
  require "dependabot/python/requirement_parser"
6
7
  require "dependabot/python/file_updater"
@@ -12,20 +13,33 @@ module Dependabot
12
13
  module Python
13
14
  class FileUpdater
14
15
  class RequirementReplacer
16
+ extend T::Sig
17
+
15
18
  PACKAGE_NOT_FOUND_ERROR = "PackageNotFoundError"
16
19
 
17
20
  CERTIFICATE_VERIFY_FAILED = /CERTIFICATE_VERIFY_FAILED/
18
21
 
22
+ sig do
23
+ params(
24
+ content: String,
25
+ dependency_name: String,
26
+ old_requirement: T.nilable(String),
27
+ new_requirement: T.nilable(String),
28
+ new_hash_version: T.nilable(String),
29
+ index_urls: T.nilable(T::Array[T.nilable(String)])
30
+ ).void
31
+ end
19
32
  def initialize(content:, dependency_name:, old_requirement:,
20
33
  new_requirement:, new_hash_version: nil, index_urls: nil)
21
- @content = content
22
- @dependency_name = normalise(dependency_name)
23
- @old_requirement = old_requirement
24
- @new_requirement = new_requirement
25
- @new_hash_version = new_hash_version
26
- @index_urls = index_urls
34
+ @content = T.let(content, String)
35
+ @dependency_name = T.let(normalise(dependency_name), String)
36
+ @old_requirement = T.let(old_requirement, T.nilable(String))
37
+ @new_requirement = T.let(new_requirement, T.nilable(String))
38
+ @new_hash_version = T.let(new_hash_version, T.nilable(String))
39
+ @index_urls = T.let(index_urls, T.nilable(T::Array[T.nilable(String)]))
27
40
  end
28
41
 
42
+ sig { returns(String) }
29
43
  def updated_content
30
44
  updated_content =
31
45
  content.gsub(original_declaration_replacement_regex) do |mtch|
@@ -43,40 +57,52 @@ module Dependabot
43
57
 
44
58
  private
45
59
 
60
+ sig { returns(String) }
46
61
  attr_reader :content
62
+
63
+ sig { returns(String) }
47
64
  attr_reader :dependency_name
65
+
66
+ sig { returns(T.nilable(String)) }
48
67
  attr_reader :old_requirement
68
+
69
+ sig { returns(T.nilable(String)) }
49
70
  attr_reader :new_requirement
71
+
72
+ sig { returns(T.nilable(String)) }
50
73
  attr_reader :new_hash_version
51
74
 
75
+ sig { returns(T::Boolean) }
52
76
  def update_hashes?
53
77
  !new_hash_version.nil?
54
78
  end
55
79
 
80
+ sig { returns(T.nilable(String)) }
56
81
  def updated_requirement_string
57
82
  new_req_string = new_requirement
58
83
 
59
- new_req_string = new_req_string.gsub(/,\s*/, ", ") if add_space_after_commas?
84
+ new_req_string = new_req_string&.gsub(/,\s*/, ", ") if add_space_after_commas?
60
85
 
61
86
  if add_space_after_operators?
62
87
  new_req_string =
63
88
  new_req_string
64
- .gsub(/(#{RequirementParser::COMPARISON})\s*(?=\d)/o, '\1 ')
89
+ &.gsub(/(#{RequirementParser::COMPARISON})\s*(?=\d)/o, '\1 ')
65
90
  end
66
91
 
67
92
  new_req_string
68
93
  end
69
94
 
95
+ sig { returns(String) }
70
96
  def updated_dependency_declaration_string
71
97
  old_req = old_requirement
72
98
  updated_string =
73
99
  if old_req
74
100
  original_dependency_declaration_string(old_req)
75
- .sub(RequirementParser::REQUIREMENTS, updated_requirement_string)
101
+ .sub(RequirementParser::REQUIREMENTS, updated_requirement_string || "")
76
102
  else
77
103
  original_dependency_declaration_string(old_req)
78
104
  .sub(RequirementParser::NAME_WITH_EXTRAS) do |nm|
79
- nm + updated_requirement_string
105
+ (nm + (updated_requirement_string || ""))
80
106
  end
81
107
  end
82
108
 
@@ -92,55 +118,59 @@ module Dependabot
92
118
  )
93
119
  end
94
120
 
121
+ sig { returns(T::Boolean) }
95
122
  def add_space_after_commas?
96
123
  original_dependency_declaration_string(old_requirement)
97
124
  .match(RequirementParser::REQUIREMENTS)
98
125
  .to_s.include?(", ")
99
126
  end
100
127
 
128
+ sig { returns(T::Boolean) }
101
129
  def add_space_after_operators?
102
130
  original_dependency_declaration_string(old_requirement)
103
131
  .match(RequirementParser::REQUIREMENTS)
104
132
  .to_s.match?(/#{RequirementParser::COMPARISON}\s+\d/o)
105
133
  end
106
134
 
135
+ sig { returns(Regexp) }
107
136
  def original_declaration_replacement_regex
108
137
  original_string =
109
138
  original_dependency_declaration_string(old_requirement)
110
139
  /(?<![\-\w\.\[])#{Regexp.escape(original_string)}(?![\-\w\.])/
111
140
  end
112
141
 
142
+ sig { params(requirement: T.nilable(String)).returns(T::Boolean) }
113
143
  def requirement_includes_hashes?(requirement)
114
144
  original_dependency_declaration_string(requirement)
115
145
  .match?(RequirementParser::HASHES)
116
146
  end
117
147
 
148
+ sig { params(requirement: T.nilable(String)).returns(T.nilable(String)) }
118
149
  def hash_algorithm(requirement)
119
150
  return unless requirement_includes_hashes?(requirement)
120
151
 
121
- original_dependency_declaration_string(requirement)
122
- .match(RequirementParser::HASHES)
123
- .named_captures.fetch("algorithm")
152
+ matches = T.must(original_dependency_declaration_string(requirement).match(RequirementParser::HASHES))
153
+ matches.named_captures.fetch("algorithm")
124
154
  end
125
155
 
156
+ sig { params(requirement: T.nilable(String)).returns(String) }
126
157
  def hash_separator(requirement)
127
- return unless requirement_includes_hashes?(requirement)
158
+ return "" unless requirement_includes_hashes?(requirement)
128
159
 
129
160
  hash_regex = RequirementParser::HASH
130
- current_separator =
131
- original_dependency_declaration_string(requirement)
132
- .match(/#{hash_regex}((?<separator>\s*\\?\s*?)#{hash_regex})*/)
133
- .named_captures.fetch("separator")
161
+ matches = T.must(original_dependency_declaration_string(requirement)
162
+ .match(/#{hash_regex}((?<separator>\s*\\?\s*?)#{hash_regex})*/))
163
+ current_separator = matches.named_captures.fetch("separator")
134
164
 
135
- default_separator =
136
- original_dependency_declaration_string(requirement)
137
- .match(RequirementParser::HASH)
138
- .pre_match.match(/(?<separator>\s*\\?\s*?)\z/)
139
- .named_captures.fetch("separator")
165
+ hash_matches = T.must(T.must(original_dependency_declaration_string(requirement)
166
+ .match(RequirementParser::HASH)).pre_match.match(/(?<separator>\s*\\?\s*?)\z/))
167
+ default_separator = hash_matches
168
+ .named_captures.fetch("separator")
140
169
 
141
- current_separator || default_separator
170
+ current_separator || default_separator || ""
142
171
  end
143
172
 
173
+ sig { params(name: String, version: T.nilable(String), algorithm: T.nilable(String)).returns(T::Array[String]) }
144
174
  def package_hashes_for(name:, version:, algorithm:)
145
175
  index_urls = @index_urls || [nil]
146
176
 
@@ -168,6 +198,7 @@ module Dependabot
168
198
  raise Dependabot::DependencyFileNotResolvable, "Unable to find hashes for package #{name}"
169
199
  end
170
200
 
201
+ sig { params(old_req: T.nilable(String)).returns(String) }
171
202
  def original_dependency_declaration_string(old_req)
172
203
  matches = []
173
204
 
@@ -189,10 +220,12 @@ module Dependabot
189
220
  dec.to_s.strip
190
221
  end
191
222
 
223
+ sig { params(name: String).returns(String) }
192
224
  def normalise(name)
193
225
  NameNormaliser.normalise(name)
194
226
  end
195
227
 
228
+ sig { params(req1: T.nilable(String), req2: T.nilable(String)).returns(T::Boolean) }
196
229
  def requirements_match(req1, req2)
197
230
  req1&.split(",")&.map { |r| r.gsub(/\s/, "") }&.sort ==
198
231
  req2&.split(",")&.map { |r| r.gsub(/\s/, "") }&.sort
@@ -200,6 +233,7 @@ module Dependabot
200
233
 
201
234
  public
202
235
 
236
+ sig { params(error: Exception).void }
203
237
  def requirement_error_handler(error)
204
238
  Dependabot.logger.warn(error.message)
205
239
 
@@ -1,6 +1,7 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
4
5
  require "dependabot/python/file_updater"
5
6
  require "dependabot/python/file_parser/setup_file_parser"
6
7
 
@@ -10,11 +11,24 @@ module Dependabot
10
11
  # Take a setup.py, parses it (carefully!) and then create a new, clean
11
12
  # setup.py using only the information which will appear in the lockfile.
12
13
  class SetupFileSanitizer
14
+ extend T::Sig
15
+
16
+ sig do
17
+ params(
18
+ setup_file: T.nilable(Dependabot::DependencyFile),
19
+ setup_cfg: T.nilable(Dependabot::DependencyFile)
20
+ ).void
21
+ end
13
22
  def initialize(setup_file:, setup_cfg:)
14
- @setup_file = setup_file
15
- @setup_cfg = setup_cfg
23
+ @setup_file = T.let(setup_file, T.nilable(Dependabot::DependencyFile))
24
+ @setup_cfg = T.let(setup_cfg, T.nilable(Dependabot::DependencyFile))
25
+ @install_requires_array = T.let(nil, T.nilable(T::Array[String]))
26
+ @setup_requires_array = T.let(nil, T.nilable(T::Array[String]))
27
+ @extras_require_hash = T.let(nil, T.nilable(T::Hash[String, T::Array[String]]))
28
+ @parsed_setup_file = T.let(nil, T.nilable(Dependabot::FileParsers::Base::DependencySet))
16
29
  end
17
30
 
31
+ sig { returns(String) }
18
32
  def sanitized_content
19
33
  # The part of the setup.py that Pipenv cares about appears to be the
20
34
  # install_requires. A name and version are required by don't end up
@@ -31,44 +45,54 @@ module Dependabot
31
45
 
32
46
  private
33
47
 
48
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
34
49
  attr_reader :setup_file
50
+
51
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
35
52
  attr_reader :setup_cfg
36
53
 
54
+ sig { returns(T::Boolean) }
37
55
  def include_pbr?
38
56
  setup_requires_array.any? { |d| d.start_with?("pbr") }
39
57
  end
40
58
 
59
+ sig { returns(T::Array[String]) }
41
60
  def install_requires_array
42
61
  @install_requires_array ||=
43
62
  parsed_setup_file.dependencies.filter_map do |dep|
44
- next unless dep.requirements.first[:groups]
45
- .include?("install_requires")
63
+ first = T.must(dep.requirements.first)
64
+ next unless first[:groups]
65
+ .include?("install_requires")
46
66
 
47
- dep.name + dep.requirements.first[:requirement].to_s
67
+ dep.name + first[:requirement].to_s
48
68
  end
49
69
  end
50
70
 
71
+ sig { returns(T::Array[String]) }
51
72
  def setup_requires_array
52
73
  @setup_requires_array ||=
53
74
  parsed_setup_file.dependencies.filter_map do |dep|
54
- next unless dep.requirements.first[:groups]
55
- .include?("setup_requires")
75
+ first = T.must(dep.requirements.first)
76
+ next unless first[:groups]
77
+ .include?("setup_requires")
56
78
 
57
- dep.name + dep.requirements.first[:requirement].to_s
79
+ dep.name + first[:requirement].to_s
58
80
  end
59
81
  end
60
82
 
83
+ sig { returns(T::Hash[String, T::Array[String]]) }
61
84
  def extras_require_hash
62
85
  @extras_require_hash ||=
63
86
  begin
64
87
  hash = {}
65
88
  parsed_setup_file.dependencies.each do |dep|
66
- dep.requirements.first[:groups].each do |group|
89
+ first = T.must(dep.requirements.first)
90
+ first[:groups].each do |group|
67
91
  next unless group.start_with?("extras_require:")
68
92
 
69
93
  hash[group.split(":").last] ||= []
70
94
  hash[group.split(":").last] <<
71
- (dep.name + dep.requirements.first[:requirement].to_s)
95
+ (dep.name + first[:requirement].to_s)
72
96
  end
73
97
  end
74
98
 
@@ -76,6 +100,7 @@ module Dependabot
76
100
  end
77
101
  end
78
102
 
103
+ sig { returns(Dependabot::FileParsers::Base::DependencySet) }
79
104
  def parsed_setup_file
80
105
  @parsed_setup_file ||=
81
106
  Python::FileParser::SetupFileParser.new(
@@ -86,10 +111,11 @@ module Dependabot
86
111
  ).dependency_set
87
112
  end
88
113
 
114
+ sig { returns(String) }
89
115
  def package_name
90
- content = setup_file.content
116
+ content = T.must(T.must(setup_file).content)
91
117
  match = content.match(/name\s*=\s*['"](?<package_name>[^'"]+)['"]/)
92
- match ? match[:package_name] : "default_package_name"
118
+ match ? T.must(match[:package_name]) : "default_package_name"
93
119
  end
94
120
  end
95
121
  end
@@ -132,7 +132,7 @@ module Dependabot
132
132
  ).updated_dependency_files
133
133
  end
134
134
 
135
- sig { returns(T::Array[String]) }
135
+ sig { returns(T::Array[T.nilable(String)]) }
136
136
  def pip_compile_index_urls
137
137
  if credentials.any?(&:replaces_base?)
138
138
  credentials.select(&:replaces_base?).map { |cred| AuthedUrlBuilder.authed_url(credential: cred) }