dependabot-python 0.213.0 → 0.215.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: 6cb23890c79504e40e7e4962485003c76c07179574ac89b210b6529d15d2c216
4
- data.tar.gz: b96523f9cf991cbffc38fc2831221c43450c74ef560e8e80ff2d2bbf73c889c4
3
+ metadata.gz: bb146c09fb17142425be804da23abdf95e938a9c8e70c8b95697ebdbc55f89c3
4
+ data.tar.gz: d0b61ca9973b582448c78edecb798b500806b6eb5805f7236ae87703255ad953
5
5
  SHA512:
6
- metadata.gz: 5beeac4ec63193ce095e6a5d7223c11e4e9c2ace55b3ef5c94f0011d8cb0c70fc7b364108b68cd68f656a5ed79d712b64eecbb75998714325a0f3b101169592c
7
- data.tar.gz: 17ec5483c750fe4bc35490feebf418a8bd7eaf0eb2d14e2bcfc811e06f94c02f69eca71bafb589cb2d51b8a73155d3d358b97fcc6125a8fb7229b54f06a42fbe
6
+ metadata.gz: e023894b96f723c3cf3d812a959b35f9a1d9de5b33981c2090af0b0ba259376e83f5dc728cd3e06c5f3aceb39c6ce1181e6ed8eb10d8d1d0a9e0e216698a24fa
7
+ data.tar.gz: bfeafe03ba027242f9a1327f1aee036768ea693cffb08e485062879829109f956dcd8b77b7a24c3bde2eb289b50d9b57717216a199e107df221c8a391de8ecea
data/helpers/build CHANGED
@@ -18,4 +18,8 @@ cp -r \
18
18
  "$install_dir"
19
19
 
20
20
  cd "$install_dir"
21
- PYENV_VERSION=3.10.7 pyenv exec pip --disable-pip-version-check install --use-pep517 -r "requirements.txt"
21
+ PYENV_VERSION=3.11.0 pyenv exec pip --disable-pip-version-check install --use-pep517 -r "requirements.txt"
22
+ PYENV_VERSION=3.10.8 pyenv exec pip --disable-pip-version-check install --use-pep517 -r "requirements.txt"
23
+ PYENV_VERSION=3.9.15 pyenv exec pip --disable-pip-version-check install --use-pep517 -r "requirements.txt"
24
+ PYENV_VERSION=3.8.15 pyenv exec pip --disable-pip-version-check install --use-pep517 -r "requirements.txt"
25
+ PYENV_VERSION=3.7.15 pyenv exec pip --disable-pip-version-check install --use-pep517 -r "requirements.txt"
@@ -49,10 +49,17 @@ def parse_pep621_dependencies(pyproject_path):
49
49
 
50
50
  return requirement_packages
51
51
 
52
- dependencies = parse_toml_section_pep621_dependencies(
53
- pyproject_path,
54
- project_toml['dependencies']
55
- )
52
+ dependencies = []
53
+
54
+ if 'dependencies' in project_toml:
55
+ dependencies_toml = project_toml['dependencies']
56
+
57
+ runtime_dependencies = parse_toml_section_pep621_dependencies(
58
+ pyproject_path,
59
+ dependencies_toml
60
+ )
61
+
62
+ dependencies.extend(runtime_dependencies)
56
63
 
57
64
  if 'optional-dependencies' in project_toml:
58
65
  optional_dependencies_toml = project_toml['optional-dependencies']
@@ -1,5 +1,5 @@
1
1
  pip>=21.3.1,<22.4.0 # Range maintains py36 support TODO: Review python 3.6 support in April 2023 (eol ubuntu 18.04)
2
- pip-tools>=6.4.0,<6.9.1 # Range maintains py36 support TODO: Review python 3.6 support in April 2023 (eol ubuntu 18.04)
2
+ pip-tools>=6.4.0,<6.11.1 # Range maintains py36 support TODO: Review python 3.6 support in April 2023 (eol ubuntu 18.04)
3
3
  flake8==5.0.4
4
4
  hashin==0.17.0
5
5
  pipenv==2022.4.8
@@ -126,7 +126,8 @@ module Dependabot
126
126
  end
127
127
 
128
128
  def using_pep621?
129
- !parsed_pyproject.dig("project", "dependencies").nil?
129
+ !parsed_pyproject.dig("project", "dependencies").nil? ||
130
+ !parsed_pyproject.dig("project", "optional-dependencies").nil?
130
131
  end
