dependabot-python 0.227.0 → 0.228.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb1b6edd3b3d295491ad39866fa4a7d480f9322bd60a6a05e2d9a8e7eb3c9462
4
- data.tar.gz: 3b6397f0af03444908c3b87cc6dfbc173b38f0e5ae54bc5528c6588ea3e4655a
3
+ metadata.gz: 67fcdac9ca728ef251cf259a11a3d1efec3f037715f9587bc30896baf3abcad9
4
+ data.tar.gz: 00cf4ecfceeba160a6ccb95c84853f782df01f571ea17b320609205a6138e76e
5
5
  SHA512:
6
- metadata.gz: 295996b49310faa8aa04502f057963a0a3e21289a800be24780fcdc38c4533d0496e88a4b9a0b6722d526e707ee51cadb30a91916a882db4fb95aa8f8f2d9ebd
7
- data.tar.gz: 71b07d3ed46fe06aeecce18cf2dc42da67143be4953e9b45e051cad4e57f84332fda400b071139695847a1e7eaf8ee4c4fc6da50a03dfc9d00a81979e0ffc10c
6
+ metadata.gz: e320bfeef5f545705df3daf17edf15cf9633b3ed2a6438bc1cd12ec3fc66d8abd1248d20898b0a8aca1d3aaa86f1b512f951179c4708706af36d64a93b0a5933
7
+ data.tar.gz: 9bc806e1d363784ed23ed71d694154e8d37f967bb1d559348852fffdde381889b2f235658b5dc424c9400589483d76c08b5f1f608eb15e43e59e70bc773a266a
@@ -1,9 +1,10 @@
1
- pip==23.2.0
2
- pip-tools==7.2.0
1
+ pip==23.2.1
2
+ pip-tools==7.3.0
3
+ flake8==6.1.0
3
4
  hashin==0.17.0
4
5
  pipenv==2022.4.8
5
6
  pipfile==0.0.2
6
- poetry==1.5.1
7
+ poetry==1.6.1
7
8
 
8
9
  # Some dependencies will only install if Cython is present
9
10
  Cython==3.0.0
@@ -4,8 +4,10 @@ require "toml-rb"
4
4
 
5
5
  require "dependabot/file_fetchers"
6
6
  require "dependabot/file_fetchers/base"
7
+ require "dependabot/python/language_version_manager"
7
8
  require "dependabot/python/requirement_parser"
8
9
  require "dependabot/python/file_parser/pyproject_files_parser"
10
+ require "dependabot/python/file_parser/python_requirement_parser"
9
11
  require "dependabot/errors"
10
12
 
11
13
  module Dependabot
@@ -7,6 +7,7 @@ require "dependabot/file_parsers/base/dependency_set"
7
7
  require "dependabot/python/file_parser"
8
8
  require "dependabot/python/requirement"
9
9
  require "dependabot/errors"
10
+ require "dependabot/python/helpers"
10
11
  require "dependabot/python/name_normaliser"
11
12
 
12
13
  module Dependabot
@@ -44,16 +45,20 @@ module Dependabot
44
45
  end
45
46
 
46
47
  def poetry_dependencies
48
+ @poetry_dependencies ||= parse_poetry_dependencies
49
+ end
50
+
51
+ def parse_poetry_dependencies
47
52
  dependencies = Dependabot::FileParsers::Base::DependencySet.new
48
53
 
49
54
  POETRY_DEPENDENCY_TYPES.each do |type|
50
55
  deps_hash = parsed_pyproject.dig("tool", "poetry", type) || {}
51
- dependencies += parse_poetry_dependencies(type, deps_hash)
56
+ dependencies += parse_poetry_dependency_group(type, deps_hash)
52
57
  end
53
58
 
54
59
  groups = parsed_pyproject.dig("tool", "poetry", "group") || {}
55
60
  groups.each do |group, group_spec|
56
- dependencies += parse_poetry_dependencies(group, group_spec["dependencies"])
61
+ dependencies += parse_poetry_dependency_group(group, group_spec["dependencies"])
57
62
  end
58
63
  dependencies
59
64
  end
@@ -92,7 +97,7 @@ module Dependabot
92
97
  dependencies
93
98
  end
94
99
 
