dependabot-uv 0.394.0 → 0.396.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: f9eee59202ca318e612e23d7303309e498d51999cda642a1660d41390a2bd4a8
4
- data.tar.gz: 3b3bb2ea60f190db5d8c9bd36f1ff01531097788c3755c6638d5a4e8e3ebf923
3
+ metadata.gz: 027ad1367a86b529db5967ecbd9aed18f7ccdceb9d4df8ff8cdfddcaf5ec5d97
4
+ data.tar.gz: 24335d0faa175e847520483ddbfcf8f63e6a40148051a38d83d71542c34656e9
5
5
  SHA512:
6
- metadata.gz: 2f6d9c0f1ea2c05bab8acea5563a4a74c016ab9b8bd77639afe9468a8f7b8cb18d238585b5bdc11b255bf8e8d0af01d7d470c07ab9b83792d8001156bb73a199
7
- data.tar.gz: '09c83e67c0b94adf7ad3f848f17521b57e282ef33db9d4ac0b5991d0ea8135024fc9eb5e78a1515a7f9f4c826f8db3347e25b24ed842ed85681a0b3dd8289e94'
6
+ metadata.gz: 5db0cb74fe436d25c525a42d306c9da0e6708dc176915fa6daf3d57f1d482404cad6ed0a061d1f6ee2b5e7235c57e6963cb6e85defca8be39b8bd4a209af64f3
7
+ data.tar.gz: cf36a1b60e34ef5325b5b9108a098f923d0245f1eca864ab1d83e16be64f31afaf86f7c71fc4867af057c569ce5a0e90be66f98aab732667790aa22d4b83aba0
@@ -7,7 +7,7 @@ plette==2.2.1
7
7
  poetry==2.4.1
8
8
  # TODO: Replace 3p package `tomli` with 3.11's new stdlib `tomllib` once we drop support for Python 3.10.
9
9
  tomli==2.4.1
10
- uv==0.12.5
10
+ uv==0.12.7
11
11
 
12
12
  # Some dependencies will only install if Cython is present
13
13
  Cython==3.3.0
@@ -89,11 +89,17 @@ module Dependabot
89
89
  # undesirable. Leave PDM alone until properly supported
90
90
  return dependencies if using_pdm?
91
91
 
92
+ unresolvable_sources = PyprojectDocument.from_file(pyproject_file)
93
+ .unresolvable_uv_source_names
94
+ .map { |name| normalise(name) }
95
+
92
96
  parse_pep621_pep735_dependencies(pyproject_file).each do |dep|
93
97
  # If a requirement has a `<` or `<=` marker then updating it is
94
98
  # probably blocked. Ignore it.
95
99
  next if dep.markers&.include?("<")
96
100
 
101
+ next if unresolvable_sources.include?(normalise(dep.name))
102
+
97
103
  # In uv no constraint means any version is acceptable
98
104
  requirement_value = dep.requirement == "" ? "*" : dep.requirement
99
105
 
@@ -16,6 +16,7 @@ require "dependabot/uv/name_normaliser"
16
16
  require "dependabot/uv/requirements_file_matcher"
17
17
  require "dependabot/uv/language_version_manager"
18
18
  require "dependabot/uv/package_manager"
19
+ require "dependabot/python/file_parser/pep_dependency"
19
20
  require "toml-rb"
20
21
 
21
22
  module Dependabot
@@ -235,16 +236,16 @@ module Dependabot
235
236
  parsed_requirement_files.each do |dep|
236
237
  next if blocking_marker?(dep)
237
238
 
238
- name = dep["name"]
239
- file = dep["file"]
240
- version = dep["version"]
239
+ name = dep.name
240
+ file = dep.file
241
+ version = dep.version
241
242
  original_file = get_original_file(file)
242
243
 
243
244
  requirements =
244
245
  if original_file && requirements_in_file_matcher.compiled_file?(original_file) then []
245
246
  else