131
132
 
132
133
  def using_pdm?
@@ -71,15 +71,25 @@ module Dependabot
71
71
  filenames_to_compile.each do |filename|
72
72
  # Shell out to pip-compile, generate a new set of requirements.
73
73
  # This is slow, as pip-compile needs to do installs.
74
+ options = pip_compile_options(filename)
75
+ options_fingerprint = pip_compile_options_fingerprint(options)
76
+
74
77
  name_part = "pyenv exec pip-compile " \
75
- "#{pip_compile_options(filename)} -P " \
78
+ "#{options} -P " \
76
79
  "#{dependency.name}"
80
+ fingerprint_name_part = "pyenv exec pip-compile " \
81
+ "#{options_fingerprint} -P " \
82
+ "<dependency_name>"
83
+
77
84
  version_part = "#{dependency.version} #{filename}"
85
+ fingerprint_version_part = "<dependency_version> <filename>"
86
+
78
87
  # Don't escape pyenv `dep-name==version` syntax
79
88
  run_pip_compile_command(
80
89
  "#{SharedHelpers.escape_command(name_part)}==" \
81
90
  "#{SharedHelpers.escape_command(version_part)}",
82
- allow_unsafe_shell_command: true
91
+ allow_unsafe_shell_command: true,
92
+ fingerprint: "#{fingerprint_name_part}==#{fingerprint_version_part}"
83
93
  )
84
94
  end
85
95
 
@@ -137,7 +147,7 @@ module Dependabot
137
147
  ).updated_dependency_files
138
148
  end
139
149
 
140
- def run_command(cmd, env: python_env, allow_unsafe_shell_command: false)
150
+ def run_command(cmd, env: python_env, allow_unsafe_shell_command: false, fingerprint:)
141
151
  start = Time.now
142
152
  command = if allow_unsafe_shell_command
143
153
  cmd
@@ -149,10 +159,6 @@ module Dependabot
149
159
 
150
160
  return stdout if process.success?
151
161
 
152
- handle_pip_errors(stdout, command, time_taken, process.to_s)
153
- end
154
-
155
- def handle_pip_errors(stdout, command, time_taken, exit_value)
156
162
  if stdout.match?(INCOMPATIBLE_VERSIONS_REGEX)
157
163
  raise DependencyFileNotResolvable, stdout.match(INCOMPATIBLE_VERSIONS_REGEX)
158
164
  end
@@ -161,17 +167,23 @@ module Dependabot
161
167
  message: stdout,
162
168
  error_context: {
163
169
  command: command,
170
+ fingerprint: fingerprint,
164
171
  time_taken: time_taken,
165
- process_exit_value: exit_value
172
+ process_exit_value: process.to_s
166
173
  }
167
174
  )
168
175
  end
169
176
 
170
- def run_pip_compile_command(command, allow_unsafe_shell_command: false)
171
- run_command("pyenv local #{python_version}")
177
+ def run_pip_compile_command(command, allow_unsafe_shell_command: false, fingerprint:)
178
+ run_command(
179
+ "pyenv local #{Helpers.python_major_minor(python_version)}",
180
+ fingerprint: "pyenv local <python_major_minor>"
181
+ )
182
+
172
183
  run_command(
173
184
  command,
174
- allow_unsafe_shell_command: allow_unsafe_shell_command
185
+ allow_unsafe_shell_command: allow_unsafe_shell_command,
186
+ fingerprint: fingerprint
175
187
  )
176
188
  end
177
189
 
@@ -198,7 +210,7 @@ module Dependabot
198
210
  end
199
211
 
200
212
  # Overwrite the .python-version with updated content
201
- File.write(".python-version", python_version)
213
+ File.write(".python-version", Helpers.python_major_minor(python_version))
202
214
 
203
215
  setup_files.each do |file|
204
216
  path = file.name
@@ -391,6 +403,16 @@ module Dependabot
391
403
  current_separator || default_separator
392
404
  end
393
405
 
406
+ def pip_compile_options_fingerprint(options)
407
+ options.sub(
408
+ /--output-file=\S+/, "--output-file=<output_file>"
409
+ ).sub(
410
+ /--index-url=\S+/, "--index-url=<index_url>"
411
+ ).sub(
412
+ /--extra-index-url=\S+/, "--extra-index-url=<extra_index_url>"
413
+ )
414
+ end
415
+
394
416
  def pip_compile_options(filename)