95
- def parse_poetry_dependencies(type, deps_hash)
100
+ def parse_poetry_dependency_group(type, deps_hash)
96
101
  dependencies = Dependabot::FileParsers::Base::DependencySet.new
97
102
 
98
103
  deps_hash.each do |name, req|
@@ -154,14 +159,16 @@ module Dependabot
154
159
  parsed_lockfile.fetch("package", []).each do |details|
155
160
  next if source_types.include?(details.dig("source", "type"))
156
161
 
162
+ name = normalise(details.fetch("name"))
163
+
157
164
  dependencies <<
158
165
  Dependency.new(
159
- name: normalise(details.fetch("name")),
166
+ name: name,
160
167
  version: details.fetch("version"),
161
168
  requirements: [],
162
169
  package_manager: "pip",
163
170
  subdependency_metadata: [{
164
- production: details["category"] != "dev"
171
+ production: production_dependency_names.include?(name)
165
172
  }]
166
173
  )
167
174
  end
@@ -169,6 +176,32 @@ module Dependabot
169
176
  dependencies
170
177
  end
171
178
 
179
+ def production_dependency_names
180
+ @production_dependency_names ||= parse_production_dependency_names
181
+ end
182
+
183
+ def parse_production_dependency_names
184
+ SharedHelpers.in_a_temporary_directory do
185
+ File.write(pyproject.name, pyproject.content)
186
+ File.write(lockfile.name, lockfile.content)
187
+
188
+ begin
189
+ output = Helpers.run_poetry_command("pyenv exec poetry show --only main")
190
+
191
+ output.split("\n").map { |line| line.split.first }
192
+ rescue SharedHelpers::HelperSubprocessFailed
193
+ # Sometimes, we may be dealing with an old lockfile that our
194
+ # poetry version can't show dependency information for. Other
195
+ # commands we use like `poetry update` are more resilient and
196
+ # automatically heal the lockfile. So we rescue the error and make
197
+ # a best effort approach to this.
198
+ poetry_dependencies.dependencies.filter_map do |dep|
199
+ dep.name if dep.production?
200
+ end
201
+ end
202
+ end
203
+ end
204
+
172
205
  def version_from_lockfile(dep_name)
173
206
  return unless parsed_lockfile
174
207
 
@@ -228,7 +261,7 @@ module Dependabot
228
261
  end
229
262
 
230
263
  def parsed_lockfile
231
- return parsed_poetry_lock if poetry_lock
264
+ parsed_poetry_lock if poetry_lock
232
265
  end
233
266
 
234
267
  def poetry_lock
@@ -8,8 +8,8 @@ require "dependabot/python/language_version_manager"
8
8
  require "dependabot/python/version"
9
9
  require "dependabot/python/requirement"
10
10
  require "dependabot/python/file_parser/python_requirement_parser"
11
- require "dependabot/python/file_parser/subdependency_type_parser"
12
11
  require "dependabot/python/file_updater"
12
+ require "dependabot/python/helpers"
13
13
  require "dependabot/python/native_helpers"
14
14
  require "dependabot/python/name_normaliser"
15
15
 
@@ -95,6 +95,12 @@ module Dependabot
95
95
  begin
96
96
  new_lockfile = updated_lockfile_content_for(prepared_pyproject)
97
97
 
98
+ original_locked_python = TomlRB.parse(lockfile.content)["metadata"]["python-versions"]
99
+
100
+ new_lockfile.gsub!(/\[metadata\]\n.*python-versions[^\n]+\n/m) do |match|
101
+ match.gsub(/(["']).*(['"])\n\Z/, '\1' + original_locked_python + '\1' + "\n")
102
+ end
103
+
98
104
  tmp_hash =
99
105
  TomlRB.parse(new_lockfile)["metadata"]["content-hash"]
100
106
  correct_hash = pyproject_hash_for(updated_pyproject_content)
@@ -139,7 +145,7 @@ module Dependabot
139
145
  def update_python_requirement(pyproject_content)
140
146
  PyprojectPreparer.
141
147
  new(pyproject_content: pyproject_content).
142
- update_python_requirement(language_version_manager.python_major_minor)
148
+ update_python_requirement(language_version_manager.python_version)
143
149
  end
144
150
 
145
151
  def lock_declaration_to_new_version!(poetry_object, dep)