246
247
  [{
247
- requirement: dep["requirement"],
248
+ requirement: dep.requirement,
248
249
  file: Pathname.new(file).cleanpath.to_path,
249
250
  source: nil,
250
251
  groups: group_from_filename(file)
@@ -256,7 +257,7 @@ module Dependabot
256
257
 
257
258
  dependencies <<
258
259
  Dependency.new(
259
- name: normalised_name(name, dep["extras"]),
260
+ name: normalised_name(name, dep.extras),
260
261
  version: version&.include?("*") ? nil : version,
261
262
  requirements: requirements,
262
263
  package_manager: "uv"
@@ -281,35 +282,32 @@ module Dependabot
281
282
  end
282
283
  end
283
284
 
284
- sig { params(dep: T.untyped).returns(T::Boolean) }
285
+ sig { params(dep: Dependabot::Python::FileParser::PepDependency).returns(T::Boolean) }
285
286
  def blocking_marker?(dep)
286
- return false if dep["markers"] == "None"
287
+ marker = dep.markers
288
+ return false if marker.nil? || marker == "None"
287
289
 
288
- marker = dep["markers"]
289
290
  version = python_raw_version
290
291
 
291
292
  if marker.include?("python_version")
292
293
  !marker_satisfied?(marker, version)
293
294
  else
294
- return true if dep["markers"].include?("<")
295
- return false if dep["markers"].include?(">")
296
- return false if dep["requirement"].nil?
295
+ return true if marker.include?("<")
296
+ return false if marker.include?(">")
297
297
 
298
- dep["requirement"].include?("<")
298
+ dep.requirement&.include?("<") || false
299
299
  end
300
300
  end
301
301
 
302
- sig do
303
- params(marker: T.untyped, python_version: T.any(String, Integer, Gem::Version)).returns(T::Boolean)
304
- end
302
+ sig { params(marker: String, python_version: T.any(String, Integer, Gem::Version)).returns(T::Boolean) }
305
303
  def marker_satisfied?(marker, python_version)
306
304
  conditions = marker.split(/\s+(and|or)\s+/)
307
305
 
308
- result = T.let(evaluate_condition?(conditions.shift, python_version), T::Boolean)
306
+ result = T.let(evaluate_condition?(T.must(conditions.shift), python_version), T::Boolean)
309
307
 
310
308
  until conditions.empty?
311
309
  operator = conditions.shift
312
- next_condition = conditions.shift
310
+ next_condition = T.must(conditions.shift)
313
311
  next_result = evaluate_condition?(next_condition, python_version)
314
312
 
315
313
  result = if operator == "and"
@@ -324,12 +322,13 @@ module Dependabot
324
322
 
325
323
  sig do
326
324
  params(
327
- condition: T.untyped,
325
+ condition: String,
328
326
  python_version: T.any(String, Integer, Gem::Version)
329
327
  ).returns(T::Boolean)
330
328
  end
331
329
  def evaluate_condition?(condition, python_version)
332
330
  operator, version = condition.match(/([<>=!]=?)\s*"?([\d.]+)"?/)&.captures
331
+ return false unless version
333
332
 
334
333
  case operator
335
334
  when "<"
@@ -347,17 +346,18 @@ module Dependabot
347
346
  end
348
347
  end
349
348
 
350
- sig { returns(T.untyped) }
349
+ sig { returns(T::Array[Dependabot::Python::FileParser::PepDependency]) }
351
350
  def parsed_requirement_files
352
351
  SharedHelpers.in_a_temporary_directory do
353
352
  write_temporary_dependency_files
354
353
 
355
- requirements = SharedHelpers.run_helper_subprocess(
354
+ result = SharedHelpers.run_helper_subprocess(
356
355
  command: "pyenv exec python3 #{NativeHelpers.python_helper_path}",
357
356
  function: "parse_requirements",
358
357
  args: [Dir.pwd]
359
358
  )
360
359
 
360
+ requirements = Dependabot::Python::FileParser::PepDependency.from_requirements_helper_result(result)
361
361
  check_requirements(requirements)
362
362
  requirements
363
363
  end
@@ -368,12 +368,13 @@ module Dependabot
368
368
  raise DependencyFileNotEvaluatable, e.message
369
369
  end
370
370
 
371
- sig { params(requirements: T.untyped).returns(T.untyped) }
371
+ sig { params(requirements: T::Array[Dependabot::Python::FileParser::PepDependency]).void }
372
372
  def check_requirements(requirements)
373
373
  requirements.each do |dep|
374
- next unless dep["requirement"]
374
+ requirement = dep.requirement
375
+ next unless requirement
375
376
 
376
- Requirement.new(dep["requirement"].split(","))
377
+ Requirement.new(requirement.split(","))
377
378
  rescue Gem::Requirement::BadRequirementError => e
378
379
  raise DependencyFileNotEvaluatable, e.message
379
380
  end
@@ -18,7 +18,7 @@ require "dependabot/uv/authed_url_builder"
18
18
  module Dependabot
19
19
  module Uv
20
20
  class FileUpdater
21
- # rubocop:disable Metrics/ClassLength
21
+ # rubocop:disable-next Metrics/ClassLength
22
22
  class CompileFileUpdater
23
23
  extend T::Sig
24
24
 
@@ -434,12 +434,17 @@ module Dependabot
434
434
  args << index_url if index_url
435
435
 
436
436
  begin
437
+ helper_result = SharedHelpers.run_helper_subprocess(
438
+ command: "pyenv exec python3 #{NativeHelpers.python_helper_path}",
439
+ function: "get_dependency_hash",
440
+ args: args
441
+ )
442
+
443
+ # Skip this index if helper returned nil (can happen with unavailable registries)
444
+ next if helper_result.nil?
445
+
437
446
  native_helper_hashes = T.cast(
438
- SharedHelpers.run_helper_subprocess(
439
- command: "pyenv exec python3 #{NativeHelpers.python_helper_path}",
440
- function: "get_dependency_hash",
441
- args: args
442
- ),
447
+ helper_result,
443
448
  T::Array[T::Hash[String, String]]
444
449
  ).map { |h| "--hash=#{algorithm}:#{h['hash']}" }
445
450
 
@@ -451,6 +456,8 @@ module Dependabot
451
456
  end
452
457
  end
453
458
 
459
+ raise DependencyFileNotResolvable, "Unable to find hashes for package #{name}" if hashes.empty?
460
+
454
461
  hashes
455
462
  end
456
463
 
@@ -665,7 +672,6 @@ module Dependabot
665
672
  dependency_files.select { |f| f.name.end_with?(".txt") }
666
673
  end
667
674
  end
668
- # rubocop:enable Metrics/ClassLength
669
675
  end
670
676
  end
671
677
  end
@@ -18,7 +18,7 @@ require "dependabot/uv/requirement_suffix_helper"
18
18
  module Dependabot
19
19
  module Uv
20
20
  class FileUpdater
21
- # rubocop:disable Metrics/ClassLength
21
+ # rubocop:disable-next Metrics/ClassLength
22
22
  class LockFileUpdater
23
23
  extend T::Sig
24
24
 
@@ -798,7 +798,6 @@ module Dependabot
798
798
  )
799
799
  end
800
800
  end
801
- # rubocop:enable Metrics/ClassLength
802
801
  end
803
802
  end
804
803
  end
@@ -1,4 +1,4 @@
1
- # typed: strict
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "toml-rb"
@@ -13,6 +13,8 @@ module Dependabot
13
13
  class VersionConfigParser
14
14
  extend T::Sig
15
15
 
16
+ ObjectHash = T.type_alias { T::Hash[String, Object] }
17
+
16
18
  class VersionConfig < T::Struct
17
19
  extend T::Sig
18
20
 
@@ -32,7 +34,7 @@ module Dependabot
32
34
  @pyproject_content = pyproject_content
33
35
  @base_path = base_path
34
36
  @repo_root = repo_root
35
- @parsed_pyproject = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
37
+ @parsed_pyproject = T.let(nil, T.nilable(ObjectHash))
36
38
  end
37
39
 
38
40
  sig { returns(VersionConfig) }
@@ -56,15 +58,46 @@ module Dependabot
56
58
  sig { returns(String) }
57
59
  attr_reader :repo_root
58
60
 
59
- sig { returns(T::Hash[String, T.untyped]) }
61
+ sig { returns(ObjectHash) }
60
62
  def parsed_pyproject
61
63
  return @parsed_pyproject unless @parsed_pyproject.nil?
62
64
 
63
- @parsed_pyproject = TomlRB.parse(pyproject_content)
65
+ @parsed_pyproject = object_hash(T.cast(TomlRB.parse(pyproject_content), Object))
64
66
  rescue TomlRB::ParseError, TomlRB::ValueOverwriteError
65
67
  @parsed_pyproject = {}
66
68
  end
67
69
 
70
+ sig { params(value: Object).returns(ObjectHash) }
71
+ def object_hash(value)
72
+ raise TypeError, "Version configuration must be a table" unless value.is_a?(Hash)
73
+
74
+ result = T.let({}, ObjectHash)
75
+ value.each do |raw_key, raw_value|
76
+ key = T.cast(raw_key, Object)
77
+ raise TypeError, "Version configuration keys must be strings" unless key.is_a?(String)
78
+
79
+ result[key] = T.cast(raw_value, Object)
80
+ end
81
+ result
82
+ end
83
+
84
+ sig { params(path: T::Array[String]).returns(Object) }
85
+ def config_value(path)
86
+ value = T.let(parsed_pyproject, Object)
87
+ path.each do |key|
88
+ return nil if value.nil?
89
+
90
+ value = object_hash(value)[key]
91
+ end
92
+ value
93
+ end
94
+
95
+ sig { params(path: T::Array[String]).returns(T.nilable(ObjectHash)) }
96
+ def config_table(path)
97
+ value = config_value(path)
98
+ object_hash(value) if value.is_a?(Hash)
99
+ end
100
+
68
101
  sig { returns(T::Array[String]) }
69
102
  def collect_write_paths
70
103
  paths = []
@@ -82,8 +115,8 @@ module Dependabot
82
115
 
83
116
  sig { returns(T::Array[String]) }
84
117
  def setuptools_scm_write_paths
85
- scm_config = parsed_pyproject.dig("tool", "setuptools_scm")
86
- return [] unless scm_config.is_a?(Hash)
118
+ scm_config = config_table(%w(tool setuptools_scm))
119
+ return [] unless scm_config
87
120
 
88
121
  paths = []
89
122
 
@@ -98,8 +131,8 @@ module Dependabot
98
131
 
99
132
  sig { returns(T::Array[String]) }
100
133
  def hatch_vcs_build_hook_write_paths
101
- vcs_hook = parsed_pyproject.dig("tool", "hatch", "build", "hooks", "vcs")
102
- return [] unless vcs_hook.is_a?(Hash)
134
+ vcs_hook = config_table(%w(tool hatch build hooks vcs))
135
+ return [] unless vcs_hook
103
136
 
104
137
  paths = []
105
138
 
@@ -111,8 +144,8 @@ module Dependabot
111
144
 
112
145
  sig { returns(T::Array[String]) }
113
146
  def hatch_version_source_paths
114
- hatch_version = parsed_pyproject.dig("tool", "hatch", "version")
115
- return [] unless hatch_version.is_a?(Hash)
147
+ hatch_version = config_table(%w(tool hatch version))
148
+ return [] unless hatch_version
116
149
 
117
150
  paths = []
118
151
 
@@ -124,14 +157,14 @@ module Dependabot
124
157
 
125
158
  sig { returns(T.nilable(String)) }
126
159
  def extract_fallback_version
127
- scm_config = parsed_pyproject.dig("tool", "setuptools_scm")
128
- if scm_config.is_a?(Hash)
160
+ scm_config = config_table(%w(tool setuptools_scm))
161
+ if scm_config
129
162
  fallback = scm_config["fallback_version"]
130
163
  return fallback if fallback.is_a?(String)
131
164
  end
132
165
 
133
- raw_options = parsed_pyproject.dig("tool", "hatch", "version", "raw-options")
134
- if raw_options.is_a?(Hash)
166
+ raw_options = config_table(%w(tool hatch version raw-options))
167
+ if raw_options
135
168
  fallback = raw_options["fallback_version"]
136
169
  return fallback if fallback.is_a?(String)
137
170
  end
@@ -141,7 +174,7 @@ module Dependabot
141
174
 
142
175
  sig { returns(T.nilable(String)) }
143
176
  def extract_package_name
144
- name = parsed_pyproject.dig("project", "name")
177
+ name = config_value(%w(project name))
145
178
  return name if name.is_a?(String)
146
179
 
147
180
  nil
@@ -24,7 +24,7 @@ module Dependabot
24
24
  # This class does version resolution for pip-compile. Its approach is:
25
25
  # - Unlock the dependency we're checking in the requirements.in file
26
26
  # - Run `pip-compile` and see what the result is
27
- # rubocop:disable Metrics/ClassLength
27
+ # rubocop:disable-next Metrics/ClassLength
28
28
  class PipCompileVersionResolver
29
29
  extend T::Sig
30
30
 
@@ -595,7 +595,6 @@ module Dependabot
595
595
  dependency_files.select { |f| f.name.end_with?("setup.cfg") }
596
596
  end
597
597
  end
598
- # rubocop:enable Metrics/ClassLength
599
598
  end
600
599
 
601
600
  class PipCompileErrorHandler
@@ -228,11 +228,11 @@ module Dependabot
228
228
  requirement_files.any? { |f| f.end_with?("requirements.txt") }
229
229
  end
230
230
 
231
- sig { override.returns(T.nilable(T::Hash[String, T.untyped])) }
231
+ sig { override.returns(T.nilable(PyprojectDocument::ProjectMetadata)) }
232
232
  def library_details
233
233
  @library_details ||= T.let(
234
- standard_details || build_system_details,
235
- T.nilable(T::Hash[String, T.untyped])
234
+ pyproject_document.project_metadata || pyproject_document.build_system_metadata,
235
+ T.nilable(PyprojectDocument::ProjectMetadata)
236
236
  )
237
237
  end
238
238
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-uv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.394.0
4
+ version: 0.396.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,28 +15,28 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.394.0
18
+ version: 0.396.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.394.0
25
+ version: 0.396.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: dependabot-python
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.394.0
32
+ version: 0.396.0
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 0.394.0
39
+ version: 0.396.0
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: debug
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -192,19 +192,19 @@ dependencies:
192
192
  - !ruby/object:Gem::Version
193
193
  version: '1.1'
194
194
  - !ruby/object:Gem::Dependency
195
- name: turbo_tests
195
+ name: turbo_tests2
196
196
  requirement: !ruby/object:Gem::Requirement
197
197
  requirements:
198
198
  - - "~>"
199
199
  - !ruby/object:Gem::Version
200
- version: 2.2.5
200
+ version: 3.2.7
201
201
  type: :development
202
202
  prerelease: false
203
203
  version_requirements: !ruby/object:Gem::Requirement
204
204
  requirements:
205
205
  - - "~>"
206
206
  - !ruby/object:Gem::Version
207
- version: 2.2.5
207
+ version: 3.2.7
208
208
  - !ruby/object:Gem::Dependency
209
209
  name: vcr
210
210
  requirement: !ruby/object:Gem::Requirement
@@ -301,7 +301,7 @@ licenses:
301
301
  - MIT
302
302
  metadata:
303
303
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
304
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.394.0
304
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.396.0
305
305
  rdoc_options: []
306
306
  require_paths:
307
307
  - lib