395
417
  options = ["--build-isolation"]
396
418
  options += pip_compile_index_options
@@ -133,6 +133,7 @@ module Dependabot
133
133
  content = freeze_other_dependencies(content)
134
134
  content = freeze_dependencies_being_updated(content)
135
135
  content = add_private_sources(content)
136
+ content = update_python_requirement(content)
136
137
  content
137
138
  end
138
139
 
@@ -142,6 +143,12 @@ module Dependabot
142
143
  freeze_top_level_dependencies_except(dependencies)
143
144
  end
144
145
 
146
+ def update_python_requirement(pipfile_content)
147
+ PipfilePreparer.
148
+ new(pipfile_content: pipfile_content).
149
+ update_python_requirement(Helpers.python_major_minor(python_version))
150
+ end
151
+
145
152
  # rubocop:disable Metrics/PerceivedComplexity
146
153
  def freeze_dependencies_being_updated(pipfile_content)
147
154
  pipfile_object = TomlRB.parse(pipfile_content)
@@ -246,7 +253,7 @@ module Dependabot
246
253
  def run_command(command, env: {})
247
254
  start = Time.now
248
255
  command = SharedHelpers.escape_command(command)
249
- stdout, process = Open3.capture2e(env, command)
256
+ stdout, _, process = Open3.capture3(env, command)
250
257
  time_taken = Time.now - start
251
258
 
252
259
  # Raise an error with the output from the shell session if Pipenv
@@ -264,7 +271,7 @@ module Dependabot
264
271
  end
265
272
 
266
273
  def run_pipenv_command(command, env: pipenv_env_variables)
267
- run_command("pyenv local #{python_version}")
274
+ run_command("pyenv local #{Helpers.python_major_minor(python_version)}")
268
275
  run_command(command, env: env)
269
276
  end
270
277
 
@@ -276,7 +283,7 @@ module Dependabot
276
283
  end
277
284
 
278
285
  # Overwrite the .python-version with updated content
279
- File.write(".python-version", python_version)
286
+ File.write(".python-version", Helpers.python_major_minor(python_version))
280
287
 
281
288
  setup_files.each do |file|
282
289
  path = file.name
@@ -70,10 +70,12 @@ module Dependabot
70
70
  pipfile_object = TomlRB.parse(pipfile_content)
71
71
 
72
72
  pipfile_object["requires"] ||= {}
73
- pipfile_object["requires"].delete("python_full_version")
74
- pipfile_object["requires"].delete("python_version")
75
- pipfile_object["requires"]["python_full_version"] = requirement
76
-
73
+ if pipfile_object.dig("requires", "python_full_version") && pipfile_object.dig("requires", "python_version")
74
+ pipfile_object["requires"].delete("python_full_version")
75
+ elsif pipfile_object.dig("requires", "python_full_version")
76
+ pipfile_object["requires"].delete("python_full_version")
77
+ pipfile_object["requires"]["python_version"] = requirement
78
+ end
77
79
  TomlRB.dump(pipfile_object)
78
80
  end
79
81
 
@@ -106,6 +106,7 @@ module Dependabot
106
106
  content = sanitize(content)
107
107
  content = freeze_other_dependencies(content)
108
108
  content = freeze_dependencies_being_updated(content)
109
+ content = update_python_requirement(content)
109
110
  content
110
111
  end
111
112
  end
@@ -131,6 +132,12 @@ module Dependabot
131
132
  TomlRB.dump(pyproject_object)
132
133
  end
133
134
 
135
+ def update_python_requirement(pyproject_content)
136
+ PyprojectPreparer.
137
+ new(pyproject_content: pyproject_content).
138
+ update_python_requirement(Helpers.python_major_minor(python_version))
139
+ end
140
+
134
141
  def lock_declaration_to_new_version!(poetry_object, dep)
135
142
  Dependabot::Python::FileParser::PyprojectFilesParser::POETRY_DEPENDENCY_TYPES.each do |type|
136
143
  names = poetry_object[type]&.keys || []
@@ -178,7 +185,7 @@ module Dependabot
178
185
  run_poetry_command("pyenv exec poetry config experimental.system-git-client true")
179
186
  end
180
187
 
181
- run_poetry_command(poetry_update_command)
188
+ run_poetry_update_command
182
189
 
