dependabot-python 0.110.13 → 0.110.14

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: 43e205d891e9f373d47ed1aed1ed73e2538770edd93fd20dab742b8a99dfe33b
4
- data.tar.gz: dd989a95c73a113d6567a7d61a3e2351e642ed87eef9669dee5b15541581fcee
3
+ metadata.gz: ce7ac9110e4d9fad6510995f9938ccfac0ac5ce62bb7b56b6bd5be4ba3b5dc2a
4
+ data.tar.gz: f0205fc6e19195f880333699486db230111912b3c79dfbde3fd02eb82b91df61
5
5
  SHA512:
6
- metadata.gz: b88ad7f77598d73adb49bfd706313796e4cefe3849ea0d33b982069284f0235f740764b6e2b09ef27ab926ba66a39cb1e011fe1193f03f6f3483ffbb99e23e94
7
- data.tar.gz: '0286a4185bdad37ddc9123b87aebbd745cb405d25048632d7b5af523566b40c88db5ba229b8725a9d8a3cbf7c8030cb83e4cc7b75984d6353293cbc7bfc0a12e'
6
+ metadata.gz: a51dbc2c9bf9baec3d0e7b0081a90d3022e5f5a55a80e4489407a73fdaab0518e4ab15fc5bda18a95bc1b73e68c6d255b8214ccff06481506a312b56a2874f1e
7
+ data.tar.gz: a37f6ba59bd5009201c3b4242c7a1f6244bcc35429c9764a291b6f392538c1d508e62bbb89ccc1ba74fe47c1ffa5eaa835c1325d086255fdf505a1ccd484babd
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "toml-rb"
4
+ require "open3"
5
+ require "dependabot/errors"
6
+ require "dependabot/shared_helpers"
7
+ require "dependabot/python/file_parser"
8
+ require "dependabot/python/requirement"
9
+
10
+ module Dependabot
11
+ module Python
12
+ class FileParser
13
+ class PythonRequirementParser
14
+ attr_reader :dependency_files
15
+
16
+ def initialize(dependency_files:)
17
+ @dependency_files = dependency_files
18
+ end
19
+
20
+ # TODO: Parse setup.py and setup.cfg to get python requirement
21
+ def user_specified_requirement
22
+ pipfile_python_requirement ||
23
+ pyproject_python_requirement ||
24
+ python_version_file_version ||
25
+ runtime_file_python_version
26
+ end
27
+
28
+ # TODO: Add better Python version detection using dependency versions
29
+ # (e.g., Django 2.x implies Python 3)
30
+ def imputed_requirements
31
+ requirement_files.flat_map do |file|
32
+ file.content.lines.
33
+ select { |l| l.include?(";") && l.include?("python") }.
34
+ map { |l| l.match(/python_version(?<req>.*?["'].*?['"])/) }.
35
+ compact.
36
+ map { |re| re.named_captures.fetch("req").gsub(/['"]/, "") }.
37
+ select do |r|
38
+ requirement_class.new(r)
39
+ true
40
+ rescue Gem::Requirement::BadRequirementError
41
+ false
42
+ end
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def pipfile_python_requirement
49
+ return unless pipfile
50
+
51
+ parsed_pipfile = TomlRB.parse(pipfile.content)
52
+ requirement =
53
+ parsed_pipfile.dig("requires", "python_full_version") ||
54
+ parsed_pipfile.dig("requires", "python_version")
55
+ return unless requirement&.match?(/^\d/)
56
+
57
+ requirement
58
+ end
59
+
60
+ def pyproject_python_requirement
61
+ return unless pyproject
62
+
63
+ pyproject_object = TomlRB.parse(pyproject.content)
64
+ poetry_object = pyproject_object.dig("tool", "poetry")
65
+
66
+ poetry_object&.dig("dependencies", "python") ||
67
+ poetry_object&.dig("dev-dependencies", "python")
68
+ end
69
+
70
+ def python_version_file_version
71
+ return unless python_version_file
72
+
73
+ file_version = python_version_file.content.strip
74
+ return if file_version&.empty?
75
+ return unless pyenv_versions.include?("#{file_version}\n")
76
+
77
+ file_version
78
+ end
79
+
80
+ def runtime_file_python_version
81
+ return unless runtime_file
82
+
83
+ file_version = runtime_file.content.
84
+ match(/(?<=python-).*/)&.to_s&.strip
85
+ return if file_version&.empty?
86
+ return unless pyenv_versions.include?("#{file_version}\n")
87
+
88
+ file_version
89
+ end
90
+
91
+ def pipenv_python_requirement
92
+ pipfile_lock_python_version || pipfile_python_requirement
93
+ end
94
+
95
+ def pipfile_lock_python_version
96
+ return unless pipfile_lock
97
+
98
+ JSON.parse(pipfile_lock.content).dig(
99
+ "_meta",
100
+ "host-environment-markers",
101
+ "python_full_version"
102
+ )
103
+ end
104
+
105
+ def pyenv_versions
106
+ @pyenv_versions ||= run_command("pyenv install --list")
107
+ end
108
+
109
+ def run_command(command, env: {})
110
+ start = Time.now
111
+ command = SharedHelpers.escape_command(command)
112
+ stdout, process = Open3.capture2e(env, command)
113
+ time_taken = Time.now - start
114
+
115
+ return stdout if process.success?
116
+
117
+ raise SharedHelpers::HelperSubprocessFailed.new(
118
+ message: stdout,
119
+ error_context: {
120
+ command: command,
121
+ time_taken: time_taken,
122
+ process_exit_value: process.to_s
123
+ }
124
+ )
125
+ end
126
+
127
+ def requirement_class
128
+ Dependabot::Python::Requirement
129
+ end
130
+
131
+ def pipfile
132
+ dependency_files.find { |f| f.name == "Pipfile" }
133
+ end
134
+
135
+ def pipfile_lock
136
+ dependency_files.find { |f| f.name == "Pipfile.lock" }
137
+ end
138
+
139
+ def pyproject
140
+ dependency_files.find { |f| f.name == "pyproject.toml" }
141
+ end
142
+
143
+ def setup_files
144
+ dependency_files.select { |f| f.name.end_with?("setup.py") }
145
+ end
146
+
147
+ def setup_cfg_files
148
+ dependency_files.select { |f| f.name.end_with?("setup.cfg") }
149
+ end
150
+
151
+ def python_version_file
152
+ dependency_files.find { |f| f.name == ".python-version" }
153
+ end
154
+
155
+ def runtime_file
156
+ dependency_files.find { |f| f.name.end_with?("runtime.txt") }
157
+ end
158
+
159
+ def requirement_files
160
+ dependency_files.select { |f| f.name.end_with?(".txt") }
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -3,6 +3,7 @@
3
3
  require "open3"
4
4
  require "dependabot/python/requirement_parser"
5
5
  require "dependabot/python/file_fetcher"
6
+ require "dependabot/python/file_parser/python_requirement_parser"
6
7
  require "dependabot/python/file_updater"
7
8
  require "dependabot/shared_helpers"
8
9
  require "dependabot/python/native_helpers"
@@ -524,60 +525,42 @@ module Dependabot
524
525
  end
525
526
 
526
527
  def python_version
527
- # TODO: Add better Python version detection using dependency versions
528
- # (e.g., Django 2.x implies Python 3)
529
528
  @python_version ||=
530
529
  user_specified_python_version ||
531
- python_version_from_compiled_requirements ||
530
+ python_version_matching_imputed_requirements ||
532
531
  PythonVersions::PRE_INSTALLED_PYTHON_VERSIONS.first
533
532
  end
534
533
 
535
534
  def user_specified_python_version
536
- file_version = python_version_file&.content&.strip
537
- file_version ||= runtime_file_python_version
535
+ return unless python_requirement_parser.user_specified_requirement
538
536
 
539
- return unless file_version
540
- return unless pyenv_versions.include?("#{file_version}\n")
541
-
542
- file_version
537
+ user_specified_requirement =
538
+ Dependabot::Python::Requirement.new(
539
+ python_requirement_parser.user_specified_requirement
540
+ )
541
+ python_version_matching([user_specified_requirement])
543
542
  end
544
543
 
545
- def runtime_file_python_version
546
- return unless runtime_file
547
-
548
- runtime_file.content.match(/(?<=python-).*/)&.to_s&.strip
544
+ def python_version_matching_imputed_requirements
545
+ compiled_file_python_requirement_markers =
546
+ python_requirement_parser.imputed_requirements.map do |r|
547
+ Dependabot::Python::Requirement.new(r)
548
+ end
549
+ python_version_matching(compiled_file_python_requirement_markers)
549
550
  end
550
551
 
551
- def python_version_from_compiled_requirements
552
+ def python_version_matching(requirements)
552
553
  PythonVersions::SUPPORTED_VERSIONS_TO_ITERATE.find do |version_string|
553
554
  version = Python::Version.new(version_string)
554
- compiled_file_python_requirement_markers.all? do |req|
555
- req.satisfied_by?(version)
556
- end
555
+ requirements.all? { |req| req.satisfied_by?(version) }
557
556
  end
558
557
  end
559
558
 
560
- def compiled_file_python_requirement_markers
561
- @python_requirement_strings ||=
562
- compiled_files.flat_map do |file|
563
- file.content.lines.
564
- select { |l| l.include?(";") && l.include?("python") }.
565
- map { |l| l.match(/python_version(?<req>.*?["'].*?['"])/) }.
566
- compact.
567
- map { |re| re.named_captures.fetch("req").gsub(/['"]/, "") }.
568
- select do |r|
569
- requirement_class.new(r)
570
- true
571
- rescue Gem::Requirement::BadRequirementError
572
- false
573
- end
574
- end
575
-
576
- @python_requirement_strings.map { |r| requirement_class.new(r) }
577
- end
578
-
579
- def pyenv_versions
580
- @pyenv_versions ||= run_command("pyenv install --list")
559
+ def python_requirement_parser
560
+ @python_requirement_parser ||=
561
+ FileParser::PythonRequirementParser.new(
562
+ dependency_files: dependency_files
563
+ )
581
564
  end
582
565
 
583
566
  def pre_installed_python?(version)
@@ -599,18 +582,6 @@ module Dependabot
599
582
  def setup_cfg_files
600
583
  dependency_files.select { |f| f.name.end_with?("setup.cfg") }
601
584
  end
602
-
603
- def python_version_file
604
- dependency_files.find { |f| f.name == ".python-version" }
605
- end
606
-
607
- def runtime_file
608
- dependency_files.find { |f| f.name.end_with?("runtime.txt") }
609
- end
610
-
611
- def requirement_class
612
- Python::Requirement
613
- end
614
585
  end
615
586
  # rubocop:enable Metrics/ClassLength
616
587
  end
@@ -3,6 +3,7 @@
3
3
  require "toml-rb"
4
4
  require "open3"
5
5
  require "dependabot/python/requirement_parser"
6
+ require "dependabot/python/file_parser/python_requirement_parser"
6
7
  require "dependabot/python/file_updater"
7
8
  require "dependabot/shared_helpers"
8
9
  require "dependabot/python/native_helpers"
@@ -385,37 +386,14 @@ module Dependabot
385
386
  end
386
387
 
387
388
  def user_specified_python_requirement
388
- if pipfile_python_requirement&.match?(/^\d/)
389
- return pipfile_python_requirement
390
- end
391
-
392
- python_version_file_version || runtime_file_python_version
393
- end
394
-
395
- def python_version_file_version
396
- file_version = python_version_file&.content&.strip
397
-
398
- return unless file_version
399
- return unless pyenv_versions.include?("#{file_version}\n")
400
-
401
- file_version
402
- end
403
-
404
- def runtime_file_python_version
405
- return unless runtime_file
406
-
407
- runtime_file.content.match(/(?<=python-).*/)&.to_s&.strip
389
+ python_requirement_parser.user_specified_requirement
408
390
  end
409
391
 
410
- def pyenv_versions
411
- @pyenv_versions ||= run_command("pyenv install --list")
412
- end
413
-
414
- def pipfile_python_requirement
415
- parsed_pipfile = TomlRB.parse(pipfile.content)
416
-
417
- parsed_pipfile.dig("requires", "python_full_version") ||
418
- parsed_pipfile.dig("requires", "python_version")
392
+ def python_requirement_parser
393
+ @python_requirement_parser ||=
394
+ FileParser::PythonRequirementParser.new(
395
+ dependency_files: dependency_files
396
+ )
419
397
  end
420
398
 
421
399
  def setup_cfg(file)
@@ -470,14 +448,6 @@ module Dependabot
470
448
  dependency_files.select { |f| f.name.end_with?(".txt") }
471
449
  end
472
450
 
473
- def python_version_file
474
- dependency_files.find { |f| f.name == ".python-version" }
475
- end
476
-
477
- def runtime_file
478
- dependency_files.find { |f| f.name.end_with?("runtime.txt") }
479
- end
480
-
481
451
  def pipenv_env_variables
482
452
  {
483
453
  "PIPENV_YES" => "true", # Install new Python ver if needed
@@ -6,10 +6,10 @@ require "dependabot/shared_helpers"
6
6
  require "dependabot/python/version"
7
7
  require "dependabot/python/requirement"
8
8
  require "dependabot/python/python_versions"
9
+ require "dependabot/python/file_parser/python_requirement_parser"
9
10
  require "dependabot/python/file_updater"
10
11
  require "dependabot/python/native_helpers"
11
12
 
12
- # rubocop:disable Metrics/ClassLength
13
13
  module Dependabot
14
14
  module Python
15
15
  class FileUpdater
@@ -232,17 +232,7 @@ module Dependabot
232
232
  end
233
233
 
234
234
  def python_version
235
- pyproject_object = TomlRB.parse(prepared_pyproject)
236
- poetry_object = pyproject_object.dig("tool", "poetry")
237
-
238
- requirement =
239
- poetry_object&.dig("dependencies", "python") ||
240
- poetry_object&.dig("dev-dependencies", "python")
241
-
242
- unless requirement
243
- return python_version_file_version || runtime_file_python_version
244
- end
245
-
235
+ requirement = user_specified_python_requirement
246
236
  requirements = Python::Requirement.requirements_array(requirement)
247
237
 
248
238
  PythonVersions::SUPPORTED_VERSIONS_TO_ITERATE.find do |version|
@@ -252,23 +242,15 @@ module Dependabot
252
242
  end
253
243
  end
254
244
 
255
- def python_version_file_version
256
- file_version = python_version_file&.content&.strip
257
-
258
- return unless file_version
259
- return unless pyenv_versions.include?("#{file_version}\n")
260
-
261
- file_version
245
+ def user_specified_python_requirement
246
+ python_requirement_parser.user_specified_requirement
262
247
  end
263
248
 
264
- def runtime_file_python_version
265
- return unless runtime_file
266
-
267
- runtime_file.content.match(/(?<=python-).*/)&.to_s&.strip
268
- end
269
-
270
- def pyenv_versions
271
- @pyenv_versions ||= run_poetry_command("pyenv install --list")
249
+ def python_requirement_parser
250
+ @python_requirement_parser ||=
251
+ FileParser::PythonRequirementParser.new(
252
+ dependency_files: dependency_files
253
+ )
272
254
  end
273
255
 
274
256
  def pre_installed_python?(version)
@@ -335,16 +317,7 @@ module Dependabot
335
317
  def poetry_lock
336
318
  dependency_files.find { |f| f.name == "poetry.lock" }
337
319
  end
338
-
339
- def python_version_file
340
- dependency_files.find { |f| f.name == ".python-version" }
341
- end
342
-
343
- def runtime_file
344
- dependency_files.find { |f| f.name.end_with?("runtime.txt") }
345
- end
346
320
  end
347
321
  end
348
322
  end
349
323
  end
350
- # rubocop:enable Metrics/ClassLength
@@ -4,6 +4,7 @@ require "open3"
4
4
  require "dependabot/python/requirement_parser"
5
5
  require "dependabot/python/file_fetcher"
6
6
  require "dependabot/python/file_parser"
7
+ require "dependabot/python/file_parser/python_requirement_parser"
7
8
  require "dependabot/python/update_checker"
8
9
  require "dependabot/python/file_updater/requirement_replacer"
9
10
  require "dependabot/python/file_updater/setup_file_sanitizer"
@@ -440,60 +441,42 @@ module Dependabot
440
441
  end
441
442
 
442
443
  def python_version
443
- # TODO: Add better Python version detection using dependency versions
444
- # (e.g., Django 2.x implies Python 3)
445
444
  @python_version ||=
446
445
  user_specified_python_version ||
447
- python_version_matching_requirements ||
446
+ python_version_matching_imputed_requirements ||
448
447
  PythonVersions::PRE_INSTALLED_PYTHON_VERSIONS.first
449
448
  end
450
449
 
451
450
  def user_specified_python_version
452
- file_version = python_version_file&.content&.strip
453
- file_version ||= runtime_file_python_version
451
+ return unless python_requirement_parser.user_specified_requirement
454
452
 
455
- return unless file_version
456
- return unless pyenv_versions.include?("#{file_version}\n")
457
-
458
- file_version
453
+ user_specified_requirement =
454
+ Dependabot::Python::Requirement.new(
455
+ python_requirement_parser.user_specified_requirement
456
+ )
457
+ python_version_matching([user_specified_requirement])
459
458
  end
460
459
 
461
- def runtime_file_python_version
462
- return unless runtime_file
463
-
464
- runtime_file.content.match(/(?<=python-).*/)&.to_s&.strip
460
+ def python_version_matching_imputed_requirements
461
+ compiled_file_python_requirement_markers =
462
+ python_requirement_parser.imputed_requirements.map do |r|
463
+ Dependabot::Python::Requirement.new(r)
464
+ end
465
+ python_version_matching(compiled_file_python_requirement_markers)
465
466
  end
466
467
 
467
- def python_version_matching_requirements
468
+ def python_version_matching(requirements)
468
469
  PythonVersions::SUPPORTED_VERSIONS_TO_ITERATE.find do |version_string|
469
470
  version = Python::Version.new(version_string)
470
- compiled_file_python_requirement_markers.all? do |req|
471
- req.satisfied_by?(version)
472
- end
471
+ requirements.all? { |req| req.satisfied_by?(version) }
473
472
  end
474
473
  end
475
474
 
476
- def compiled_file_python_requirement_markers
477
- @python_requirement_strings ||=
478
- compiled_files.flat_map do |file|
479
- file.content.lines.
480
- select { |l| l.include?(";") && l.include?("python") }.
481
- map { |l| l.match(/python_version(?<req>.*?["'].*?['"])/) }.
482
- compact.
483
- map { |re| re.named_captures.fetch("req").gsub(/['"]/, "") }.
484
- select do |r|
485
- requirement_class.new(r)
486
- true
487
- rescue Gem::Requirement::BadRequirementError
488
- false
489
- end
490
- end
491
-
492
- @python_requirement_strings.map { |r| requirement_class.new(r) }
493
- end
494
-
495
- def pyenv_versions
496
- @pyenv_versions ||= run_command("pyenv install --list")
475
+ def python_requirement_parser
476
+ @python_requirement_parser ||=
477
+ FileParser::PythonRequirementParser.new(
478
+ dependency_files: dependency_files
479
+ )
497
480
  end
498
481
 
499
482
  def pre_installed_python?(version)
@@ -515,18 +498,6 @@ module Dependabot
515
498
  def setup_cfg_files
516
499
  dependency_files.select { |f| f.name.end_with?("setup.cfg") }
517
500
  end
518
-
519
- def python_version_file
520
- dependency_files.find { |f| f.name == ".python-version" }
521
- end
522
-
523
- def runtime_file
524
- dependency_files.find { |f| f.name.end_with?("runtime.txt") }
525
- end
526
-
527
- def requirement_class
528
- Python::Requirement
529
- end
530
501
  end
531
502
  # rubocop:enable Metrics/ClassLength
532
503
  end
@@ -6,13 +6,13 @@ require "open3"
6
6
  require "dependabot/errors"
7
7
  require "dependabot/shared_helpers"
8
8
  require "dependabot/python/file_parser"
9
+ require "dependabot/python/file_parser/python_requirement_parser"
9
10
  require "dependabot/python/file_updater/pipfile_preparer"
10
11
  require "dependabot/python/file_updater/setup_file_sanitizer"
11
12
  require "dependabot/python/update_checker"
12
13
  require "dependabot/python/python_versions"
13
14
  require "dependabot/python/native_helpers"
14
15
  require "dependabot/python/version"
15
- require "dependabot/python/authed_url_builder"
16
16
 
17
17
  # rubocop:disable Metrics/ClassLength
18
18
  module Dependabot
@@ -407,37 +407,14 @@ module Dependabot
407
407
  end
408
408
 
409
409
  def user_specified_python_requirement
410
- if pipfile_python_requirement&.match?(/^\d/)
411
- return pipfile_python_requirement
412
- end
413
-
414
- python_version_file_version || runtime_file_python_version
415
- end
416
-
417
- def python_version_file_version
418
- file_version = python_version_file&.content&.strip
419
-
420
- return unless file_version
421
- return unless pyenv_versions.include?("#{file_version}\n")
422
-
423
- file_version
410
+ python_requirement_parser.user_specified_requirement
424
411
  end
425
412
 
426
- def runtime_file_python_version
427
- return unless runtime_file
428
-
429
- runtime_file.content.match(/(?<=python-).*/)&.to_s&.strip
430
- end
431
-
432
- def pyenv_versions
433
- @pyenv_versions ||= run_command("pyenv install --list")
434
- end
435
-
436
- def pipfile_python_requirement
437
- parsed_pipfile = TomlRB.parse(pipfile.content)
438
-
439
- parsed_pipfile.dig("requires", "python_full_version") ||
440
- parsed_pipfile.dig("requires", "python_version")
413
+ def python_requirement_parser
414
+ @python_requirement_parser ||=
415
+ FileParser::PythonRequirementParser.new(
416
+ dependency_files: dependency_files
417
+ )
441
418
  end
442
419
 
443
420
  def run_command(command, env: {})
@@ -491,16 +468,6 @@ module Dependabot
491
468
  error_message.include?('Command "python setup.py egg_info" failed')
492
469
  end
493
470
 
494
- def config_variable_sources
495
- @config_variable_sources ||=
496
- credentials.
497
- select { |cred| cred["type"] == "python_index" }.
498
- map do |h|
499
- url = AuthedUrlBuilder.authed_url(credential: h)
500
- { "url" => url.gsub(%r{/*$}, "") + "/" }
501
- end
502
- end
503
-
504
471
  def pipenv_env_variables
505
472
  {
506
473
  "PIPENV_YES" => "true", # Install new Python ver if needed
@@ -531,14 +498,6 @@ module Dependabot
531
498
  def setup_cfg_files
532
499
  dependency_files.select { |f| f.name.end_with?("setup.cfg") }
533
500
  end
534
-
535
- def python_version_file
536
- dependency_files.find { |f| f.name == ".python-version" }
537
- end
538
-
539
- def runtime_file
540
- dependency_files.find { |f| f.name.end_with?("runtime.txt") }
541
- end
542
501
  end
543
502
  end
544
503
  end
@@ -6,6 +6,7 @@ require "open3"
6
6
  require "dependabot/errors"
7
7
  require "dependabot/shared_helpers"
8
8
  require "dependabot/python/file_parser"
9
+ require "dependabot/python/file_parser/python_requirement_parser"
9
10
  require "dependabot/python/file_updater/pyproject_preparer"
10
11
  require "dependabot/python/update_checker"
11
12
  require "dependabot/python/version"
@@ -14,7 +15,6 @@ require "dependabot/python/native_helpers"
14
15
  require "dependabot/python/python_versions"
15
16
  require "dependabot/python/authed_url_builder"
16
17
 
17
- # rubocop:disable Metrics/ClassLength
18
18
  module Dependabot
19
19
  module Python
20
20
  class UpdateChecker
@@ -189,19 +189,8 @@ module Dependabot
189
189
  end
190
190
 
191
191
  def python_version
192
- pyproject_object = TomlRB.parse(pyproject.content)
193
- poetry_object = pyproject_object.dig("tool", "poetry")
194
-
195
- requirement =
196
- poetry_object&.dig("dependencies", "python") ||
197
- poetry_object&.dig("dev-dependencies", "python")
198
-
199
- unless requirement
200
- return python_version_file_version || runtime_file_python_version
201
- end
202
-
203
- requirements =
204
- Python::Requirement.requirements_array(requirement)
192
+ requirement = user_specified_python_requirement
193
+ requirements = Python::Requirement.requirements_array(requirement)
205
194
 
206
195
  version = PythonVersions::SUPPORTED_VERSIONS_TO_ITERATE.find do |v|
207
196
  requirements.any? { |r| r.satisfied_by?(Python::Version.new(v)) }
@@ -215,23 +204,15 @@ module Dependabot
215
204
  raise DependencyFileNotResolvable, msg
216
205
  end
217
206
 
218
- def python_version_file_version
219
- file_version = python_version_file&.content&.strip
220
-
221
- return unless file_version
222
- return unless pyenv_versions.include?("#{file_version}\n")
223
-
224
- file_version
207
+ def user_specified_python_requirement
208
+ python_requirement_parser.user_specified_requirement
225
209
  end
226
210
 
227
- def runtime_file_python_version
228
- return unless runtime_file
229
-
230
- runtime_file.content.match(/(?<=python-).*/)&.to_s&.strip
231
- end
232
-
233
- def pyenv_versions
234
- @pyenv_versions ||= run_poetry_command("pyenv install --list")
211
+ def python_requirement_parser
212
+ @python_requirement_parser ||=
213
+ FileParser::PythonRequirementParser.new(
214
+ dependency_files: dependency_files
215
+ )
235
216
  end
236
217
 
237
218
  def pre_installed_python?(version)
@@ -324,14 +305,6 @@ module Dependabot
324
305
  poetry_lock || pyproject_lock
325
306
  end
326
307
 
327
- def python_version_file
328
- dependency_files.find { |f| f.name == ".python-version" }
329
- end
330
-
331
- def runtime_file
332
- dependency_files.find { |f| f.name.end_with?("runtime.txt") }
333
- end
334
-
335
308
  def run_poetry_command(command)
336
309
  start = Time.now
337
310
  command = SharedHelpers.escape_command(command)
@@ -360,4 +333,3 @@ module Dependabot
360
333
  end
361
334
  end
362
335
  end
363
- # rubocop:enable Metrics/ClassLength
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-python
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.110.13
4
+ version: 0.110.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.110.13
19
+ version: 0.110.14
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.110.13
26
+ version: 0.110.14
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -155,6 +155,7 @@ files:
155
155
  - lib/dependabot/python/file_parser.rb
156
156
  - lib/dependabot/python/file_parser/pipfile_files_parser.rb
157
157
  - lib/dependabot/python/file_parser/poetry_files_parser.rb
158
+ - lib/dependabot/python/file_parser/python_requirement_parser.rb
158
159
  - lib/dependabot/python/file_parser/setup_file_parser.rb
159
160
  - lib/dependabot/python/file_updater.rb
160
161
  - lib/dependabot/python/file_updater/pip_compile_file_updater.rb