@@ -157,7 +163,7 @@ module Dependabot
157
163
  end
158
164
 
159
165
  def create_declaration_at_new_version!(poetry_object, dep)
160
- subdep_type = subdependency_type_parser.subdep_type(dep)
166
+ subdep_type = dep.production? ? "dependencies" : "dev-dependencies"
161
167
 
162
168
  poetry_object[subdep_type] ||= {}
163
169
  poetry_object[subdep_type][dep.name] = dep.version
@@ -197,24 +203,7 @@ module Dependabot
197
203
  end
198
204
 
199
205
  def run_poetry_command(command, fingerprint: nil)
200
- start = Time.now
201
- command = SharedHelpers.escape_command(command)
202
- stdout, process = Open3.capture2e(command)
203
- time_taken = Time.now - start
204
-
205
- # Raise an error with the output from the shell session if Pipenv
206
- # returns a non-zero status
207
- return if process.success?
208
-
209
- raise SharedHelpers::HelperSubprocessFailed.new(
210
- message: stdout,
211
- error_context: {
212
- command: command,
213
- fingerprint: fingerprint,
214
- time_taken: time_taken,
215
- process_exit_value: process.to_s
216
- }
217
- )
206
+ Helpers.run_poetry_command(command, fingerprint: fingerprint)
218
207
  end
219
208
 
220
209
  def write_temporary_dependency_files(pyproject_content)
@@ -291,13 +280,6 @@ module Dependabot
291
280
  )
292
281
  end
293
282
 
294
- def subdependency_type_parser
295
- @subdependency_type_parser ||=
296
- FileParser::PoetrySubdependencyTypeParser.new(
297
- lockfile: lockfile
298
- )
299
- end
300
-
301
283
  def language_version_manager
302
284
  @language_version_manager ||=