183
190
  return File.read("poetry.lock") if File.exist?("poetry.lock")
184
191
 
@@ -189,11 +196,14 @@ module Dependabot
189
196
 
190
197
  # Using `--lock` avoids doing an install.
191
198
  # Using `--no-interaction` avoids asking for passwords.
192
- def poetry_update_command
193
- "pyenv exec poetry update #{dependency.name} --lock --no-interaction"
199
+ def run_poetry_update_command
200
+ run_poetry_command(
201
+ "pyenv exec poetry update #{dependency.name} --lock --no-interaction",
202
+ fingerprint: "pyenv exec poetry update <dependency_name> --lock --no-interaction"
203
+ )
194
204
  end
195
205
 
196
- def run_poetry_command(command)
206
+ def run_poetry_command(command, fingerprint: nil)
197
207
  start = Time.now
198
208
  command = SharedHelpers.escape_command(command)
199
209
  stdout, process = Open3.capture2e(command)
@@ -207,6 +217,7 @@ module Dependabot
207
217
  message: stdout,
208
218
  error_context: {
209
219
  command: command,
220
+ fingerprint: fingerprint,
210
221
  time_taken: time_taken,
211
222
  process_exit_value: process.to_s
212
223
  }
@@ -221,7 +232,7 @@ module Dependabot
221
232
  end
222
233
 
223
234
  # Overwrite the .python-version with updated content
224
- File.write(".python-version", python_version) if python_version
235
+ File.write(".python-version", Helpers.python_major_minor(python_version)) if python_version
225
236
 
226
237
  # Overwrite the pyproject with updated content
227
238
  File.write("pyproject.toml", pyproject_content)
@@ -36,6 +36,17 @@ module Dependabot
36
36
  end
37
37
  end
38
38
 
39
+ def update_python_requirement(requirement)
40
+ pyproject_object = TomlRB.parse(@pyproject_content)
41
+ if (python_specification = pyproject_object.dig("tool", "poetry", "dependencies", "python"))
42
+ python_req = Python::Requirement.new(python_specification)
43
+ unless python_req.satisfied_by?(requirement)
44
+ pyproject_object["tool"]["poetry"]["dependencies"]["python"] = "~#{requirement}"
45
+ end
46
+ end
47
+ TomlRB.dump(pyproject_object)
48
+ end
49
+
39
50
  def sanitize
40
51
  # {{ name }} syntax not allowed
41
52
  pyproject_content.
@@ -72,6 +83,10 @@ module Dependabot
72
83
  }
73
84
  elsif poetry_object[key][dep_name].is_a?(Hash)
74
85
  poetry_object[key][dep_name]["version"] = locked_version
86
+ elsif poetry_object[key][dep_name].is_a?(Array)
87
+ # if it has multiple-constraints, locking to a single version is
88
+ # going to result in a bad lockfile, ignore
89
+ next
75
90
  else
76
91
  poetry_object[key][dep_name] = locked_version
77
92
  end
@@ -1,19 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "dependabot/logger"
4
+ require "dependabot/python/version"
4
5
 
5
6
  module Dependabot
6
7
  module Python
7
8
  module Helpers
8
9
  def self.install_required_python(python_version)
9
10
  # The leading space is important in the version check
10
- return if SharedHelpers.run_shell_command("pyenv versions").include?(" #{python_version}")
11
+ return if SharedHelpers.run_shell_command("pyenv versions").include?(" #{python_major_minor(python_version)}.")
12
+
13
+ if File.exist?("/usr/local/.pyenv/#{python_major_minor(python_version)}.tar.gz")
14
+ SharedHelpers.run_shell_command(
15
+ "tar xzf /usr/local/.pyenv/#{python_major_minor(python_version)}.tar.gz -C /usr/local/.pyenv/"
16
+ )
17
+ return if SharedHelpers.run_shell_command("pyenv versions").
18
+ include?(" #{python_major_minor(python_version)}.")
19
+ end
11
20
 
12
21
  Dependabot.logger.info("Installing required Python #{python_version}.")
22
+ start = Time.now
13
23
  SharedHelpers.run_shell_command("pyenv install -s #{python_version}")
14
24
  SharedHelpers.run_shell_command("pyenv exec pip install --upgrade pip")
15
25
  SharedHelpers.run_shell_command("pyenv exec pip install -r" \
16
26
  "#{NativeHelpers.python_requirements_path}")
