dependabot-python 0.227.0 → 0.228.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.
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