303
285
  LanguageVersionManager.new(
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
4
+ require "open3"
5
+
6
+ require "dependabot/errors"
7
+ require "dependabot/shared_helpers"
8
+
9
+ module Dependabot
10
+ module Python
11
+ module Helpers
12
+ def self.run_poetry_command(command, fingerprint: nil)
13
+ start = Time.now
14
+ command = SharedHelpers.escape_command(command)
15
+ stdout, stderr, process = Open3.capture3(command)
16
+ time_taken = Time.now - start
17
+
18
+ # Raise an error with the output from the shell session if Poetry
19
+ # returns a non-zero status
20
+ return stdout if process.success?
21
+
22
+ raise SharedHelpers::HelperSubprocessFailed.new(
23
+ message: stderr,
24
+ error_context: {
25
+ command: command,
26
+ fingerprint: fingerprint,
27
+ time_taken: time_taken,
28
+ process_exit_value: process.to_s
29
+ }
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
@@ -43,10 +43,8 @@ module Dependabot
43
43
  else
44
44
  user_specified_python_version
45
45
  end
46
- elsif python_version_matching_imputed_requirements
47
- python_version_matching_imputed_requirements
48
46
  else
49
- PythonVersions::PRE_INSTALLED_PYTHON_VERSIONS.first
47
+ python_version_matching_imputed_requirements || PRE_INSTALLED_PYTHON_VERSIONS.first
50
48
  end
51
49
  end
52
50
 
@@ -118,6 +118,9 @@ module Dependabot
118
118
  []
119
119
 
120
120
  sources.each do |source|
121
+ # If source is PyPI, skip it, and let it pick the default URI
122
+ next if source["name"].casecmp?("PyPI")
123
+
121
124
  if source["default"]
122
125
  urls[:main] = source["url"]
123
126
  else
@@ -39,7 +39,7 @@ module Dependabot
39
39
 
40
40
  UNSUPPORTED_DEPS = %w(pyobjc).freeze
41
41
  UNSUPPORTED_DEP_REGEX =
42
- /Could not find a version that satisfies the requirement.*(?:#{UNSUPPORTED_DEPS.join("|")})/
42
+ /Could not find a version that satisfies the requirement.*(?:#{UNSUPPORTED_DEPS.join('|')})/
43
43
  PIPENV_RANGE_WARNING = /Warning:\sPython\s[<>].* was not found/
44
44
  # rubocop:enable Layout/LineLength
45
45
 
@@ -207,15 +207,13 @@ module Dependabot
207
207
  # errors when failing to update
208
208
  def check_original_requirements_resolvable
209
209
  SharedHelpers.in_a_temporary_directory do
210
- SharedHelpers.with_git_configured(credentials: credentials) do
211
- write_temporary_dependency_files(update_pipfile: false)
210
+ write_temporary_dependency_files(update_pipfile: false)
212
211
 
213
- run_pipenv_command("pyenv exec pipenv lock")
212
+ run_pipenv_command("pyenv exec pipenv lock")
214
213
 
215
- true
216
- rescue SharedHelpers::HelperSubprocessFailed => e
217
- handle_pipenv_errors_resolving_original_reqs(e)
218
- end
214
+ true
215
+ rescue SharedHelpers::HelperSubprocessFailed => e
216
+ handle_pipenv_errors_resolving_original_reqs(e)
219
217
  end
220
218
  end
221
219
 
@@ -9,11 +9,11 @@ require "dependabot/errors"
9
9
  require "dependabot/shared_helpers"
10
10
  require "dependabot/python/file_parser"
11
11
  require "dependabot/python/file_parser/python_requirement_parser"
12
- require "dependabot/python/file_parser/subdependency_type_parser"
13
12
  require "dependabot/python/file_updater/pyproject_preparer"
14
13
  require "dependabot/python/update_checker"
15
14
  require "dependabot/python/version"
16
15
  require "dependabot/python/requirement"
16
+ require "dependabot/python/helpers"
17
17
  require "dependabot/python/native_helpers"
18
18
  require "dependabot/python/authed_url_builder"
19
19
  require "dependabot/python/name_normaliser"
@@ -156,20 +156,18 @@ module Dependabot
156
156
  return @original_reqs_resolvable if @original_reqs_resolvable
157
157
 
158
158
  SharedHelpers.in_a_temporary_directory do
159
- SharedHelpers.with_git_configured(credentials: credentials) do
160
- write_temporary_dependency_files(update_pyproject: false)
159
+ write_temporary_dependency_files(update_pyproject: false)
161
160
 
162
- run_poetry_update_command
161
+ run_poetry_update_command
163
162
 
164
- @original_reqs_resolvable = true
165
- rescue SharedHelpers::HelperSubprocessFailed => e
166
- raise unless e.message.include?("SolverProblemError") ||
167
- e.message.include?("not found") ||
168
- e.message.include?("version solving failed.")
163
+ @original_reqs_resolvable = true
164
+ rescue SharedHelpers::HelperSubprocessFailed => e
165
+ raise unless e.message.include?("SolverProblemError") ||
166
+ e.message.include?("not found") ||
167
+ e.message.include?("version solving failed.")
169
168
 
170
- msg = clean_error_message(e.message)
171
- raise DependencyFileNotResolvable, msg
172
- end
169
+ msg = clean_error_message(e.message)
170
+ raise DependencyFileNotResolvable, msg
173
171
  end
174
172
  end
175
173
 
@@ -231,7 +229,7 @@ module Dependabot
231
229
  def update_python_requirement(pyproject_content)
232
230
  Python::FileUpdater::PyprojectPreparer.
233
231
  new(pyproject_content: pyproject_content).
234
- update_python_requirement(language_version_manager.python_major_minor)
232
+ update_python_requirement(language_version_manager.python_version)
235
233
  end
236
234
 
237
235
  def freeze_other_dependencies(pyproject_content)
@@ -260,8 +258,6 @@ module Dependabot
260
258
 
261
259
  # If this is a sub-dependency, add the new requirement
262
260
  unless dependency.requirements.find { |r| r[:file] == pyproject.name }
263
- subdep_type = subdependency_type_parser.subdep_type(dependency)
264
-
265
261
  poetry_object[subdep_type] ||= {}
266
262
  poetry_object[subdep_type][dependency.name] = updated_requirement
267
263
  end
@@ -281,6 +277,10 @@ module Dependabot
281
277
  end
282
278
  end
283
279
 
280
+ def subdep_type
281
+ dependency.production? ? "dependencies" : "dev-dependencies"
282
+ end
283
+
284
284
  def python_requirement_parser
285
285
  @python_requirement_parser ||=
286
286
  FileParser::PythonRequirementParser.new(
@@ -288,13 +288,6 @@ module Dependabot
288
288
  )
289
289
  end
290
290
 
291
- def subdependency_type_parser
292
- @subdependency_type_parser ||=
293
- FileParser::PoetrySubdependencyTypeParser.new(
294
- lockfile: lockfile
295
- )
296
- end
297
-
298
291
  def language_version_manager
299
292
  @language_version_manager ||=
300
293
  LanguageVersionManager.new(
@@ -315,24 +308,7 @@ module Dependabot
315
308
  end
316
309
 
317
310
  def run_poetry_command(command, fingerprint: nil)
318
- start = Time.now
319
- command = SharedHelpers.escape_command(command)
320
- stdout, process = Open3.capture2e(command)
321
- time_taken = Time.now - start
322
-
323
- # Raise an error with the output from the shell session if poetry
324
- # returns a non-zero status
325
- return if process.success?
326
-
327
- raise SharedHelpers::HelperSubprocessFailed.new(
328
- message: stdout,
329
- error_context: {
330
- command: command,
331
- fingerprint: fingerprint,
332
- time_taken: time_taken,
333
- process_exit_value: process.to_s
334
- }
335
- )
311
+ Helpers.run_poetry_command(command, fingerprint: fingerprint)
336
312
  end
337
313
 
338
314
  def normalise(name)
@@ -257,7 +257,7 @@ module Dependabot
257
257
  end
258
258
 
259
259
  def library?
260
- return unless updating_pyproject?
260
+ return false unless updating_pyproject?
261
261
 
262
262
  # Hit PyPi and check whether there are details for a library with a
263
263
  # matching name and description
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.227.0
4
+ version: 0.228.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-18 00:00:00.000000000 Z
11
+ date: 2023-08-25 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.227.0
19
+ version: 0.228.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.227.0
26
+ version: 0.228.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: debug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 1.50.0
117
+ version: 1.56.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 1.50.0
124
+ version: 1.56.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rubocop-performance
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -200,7 +200,6 @@ files:
200
200
  - lib/dependabot/python/file_parser/pyproject_files_parser.rb
201
201
  - lib/dependabot/python/file_parser/python_requirement_parser.rb
202
202
  - lib/dependabot/python/file_parser/setup_file_parser.rb
203
- - lib/dependabot/python/file_parser/subdependency_type_parser.rb
204
203
  - lib/dependabot/python/file_updater.rb
205
204
  - lib/dependabot/python/file_updater/pip_compile_file_updater.rb
206
205
  - lib/dependabot/python/file_updater/pipfile_file_updater.rb
@@ -211,6 +210,7 @@ files:
211
210
  - lib/dependabot/python/file_updater/requirement_file_updater.rb
212
211
  - lib/dependabot/python/file_updater/requirement_replacer.rb
213
212
  - lib/dependabot/python/file_updater/setup_file_sanitizer.rb
213
+ - lib/dependabot/python/helpers.rb
214
214
  - lib/dependabot/python/language_version_manager.rb
215
215
  - lib/dependabot/python/metadata_finder.rb
216
216
  - lib/dependabot/python/name_normaliser.rb
@@ -231,7 +231,7 @@ licenses:
231
231
  - Nonstandard
232
232
  metadata:
233
233
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
234
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.227.0
234
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.228.0
235
235
  post_install_message:
236
236
  rdoc_options: []
237
237
  require_paths:
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "toml-rb"
4
- require "dependabot/python/file_parser"
5
- require "dependabot/python/name_normaliser"
6
-
7
- module Dependabot
8
- module Python
9
- class FileParser
10
- class PoetrySubdependencyTypeParser
11
- def initialize(lockfile:)
12
- @lockfile = lockfile
13
- end
14
-
15
- def subdep_type(dep)
16
- category =
17
- TomlRB.parse(lockfile.content).fetch("package", []).
18
- find { |dets| normalise(dets.fetch("name")) == dep.name }.
19
- fetch("category")
20
-
21
- category == "dev" ? "dev-dependencies" : "dependencies"
22
- end
23
-
24
- private
25
-
26
- attr_reader :lockfile
27
-
28
- def normalise(name)
29
- NameNormaliser.normalise(name)
30
- end
31
- end
32
- end
33
- end
34
- end