27
+ time_taken = Time.now - start
28
+ Dependabot.logger.info("Installing Python #{python_version} took #{time_taken}s.")
29
+ end
30
+
31
+ def self.python_major_minor(python_version)
32
+ python = Python::Version.new(python_version)
33
+ "#{python.segments[0]}.#{python.segments[1]}"
17
34
  end
18
35
  end
19
36
  end
@@ -4,18 +4,22 @@ module Dependabot
4
4
  module Python
5
5
  module PythonVersions
6
6
  PRE_INSTALLED_PYTHON_VERSIONS = %w(
7
- 3.10.7
7
+ 3.11.0
8
8
  ).freeze
9
9
 
10
10
  # Due to an OpenSSL issue we can only install the following versions in
11
11
  # the Dependabot container.
12
+ # NOTE: When adding one version, always doublecheck for additional releases: https://www.python.org/downloads/
13
+ #
14
+ # WARNING: 3.9.3 is purposefully omitted as it was recalled: https://www.python.org/downloads/release/python-393/
12
15
  SUPPORTED_VERSIONS = %w(
13
- 3.10.7 3.10.6 3.10.5 3.10.4 3.10.3 3.10.2 3.10.1 3.10.0
14
- 3.9.14 3.9.13 3.9.12 3.9.11 3.9.10 3.9.9 3.9.8 3.9.7 3.9.6 3.9.5 3.9.4 3.9.2 3.9.1 3.9.0
15
- 3.8.14 3.8.13 3.8.12 3.8.11 3.8.10 3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 3.8.2 3.8.1 3.8.0
16
- 3.7.14 3.7.13 3.7.12 3.7.11 3.7.10 3.7.9 3.7.8 3.7.7 3.7.6 3.7.5 3.7.4 3.7.3 3.7.2 3.7.1 3.7.0
17
- 3.6.15 3.6.14 3.6.13 3.6.12 3.6.11 3.6.10 3.6.9 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3
18
- 3.6.2 3.6.1 3.6.0 3.5.10 3.5.8 3.5.7 3.5.6 3.5.5 3.5.4 3.5.3
16
+ 3.11.0
17
+ 3.10.8 3.10.7 3.10.6 3.10.5 3.10.4 3.10.3 3.10.2 3.10.1 3.10.0
18
+ 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 3.9.10 3.9.9 3.9.8 3.9.7 3.9.6 3.9.5 3.9.4 3.9.2 3.9.1 3.9.0
19
+ 3.8.15 3.8.14 3.8.13 3.8.12 3.8.11 3.8.10 3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 3.8.2 3.8.1 3.8.0
20
+ 3.7.15 3.7.14 3.7.13 3.7.12 3.7.11 3.7.10 3.7.9 3.7.8 3.7.7 3.7.6 3.7.5 3.7.4 3.7.3 3.7.2 3.7.1 3.7.0
21
+ 3.6.15 3.6.14 3.6.13 3.6.12 3.6.11 3.6.10 3.6.9 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.6.0
22
+ 3.5.10 3.5.8 3.5.7 3.5.6 3.5.5 3.5.4 3.5.3
19
23
  ).freeze
20
24
 
21
25
  # This list gets iterated through to find a valid version, so we have
@@ -112,9 +112,9 @@ module Dependabot
112
112
  end
113
113
 
114
114
  def filter_lower_versions(versions_array)
115
- return versions_array unless dependency.version && version_class.correct?(dependency.version)
115
+ return versions_array unless dependency.numeric_version
116
116
 
117
- versions_array.select { |version| version > version_class.new(dependency.version) }
117
+ versions_array.select { |version| version > dependency.numeric_version }
118
118
  end
119
119
 
120
120
  def filter_out_of_range_versions(versions_array)
@@ -76,8 +76,12 @@ module Dependabot
76
76
  filenames_to_compile.each do |filename|
77
77
  # Shell out to pip-compile.
78
78
  # This is slow, as pip-compile needs to do installs.
79
+ options = pip_compile_options(filename)
80
+ options_fingerprint = pip_compile_options_fingerprint(options)
81
+
79
82
  run_pip_compile_command(
80
- "pyenv exec pip-compile -v #{pip_compile_options(filename)} -P #{dependency.name} #{filename}"
83
+ "pyenv exec pip-compile -v #{options} -P #{dependency.name} #{filename}",
84
+ fingerprint: "pyenv exec pip-compile -v #{options_fingerprint} -P <dependency_name> <filename>"
81
85
  )
82
86
 
83
87
  next if dependency.top_level?
@@ -91,7 +95,8 @@ module Dependabot
91
95
  # update_not_possible.
92
96
  write_original_manifest_files
93
97
  run_pip_compile_command(
94
- "pyenv exec pip-compile #{pip_compile_options(filename)} #{filename}"
98
+ "pyenv exec pip-compile #{options} #{filename}",
99
+ fingerprint: "pyenv exec pip-compile #{options_fingerprint} <filename>"
95
100
  )
96
101
  end
97
102
 
@@ -183,8 +188,12 @@ module Dependabot
183
188
  write_temporary_dependency_files(update_requirement: false)
184
189
 
185
190
  filenames_to_compile.each do |filename|
191
+ options = pip_compile_options(filename)
192
+ options_fingerprint = pip_compile_options_fingerprint(options)
193
+
186
194
  run_pip_compile_command(
187
- "pyenv exec pip-compile #{pip_compile_options(filename)} #{filename}"
195
+ "pyenv exec pip-compile #{options} #{filename}",
196
+ fingerprint: "pyenv exec pip-compile #{options_fingerprint} <filename>"
188
197
  )
189
198
  end
190
199
 
@@ -204,7 +213,7 @@ module Dependabot
204
213
  end
205
214
  end
206
215
 
207
- def run_command(command, env: python_env)
216
+ def run_command(command, env: python_env, fingerprint:)
208
217
  start = Time.now
209
218
  command = SharedHelpers.escape_command(command)
210
219
  stdout, process = Open3.capture2e(env, command)
@@ -216,6 +225,7 @@ module Dependabot
216
225
  message: stdout,
217
226
  error_context: {
218
227
  command: command,
228
+ fingerprint: fingerprint,
219
229
  time_taken: time_taken,
220
230
  process_exit_value: process.to_s
221
231
  }
@@ -226,6 +236,16 @@ module Dependabot
226
236
  python_version >= Python::Version.new("3.7")
227
237
  end
228
238
 
239
+ def pip_compile_options_fingerprint(options)
240
+ options.sub(
241
+ /--output-file=\S+/, "--output-file=<output_file>"
242
+ ).sub(
243
+ /--index-url=\S+/, "--index-url=<index_url>"
244
+ ).sub(
245
+ /--extra-index-url=\S+/, "--extra-index-url=<extra_index_url>"
246
+ )
247
+ end
248
+
229
249
  def pip_compile_options(filename)
230
250
  options = @build_isolation ? ["--build-isolation"] : ["--no-build-isolation"]
231
251
  options += pip_compile_index_options
@@ -253,9 +273,13 @@ module Dependabot
253
273
  end
254
274
  end
255
275
 
256
- def run_pip_compile_command(command)
257
- run_command("pyenv local #{python_version}")
258
- run_command(command)
276
+ def run_pip_compile_command(command, fingerprint:)
277
+ run_command(
278
+ "pyenv local #{Helpers.python_major_minor(python_version)}",
279
+ fingerprint: "pyenv local <python_major_minor>"
280
+ )
281
+
282
+ run_command(command, fingerprint: fingerprint)
259
283
  end
260
284
 
261
285
  def python_env
@@ -298,7 +322,7 @@ module Dependabot
298
322
  end
299
323
 
300
324
  # Overwrite the .python-version with updated content
301
- File.write(".python-version", python_version)
325
+ File.write(".python-version", Helpers.python_major_minor(python_version))
302
326
 
303
327
  setup_files.each do |file|
304
328
  path = file.name
@@ -290,7 +290,7 @@ module Dependabot
290
290
  end
291
291
 
292
292
  # Overwrite the .python-version with updated content
293
- File.write(".python-version", python_version)
293
+ File.write(".python-version", Helpers.python_major_minor(python_version))
294
294
 
295
295
  setup_files.each do |file|
296
296
  path = file.name
@@ -341,6 +341,7 @@ module Dependabot
341
341
  content = freeze_other_dependencies(content)
342
342
  content = set_target_dependency_req(content, updated_requirement)
343
343
  content = add_private_sources(content)
344
+ content = update_python_requirement(content)
344
345
  content
345
346
  end
346
347
 
@@ -350,6 +351,12 @@ module Dependabot
350
351
  freeze_top_level_dependencies_except([dependency])
351
352
  end
352
353
 
354
+ def update_python_requirement(pipfile_content)
355
+ Python::FileUpdater::PipfilePreparer.
356
+ new(pipfile_content: pipfile_content).
357
+ update_python_requirement(Helpers.python_major_minor(python_version))
358
+ end
359
+
353
360
  # rubocop:disable Metrics/PerceivedComplexity
354
361
  def set_target_dependency_req(pipfile_content, updated_requirement)
355
362
  return pipfile_content unless updated_requirement
@@ -461,7 +468,7 @@ module Dependabot
461
468
  end
462
469
 
463
470
  def run_pipenv_command(command, env: pipenv_env_variables)
464
- run_command("pyenv local #{python_version}")
471
+ run_command("pyenv local #{Helpers.python_major_minor(python_version)}")
465
472
  run_command(command, env: env)
466
473
  end
467
474
 
@@ -100,7 +100,7 @@ module Dependabot
100
100
  end
101
101
 
102
102
  # Shell out to Poetry, which handles everything for us.
103
- run_poetry_command(poetry_update_command)
103
+ run_poetry_update_command
104
104
 
105
105
  updated_lockfile =
106
106
  if File.exist?("poetry.lock") then File.read("poetry.lock")
@@ -163,8 +163,11 @@ module Dependabot
163
163
 
164
164
  # Using `--lock` avoids doing an install.
165
165
  # Using `--no-interaction` avoids asking for passwords.
166
- def poetry_update_command
167
- "pyenv exec poetry update #{dependency.name} --lock --no-interaction"
166
+ def run_poetry_update_command
167
+ run_poetry_command(
168
+ "pyenv exec poetry update #{dependency.name} --lock --no-interaction",
169
+ fingerprint: "pyenv exec poetry update <dependency_name> --lock --no-interaction"
170
+ )
168
171
  end
169
172
 
170
173
  def check_original_requirements_resolvable
@@ -174,7 +177,7 @@ module Dependabot
174
177
  SharedHelpers.with_git_configured(credentials: credentials) do
175
178
  write_temporary_dependency_files(update_pyproject: false)
176
179
 
177
- run_poetry_command(poetry_update_command)
180
+ run_poetry_update_command
178
181
 
179
182
  @original_reqs_resolvable = true
180
183
  rescue SharedHelpers::HelperSubprocessFailed => e
@@ -202,7 +205,7 @@ module Dependabot
202
205
  end
203
206
 
204
207
  # Overwrite the .python-version with updated content
205
- File.write(".python-version", python_version) if python_version
208
+ File.write(".python-version", Helpers.python_major_minor(python_version)) if python_version
206
209
 
207
210
  # Overwrite the pyproject with updated content
208
211
  if update_pyproject
@@ -331,7 +334,7 @@ module Dependabot
331
334
  poetry_lock || pyproject_lock
332
335
  end
333
336
 
334
- def run_poetry_command(command)
337
+ def run_poetry_command(command, fingerprint: nil)
335
338
  start = Time.now
336
339
  command = SharedHelpers.escape_command(command)
337
340
  stdout, process = Open3.capture2e(command)
@@ -345,6 +348,7 @@ module Dependabot
345
348
  message: stdout,
346
349
  error_context: {
347
350
  command: command,
351
+ fingerprint: fingerprint,
348
352
  time_taken: time_taken,
349
353
  process_exit_value: process.to_s
350
354
  }
@@ -292,7 +292,7 @@ module Dependabot
292
292
 
293
293
  pypi_info = JSON.parse(index_response.body)["info"] || {}
294
294
  pypi_info["summary"] == library_details["description"]
295
- rescue Excon::Error::Timeout
295
+ rescue Excon::Error::Timeout, Excon::Error::Socket
296
296
  false
297
297
  rescue URI::InvalidURIError
298
298
  false
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.213.0
4
+ version: 0.215.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-31 00:00:00.000000000 Z
11
+ date: 2022-12-07 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.213.0
19
+ version: 0.215.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.213.0
26
+ version: 0.215.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: debug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 3.13.0
61
+ version: 4.0.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 3.13.0
68
+ version: 4.0.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 1.37.1
117
+ version: 1.39.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.37.1
124
+ version: 1.39.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rubocop-performance
127
127
  requirement: !ruby/object:Gem::Requirement