dependabot-python 0.212.0 → 0.214.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 +4 -4
 - data/helpers/build +5 -6
 - data/helpers/lib/parser.py +59 -0
 - data/helpers/requirements.txt +3 -3
 - data/helpers/run.py +2 -0
 - data/lib/dependabot/python/file_fetcher.rb +21 -12
 - data/lib/dependabot/python/file_parser/{poetry_files_parser.rb → pyproject_files_parser.rb} +84 -2
 - data/lib/dependabot/python/file_parser/setup_file_parser.rb +4 -4
 - data/lib/dependabot/python/file_parser.rb +5 -29
 - data/lib/dependabot/python/file_updater/pip_compile_file_updater.rb +7 -22
 - data/lib/dependabot/python/file_updater/pipfile_file_updater.rb +11 -8
 - data/lib/dependabot/python/file_updater/pipfile_preparer.rb +6 -4
 - data/lib/dependabot/python/file_updater/poetry_file_updater.rb +15 -7
 - data/lib/dependabot/python/file_updater/pyproject_preparer.rb +16 -1
 - data/lib/dependabot/python/file_updater.rb +14 -1
 - data/lib/dependabot/python/helpers.rb +37 -0
 - data/lib/dependabot/python/metadata_finder.rb +2 -0
 - data/lib/dependabot/python/python_versions.rb +11 -7
 - data/lib/dependabot/python/requirement.rb +7 -4
 - data/lib/dependabot/python/requirement_parser.rb +20 -23
 - data/lib/dependabot/python/update_checker/index_finder.rb +1 -1
 - data/lib/dependabot/python/update_checker/latest_version_finder.rb +2 -2
 - data/lib/dependabot/python/update_checker/pip_compile_version_resolver.rb +19 -21
 - data/lib/dependabot/python/update_checker/pipenv_version_resolver.rb +16 -18
 - data/lib/dependabot/python/update_checker/poetry_version_resolver.rb +14 -12
 - data/lib/dependabot/python/update_checker/requirements_updater.rb +17 -4
 - data/lib/dependabot/python/update_checker.rb +82 -25
 - data/lib/dependabot/python/version.rb +2 -2
 - metadata +15 -56
 
| 
         @@ -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.
         
     | 
| 
         @@ -52,7 +63,7 @@ module Dependabot 
     | 
|
| 
       52 
63 
     | 
    
         
             
                      poetry_object = pyproject_object["tool"]["poetry"]
         
     | 
| 
       53 
64 
     | 
    
         
             
                      excluded_names = dependencies.map(&:name) + ["python"]
         
     | 
| 
       54 
65 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
                      Dependabot::Python::FileParser:: 
     | 
| 
      
 66 
     | 
    
         
            +
                      Dependabot::Python::FileParser::PyprojectFilesParser::POETRY_DEPENDENCY_TYPES.each do |key|
         
     | 
| 
       56 
67 
     | 
    
         
             
                        next unless poetry_object[key]
         
     | 
| 
       57 
68 
     | 
    
         | 
| 
       58 
69 
     | 
    
         
             
                        source_types = %w(directory file url)
         
     | 
| 
         @@ -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,5 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require "toml-rb"
         
     | 
| 
       3 
4 
     | 
    
         
             
            require "dependabot/file_updaters"
         
     | 
| 
       4 
5 
     | 
    
         
             
            require "dependabot/file_updaters/base"
         
     | 
| 
       5 
6 
     | 
    
         
             
            require "dependabot/shared_helpers"
         
     | 
| 
         @@ -61,7 +62,13 @@ module Dependabot 
     | 
|
| 
       61 
62 
     | 
    
         
             
                    # Otherwise, this is a top-level dependency, and we can figure out
         
     | 
| 
       62 
63 
     | 
    
         
             
                    # which resolver to use based on the filename of its requirements
         
     | 
| 
       63 
64 
     | 
    
         
             
                    return :pipfile if changed_req_files.any?("Pipfile")
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    if changed_req_files.any?("pyproject.toml")
         
     | 
| 
      
 67 
     | 
    
         
            +
                      return :poetry if poetry_based?
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                      return :requirements
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
       65 
72 
     | 
    
         
             
                    return :pip_compile if changed_req_files.any? { |f| f.end_with?(".in") }
         
     | 
| 
       66 
73 
     | 
    
         | 
| 
       67 
74 
     | 
    
         
             
                    :requirements
         
     | 
| 
         @@ -119,6 +126,12 @@ module Dependabot 
     | 
|
| 
       119 
126 
     | 
    
         
             
                    raise "Missing required files!"
         
     | 
| 
       120 
127 
     | 
    
         
             
                  end
         
     | 
| 
       121 
128 
     | 
    
         | 
| 
      
 129 
     | 
    
         
            +
                  def poetry_based?
         
     | 
| 
      
 130 
     | 
    
         
            +
                    return false unless pyproject
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                    !TomlRB.parse(pyproject.content).dig("tool", "poetry").nil?
         
     | 
| 
      
 133 
     | 
    
         
            +
                  end
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
       122 
135 
     | 
    
         
             
                  def pipfile
         
     | 
| 
       123 
136 
     | 
    
         
             
                    @pipfile ||= get_original_file("Pipfile")
         
     | 
| 
       124 
137 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "dependabot/logger"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "dependabot/python/version"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Dependabot
         
     | 
| 
      
 7 
     | 
    
         
            +
              module Python
         
     | 
| 
      
 8 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def self.install_required_python(python_version)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    # The leading space is important in the version check
         
     | 
| 
      
 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
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    Dependabot.logger.info("Installing required Python #{python_version}.")
         
     | 
| 
      
 22 
     | 
    
         
            +
                    start = Time.now
         
     | 
| 
      
 23 
     | 
    
         
            +
                    SharedHelpers.run_shell_command("pyenv install -s #{python_version}")
         
     | 
| 
      
 24 
     | 
    
         
            +
                    SharedHelpers.run_shell_command("pyenv exec pip install --upgrade pip")
         
     | 
| 
      
 25 
     | 
    
         
            +
                    SharedHelpers.run_shell_command("pyenv exec pip install -r" \
         
     | 
| 
      
 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]}"
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -4,18 +4,22 @@ module Dependabot 
     | 
|
| 
       4 
4 
     | 
    
         
             
              module Python
         
     | 
| 
       5 
5 
     | 
    
         
             
                module PythonVersions
         
     | 
| 
       6 
6 
     | 
    
         
             
                  PRE_INSTALLED_PYTHON_VERSIONS = %w(
         
     | 
| 
       7 
     | 
    
         
            -
                    3. 
     | 
| 
      
 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. 
     | 
| 
       14 
     | 
    
         
            -
                    3. 
     | 
| 
       15 
     | 
    
         
            -
                    3. 
     | 
| 
       16 
     | 
    
         
            -
                    3. 
     | 
| 
       17 
     | 
    
         
            -
                    3. 
     | 
| 
       18 
     | 
    
         
            -
                    3.6. 
     | 
| 
      
 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
         
     | 
| 
         @@ -6,7 +6,7 @@ require "dependabot/python/version" 
     | 
|
| 
       6 
6 
     | 
    
         
             
            module Dependabot
         
     | 
| 
       7 
7 
     | 
    
         
             
              module Python
         
     | 
| 
       8 
8 
     | 
    
         
             
                class Requirement < Gem::Requirement
         
     | 
| 
       9 
     | 
    
         
            -
                  OR_SEPARATOR = /(?<=[a-zA-Z0-9)*])\s 
     | 
| 
      
 9 
     | 
    
         
            +
                  OR_SEPARATOR = /(?<=[a-zA-Z0-9)*])\s*\|+/
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
                  # Add equality and arbitrary-equality matchers
         
     | 
| 
       12 
12 
     | 
    
         
             
                  OPS = OPS.merge(
         
     | 
| 
         @@ -19,8 +19,8 @@ module Dependabot 
     | 
|
| 
       19 
19 
     | 
    
         
             
                  version_pattern = Python::Version::VERSION_PATTERN
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                  PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{version_pattern})\\s*"
         
     | 
| 
       22 
     | 
    
         
            -
                  PATTERN = /\A#{PATTERN_RAW}\z 
     | 
| 
       23 
     | 
    
         
            -
                  PARENS_PATTERN = /\A\(([^)]+)\)\z 
     | 
| 
      
 22 
     | 
    
         
            +
                  PATTERN = /\A#{PATTERN_RAW}\z/
         
     | 
| 
      
 23 
     | 
    
         
            +
                  PARENS_PATTERN = /\A\(([^)]+)\)\z/
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
                  def self.parse(obj)
         
     | 
| 
       26 
26 
     | 
    
         
             
                    return ["=", Python::Version.new(obj.to_s)] if obj.is_a?(Gem::Version)
         
     | 
| 
         @@ -60,6 +60,9 @@ module Dependabot 
     | 
|
| 
       60 
60 
     | 
    
         
             
                    requirements = requirements.flatten.flat_map do |req_string|
         
     | 
| 
       61 
61 
     | 
    
         
             
                      next if req_string.nil?
         
     | 
| 
       62 
62 
     | 
    
         | 
| 
      
 63 
     | 
    
         
            +
                      # Standard python doesn't support whitespace in requirements, but Poetry does.
         
     | 
| 
      
 64 
     | 
    
         
            +
                      req_string = req_string.gsub(/(\d +)([<=>])/, '\1,\2')
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
       63 
66 
     | 
    
         
             
                      req_string.split(",").map(&:strip).map do |r|
         
     | 
| 
       64 
67 
     | 
    
         
             
                        convert_python_constraint_to_ruby_constraint(r)
         
     | 
| 
       65 
68 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -87,7 +90,7 @@ module Dependabot 
     | 
|
| 
       87 
90 
     | 
    
         
             
                    return nil if req_string == "*"
         
     | 
| 
       88 
91 
     | 
    
         | 
| 
       89 
92 
     | 
    
         
             
                    req_string = req_string.gsub("~=", "~>")
         
     | 
| 
       90 
     | 
    
         
            -
                    req_string = req_string.gsub(/(?<=\d)[<=>] 
     | 
| 
      
 93 
     | 
    
         
            +
                    req_string = req_string.gsub(/(?<=\d)[<=>].*\Z/, "")
         
     | 
| 
       91 
94 
     | 
    
         | 
| 
       92 
95 
     | 
    
         
             
                    if req_string.match?(/~[^>]/) then convert_tilde_req(req_string)
         
     | 
| 
       93 
96 
     | 
    
         
             
                    elsif req_string.start_with?("^") then convert_caret_req(req_string)
         
     | 
| 
         @@ -3,29 +3,26 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Dependabot
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Python
         
     | 
| 
       5 
5 
     | 
    
         
             
                class RequirementParser
         
     | 
| 
       6 
     | 
    
         
            -
                  NAME = /[a-zA-Z0-9](?:[a-zA-Z0-9\-_\.]*[a-zA-Z0-9]) 
     | 
| 
       7 
     | 
    
         
            -
                  EXTRA = /[a-zA-Z0-9\-_\.] 
     | 
| 
       8 
     | 
    
         
            -
                  COMPARISON =  
     | 
| 
       9 
     | 
    
         
            -
                  VERSION = /([1-9][0-9]*!)?[0-9]+[a-zA-Z0-9\-_.*]*(\+[0-9a-zA-Z]+(\.[0-9a-zA-Z]+)*) 
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                  REQUIREMENT =
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                   
     | 
| 
       14 
     | 
    
         
            -
                   
     | 
| 
       15 
     | 
    
         
            -
                   
     | 
| 
       16 
     | 
    
         
            -
                   
     | 
| 
       17 
     | 
    
         
            -
                   
     | 
| 
       18 
     | 
    
         
            -
                    %r{[a-zA-Z0-9\s\(\)\.\{\}\-_\*#:;/\?\[\]!~`@\$%\^&=\+\|<>]}.freeze
         
     | 
| 
       19 
     | 
    
         
            -
                  PYTHON_STR = /('(#{PYTHON_STR_C}|")*'|"(#{PYTHON_STR_C}|')*")/.freeze
         
     | 
| 
      
 6 
     | 
    
         
            +
                  NAME = /[a-zA-Z0-9](?:[a-zA-Z0-9\-_\.]*[a-zA-Z0-9])?/
         
     | 
| 
      
 7 
     | 
    
         
            +
                  EXTRA = /[a-zA-Z0-9\-_\.]+/
         
     | 
| 
      
 8 
     | 
    
         
            +
                  COMPARISON = /===|==|>=|<=|<|>|~=|!=/
         
     | 
| 
      
 9 
     | 
    
         
            +
                  VERSION = /([1-9][0-9]*!)?[0-9]+[a-zA-Z0-9\-_.*]*(\+[0-9a-zA-Z]+(\.[0-9a-zA-Z]+)*)?/
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  REQUIREMENT = /(?<comparison>#{COMPARISON})\s*\\?\s*(?<version>#{VERSION})/
         
     | 
| 
      
 12 
     | 
    
         
            +
                  HASH = /--hash=(?<algorithm>.*?):(?<hash>.*?)(?=\s|$)/
         
     | 
| 
      
 13 
     | 
    
         
            +
                  REQUIREMENTS = /#{REQUIREMENT}(\s*,\s*\\?\s*#{REQUIREMENT})*/
         
     | 
| 
      
 14 
     | 
    
         
            +
                  HASHES = /#{HASH}(\s*\\?\s*#{HASH})*/
         
     | 
| 
      
 15 
     | 
    
         
            +
                  MARKER_OP = /\s*(#{COMPARISON}|(\s*in)|(\s*not\s*in))/
         
     | 
| 
      
 16 
     | 
    
         
            +
                  PYTHON_STR_C = %r{[a-zA-Z0-9\s\(\)\.\{\}\-_\*#:;/\?\[\]!~`@\$%\^&=\+\|<>]}
         
     | 
| 
      
 17 
     | 
    
         
            +
                  PYTHON_STR = /('(#{PYTHON_STR_C}|")*'|"(#{PYTHON_STR_C}|')*")/
         
     | 
| 
       20 
18 
     | 
    
         
             
                  ENV_VAR =
         
     | 
| 
       21 
19 
     | 
    
         
             
                    /python_version|python_full_version|os_name|sys_platform|
         
     | 
| 
       22 
20 
     | 
    
         
             
                     platform_release|platform_system|platform_version|platform_machine|
         
     | 
| 
       23 
21 
     | 
    
         
             
                     platform_python_implementation|implementation_name|
         
     | 
| 
       24 
     | 
    
         
            -
                     implementation_version 
     | 
| 
       25 
     | 
    
         
            -
                  MARKER_VAR = /\s*(#{ENV_VAR}|#{PYTHON_STR}) 
     | 
| 
       26 
     | 
    
         
            -
                  MARKER_EXPR_ONE = /#{MARKER_VAR}#{MARKER_OP}#{MARKER_VAR} 
     | 
| 
       27 
     | 
    
         
            -
                  MARKER_EXPR =
         
     | 
| 
       28 
     | 
    
         
            -
                    /(#{MARKER_EXPR_ONE}|\(\s*|\s*\)|\s+and\s+|\s+or\s+)+/.freeze
         
     | 
| 
      
 22 
     | 
    
         
            +
                     implementation_version/
         
     | 
| 
      
 23 
     | 
    
         
            +
                  MARKER_VAR = /\s*(#{ENV_VAR}|#{PYTHON_STR})/
         
     | 
| 
      
 24 
     | 
    
         
            +
                  MARKER_EXPR_ONE = /#{MARKER_VAR}#{MARKER_OP}#{MARKER_VAR}/
         
     | 
| 
      
 25 
     | 
    
         
            +
                  MARKER_EXPR = /(#{MARKER_EXPR_ONE}|\(\s*|\s*\)|\s+and\s+|\s+or\s+)+/
         
     | 
| 
       29 
26 
     | 
    
         | 
| 
       30 
27 
     | 
    
         
             
                  INSTALL_REQ_WITH_REQUIREMENT =
         
     | 
| 
       31 
28 
     | 
    
         
             
                    /\s*\\?\s*(?<name>#{NAME})
         
     | 
| 
         @@ -34,7 +31,7 @@ module Dependabot 
     | 
|
| 
       34 
31 
     | 
    
         
             
                      \s*\\?\s*(;\s*(?<markers>#{MARKER_EXPR}))?
         
     | 
| 
       35 
32 
     | 
    
         
             
                      \s*\\?\s*(?<hashes>#{HASHES})?
         
     | 
| 
       36 
33 
     | 
    
         
             
                      \s*#*\s*(?<comment>.+)?
         
     | 
| 
       37 
     | 
    
         
            -
                    /x 
     | 
| 
      
 34 
     | 
    
         
            +
                    /x
         
     | 
| 
       38 
35 
     | 
    
         | 
| 
       39 
36 
     | 
    
         
             
                  INSTALL_REQ_WITHOUT_REQUIREMENT =
         
     | 
| 
       40 
37 
     | 
    
         
             
                    /^\s*\\?\s*(?<name>#{NAME})
         
     | 
| 
         @@ -42,7 +39,7 @@ module Dependabot 
     | 
|
| 
       42 
39 
     | 
    
         
             
                      \s*\\?\s*(;\s*(?<markers>#{MARKER_EXPR}))?
         
     | 
| 
       43 
40 
     | 
    
         
             
                      \s*\\?\s*(?<hashes>#{HASHES})?
         
     | 
| 
       44 
41 
     | 
    
         
             
                      \s*#*\s*(?<comment>.+)?$
         
     | 
| 
       45 
     | 
    
         
            -
                    /x 
     | 
| 
      
 42 
     | 
    
         
            +
                    /x
         
     | 
| 
       46 
43 
     | 
    
         | 
| 
       47 
44 
     | 
    
         
             
                  VALID_REQ_TXT_REQUIREMENT =
         
     | 
| 
       48 
45 
     | 
    
         
             
                    /^\s*\\?\s*(?<name>#{NAME})
         
     | 
| 
         @@ -51,12 +48,12 @@ module Dependabot 
     | 
|
| 
       51 
48 
     | 
    
         
             
                      \s*\\?\s*(;\s*(?<markers>#{MARKER_EXPR}))?
         
     | 
| 
       52 
49 
     | 
    
         
             
                      \s*\\?\s*(?<hashes>#{HASHES})?
         
     | 
| 
       53 
50 
     | 
    
         
             
                      \s*(\#+\s*(?<comment>.*))?$
         
     | 
| 
       54 
     | 
    
         
            -
                    /x 
     | 
| 
      
 51 
     | 
    
         
            +
                    /x
         
     | 
| 
       55 
52 
     | 
    
         | 
| 
       56 
53 
     | 
    
         
             
                  NAME_WITH_EXTRAS =
         
     | 
| 
       57 
54 
     | 
    
         
             
                    /\s*\\?\s*(?<name>#{NAME})
         
     | 
| 
       58 
55 
     | 
    
         
             
                      (\s*\\?\s*\[\s*(?<extras>#{EXTRA}(\s*,\s*#{EXTRA})*)\s*\])?
         
     | 
| 
       59 
     | 
    
         
            -
                    /x 
     | 
| 
      
 56 
     | 
    
         
            +
                    /x
         
     | 
| 
       60 
57 
     | 
    
         
             
                end
         
     | 
| 
       61 
58 
     | 
    
         
             
              end
         
     | 
| 
       62 
59 
     | 
    
         
             
            end
         
     | 
| 
         @@ -9,7 +9,7 @@ module Dependabot 
     | 
|
| 
       9 
9 
     | 
    
         
             
                class UpdateChecker
         
     | 
| 
       10 
10 
     | 
    
         
             
                  class IndexFinder
         
     | 
| 
       11 
11 
     | 
    
         
             
                    PYPI_BASE_URL = "https://pypi.org/simple/"
         
     | 
| 
       12 
     | 
    
         
            -
                    ENVIRONMENT_VARIABLE_REGEX = /\$\{.+\} 
     | 
| 
      
 12 
     | 
    
         
            +
                    ENVIRONMENT_VARIABLE_REGEX = /\$\{.+\}/
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                    def initialize(dependency_files:, credentials:)
         
     | 
| 
       15 
15 
     | 
    
         
             
                      @dependency_files = dependency_files
         
     | 
| 
         @@ -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. 
     | 
| 
      
 115 
     | 
    
         
            +
                      return versions_array unless dependency.numeric_version
         
     | 
| 
       116 
116 
     | 
    
         | 
| 
       117 
     | 
    
         
            -
                      versions_array.select { |version| 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)
         
     | 
| 
         @@ -11,6 +11,7 @@ require "dependabot/python/file_updater/requirement_replacer" 
     | 
|
| 
       11 
11 
     | 
    
         
             
            require "dependabot/python/file_updater/setup_file_sanitizer"
         
     | 
| 
       12 
12 
     | 
    
         
             
            require "dependabot/python/version"
         
     | 
| 
       13 
13 
     | 
    
         
             
            require "dependabot/shared_helpers"
         
     | 
| 
      
 14 
     | 
    
         
            +
            require "dependabot/python/helpers"
         
     | 
| 
       14 
15 
     | 
    
         
             
            require "dependabot/python/native_helpers"
         
     | 
| 
       15 
16 
     | 
    
         
             
            require "dependabot/python/python_versions"
         
     | 
| 
       16 
17 
     | 
    
         
             
            require "dependabot/python/name_normaliser"
         
     | 
| 
         @@ -24,16 +25,14 @@ module Dependabot 
     | 
|
| 
       24 
25 
     | 
    
         
             
                  # - Run `pip-compile` and see what the result is
         
     | 
| 
       25 
26 
     | 
    
         
             
                  # rubocop:disable Metrics/ClassLength
         
     | 
| 
       26 
27 
     | 
    
         
             
                  class PipCompileVersionResolver
         
     | 
| 
       27 
     | 
    
         
            -
                    GIT_DEPENDENCY_UNREACHABLE_REGEX =
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                    GIT_REFERENCE_NOT_FOUND_REGEX =
         
     | 
| 
       30 
     | 
    
         
            -
                      /Did not find branch or tag '(?<tag>[^\n"]+)'/m.freeze
         
     | 
| 
      
 28 
     | 
    
         
            +
                    GIT_DEPENDENCY_UNREACHABLE_REGEX = /git clone --filter=blob:none --quiet (?<url>[^\s]+).* /
         
     | 
| 
      
 29 
     | 
    
         
            +
                    GIT_REFERENCE_NOT_FOUND_REGEX = /Did not find branch or tag '(?<tag>[^\n"]+)'/m
         
     | 
| 
       31 
30 
     | 
    
         
             
                    NATIVE_COMPILATION_ERROR =
         
     | 
| 
       32 
31 
     | 
    
         
             
                      "pip._internal.exceptions.InstallationSubprocessError: Command errored out with exit status 1:"
         
     | 
| 
       33 
32 
     | 
    
         
             
                    # See https://packaging.python.org/en/latest/tutorials/packaging-projects/#configuring-metadata
         
     | 
| 
       34 
     | 
    
         
            -
                    PYTHON_PACKAGE_NAME_REGEX = /[A-Za-z0-9_\-] 
     | 
| 
      
 33 
     | 
    
         
            +
                    PYTHON_PACKAGE_NAME_REGEX = /[A-Za-z0-9_\-]+/
         
     | 
| 
       35 
34 
     | 
    
         
             
                    RESOLUTION_IMPOSSIBLE_ERROR = "ResolutionImpossible"
         
     | 
| 
       36 
     | 
    
         
            -
                    ERROR_REGEX = /(?<=ERROR\:\W) 
     | 
| 
      
 35 
     | 
    
         
            +
                    ERROR_REGEX = /(?<=ERROR\:\W).*$/
         
     | 
| 
       37 
36 
     | 
    
         | 
| 
       38 
37 
     | 
    
         
             
                    attr_reader :dependency, :dependency_files, :credentials
         
     | 
| 
       39 
38 
     | 
    
         | 
| 
         @@ -72,7 +71,7 @@ module Dependabot 
     | 
|
| 
       72 
71 
     | 
    
         
             
                        SharedHelpers.in_a_temporary_directory do
         
     | 
| 
       73 
72 
     | 
    
         
             
                          SharedHelpers.with_git_configured(credentials: credentials) do
         
     | 
| 
       74 
73 
     | 
    
         
             
                            write_temporary_dependency_files(updated_req: requirement)
         
     | 
| 
       75 
     | 
    
         
            -
                            install_required_python
         
     | 
| 
      
 74 
     | 
    
         
            +
                            Helpers.install_required_python(python_version)
         
     | 
| 
       76 
75 
     | 
    
         | 
| 
       77 
76 
     | 
    
         
             
                            filenames_to_compile.each do |filename|
         
     | 
| 
       78 
77 
     | 
    
         
             
                              # Shell out to pip-compile.
         
     | 
| 
         @@ -80,9 +79,17 @@ module Dependabot 
     | 
|
| 
       80 
79 
     | 
    
         
             
                              run_pip_compile_command(
         
     | 
| 
       81 
80 
     | 
    
         
             
                                "pyenv exec pip-compile -v #{pip_compile_options(filename)} -P #{dependency.name} #{filename}"
         
     | 
| 
       82 
81 
     | 
    
         
             
                              )
         
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
                               
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                              next if dependency.top_level?
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                              # Run pip-compile a second time for transient dependencies
         
     | 
| 
      
 86 
     | 
    
         
            +
                              # to make sure we do not update dependencies that are
         
     | 
| 
      
 87 
     | 
    
         
            +
                              # superfluous. pip-compile does not detect these when
         
     | 
| 
      
 88 
     | 
    
         
            +
                              # updating a specific dependency with the -P option.
         
     | 
| 
      
 89 
     | 
    
         
            +
                              # Running pip-compile a second time will automatically remove
         
     | 
| 
      
 90 
     | 
    
         
            +
                              # superfluous dependencies. Dependabot then marks those with
         
     | 
| 
      
 91 
     | 
    
         
            +
                              # update_not_possible.
         
     | 
| 
      
 92 
     | 
    
         
            +
                              write_original_manifest_files
         
     | 
| 
       86 
93 
     | 
    
         
             
                              run_pip_compile_command(
         
     | 
| 
       87 
94 
     | 
    
         
             
                                "pyenv exec pip-compile #{pip_compile_options(filename)} #{filename}"
         
     | 
| 
       88 
95 
     | 
    
         
             
                              )
         
     | 
| 
         @@ -247,7 +254,7 @@ module Dependabot 
     | 
|
| 
       247 
254 
     | 
    
         
             
                    end
         
     | 
| 
       248 
255 
     | 
    
         | 
| 
       249 
256 
     | 
    
         
             
                    def run_pip_compile_command(command)
         
     | 
| 
       250 
     | 
    
         
            -
                      run_command("pyenv local #{python_version}")
         
     | 
| 
      
 257 
     | 
    
         
            +
                      run_command("pyenv local #{Helpers.python_major_minor(python_version)}")
         
     | 
| 
       251 
258 
     | 
    
         
             
                      run_command(command)
         
     | 
| 
       252 
259 
     | 
    
         
             
                    end
         
     | 
| 
       253 
260 
     | 
    
         | 
| 
         @@ -291,7 +298,7 @@ module Dependabot 
     | 
|
| 
       291 
298 
     | 
    
         
             
                      end
         
     | 
| 
       292 
299 
     | 
    
         | 
| 
       293 
300 
     | 
    
         
             
                      # Overwrite the .python-version with updated content
         
     | 
| 
       294 
     | 
    
         
            -
                      File.write(".python-version", python_version)
         
     | 
| 
      
 301 
     | 
    
         
            +
                      File.write(".python-version", Helpers.python_major_minor(python_version))
         
     | 
| 
       295 
302 
     | 
    
         | 
| 
       296 
303 
     | 
    
         
             
                      setup_files.each do |file|
         
     | 
| 
       297 
304 
     | 
    
         
             
                        path = file.name
         
     | 
| 
         @@ -313,15 +320,6 @@ module Dependabot 
     | 
|
| 
       313 
320 
     | 
    
         
             
                      end
         
     | 
| 
       314 
321 
     | 
    
         
             
                    end
         
     | 
| 
       315 
322 
     | 
    
         | 
| 
       316 
     | 
    
         
            -
                    def install_required_python
         
     | 
| 
       317 
     | 
    
         
            -
                      return if run_command("pyenv versions").include?("#{python_version}\n")
         
     | 
| 
       318 
     | 
    
         
            -
             
     | 
| 
       319 
     | 
    
         
            -
                      run_command("pyenv install -s #{python_version}")
         
     | 
| 
       320 
     | 
    
         
            -
                      run_command("pyenv exec pip install --upgrade pip")
         
     | 
| 
       321 
     | 
    
         
            -
                      run_command("pyenv exec pip install -r" \
         
     | 
| 
       322 
     | 
    
         
            -
                                  "#{NativeHelpers.python_requirements_path}")
         
     | 
| 
       323 
     | 
    
         
            -
                    end
         
     | 
| 
       324 
     | 
    
         
            -
             
     | 
| 
       325 
323 
     | 
    
         
             
                    def sanitized_setup_file_content(file)
         
     | 
| 
       326 
324 
     | 
    
         
             
                      @sanitized_setup_file_content ||= {}
         
     | 
| 
       327 
325 
     | 
    
         
             
                      return @sanitized_setup_file_content[file.name] if @sanitized_setup_file_content[file.name]
         
     | 
| 
         @@ -30,21 +30,18 @@ module Dependabot 
     | 
|
| 
       30 
30 
     | 
    
         
             
                  # still better than nothing, though.
         
     | 
| 
       31 
31 
     | 
    
         
             
                  class PipenvVersionResolver
         
     | 
| 
       32 
32 
     | 
    
         
             
                    # rubocop:disable Layout/LineLength
         
     | 
| 
       33 
     | 
    
         
            -
                    GIT_DEPENDENCY_UNREACHABLE_REGEX =
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                    GIT_REFERENCE_NOT_FOUND_REGEX =
         
     | 
| 
       36 
     | 
    
         
            -
                      %r{git checkout -q (?<tag>[^\n"]+)\n?[^\n]*/(?<name>.*?)(\\n'\]|$)}m.
         
     | 
| 
       37 
     | 
    
         
            -
                      freeze
         
     | 
| 
      
 33 
     | 
    
         
            +
                    GIT_DEPENDENCY_UNREACHABLE_REGEX = /git clone -q (?<url>[^\s]+).* /
         
     | 
| 
      
 34 
     | 
    
         
            +
                    GIT_REFERENCE_NOT_FOUND_REGEX = %r{git checkout -q (?<tag>[^\n"]+)\n?[^\n]*/(?<name>.*?)(\\n'\]|$)}m
         
     | 
| 
       38 
35 
     | 
    
         
             
                    PIPENV_INSTALLATION_ERROR = "pipenv.patched.notpip._internal.exceptions.InstallationError: Command errored out" \
         
     | 
| 
       39 
36 
     | 
    
         
             
                                                " with exit status 1: python setup.py egg_info"
         
     | 
| 
       40 
37 
     | 
    
         
             
                    TRACEBACK = "Traceback (most recent call last):"
         
     | 
| 
       41 
38 
     | 
    
         
             
                    PIPENV_INSTALLATION_ERROR_REGEX =
         
     | 
| 
       42 
     | 
    
         
            -
                      /#{Regexp.quote(TRACEBACK)}[\s\S]*^\s+import\s(?<name>.+)[\s\S]*^#{Regexp.quote(PIPENV_INSTALLATION_ERROR)} 
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
      
 39 
     | 
    
         
            +
                      /#{Regexp.quote(TRACEBACK)}[\s\S]*^\s+import\s(?<name>.+)[\s\S]*^#{Regexp.quote(PIPENV_INSTALLATION_ERROR)}/
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
       44 
41 
     | 
    
         
             
                    UNSUPPORTED_DEPS = %w(pyobjc).freeze
         
     | 
| 
       45 
42 
     | 
    
         
             
                    UNSUPPORTED_DEP_REGEX =
         
     | 
| 
       46 
     | 
    
         
            -
                      /Could not find a version that satisfies the requirement.*(?:#{UNSUPPORTED_DEPS.join("|")}) 
     | 
| 
       47 
     | 
    
         
            -
                    PIPENV_RANGE_WARNING = /Warning:\sPython\s[<>].* was not found 
     | 
| 
      
 43 
     | 
    
         
            +
                      /Could not find a version that satisfies the requirement.*(?:#{UNSUPPORTED_DEPS.join("|")})/
         
     | 
| 
      
 44 
     | 
    
         
            +
                    PIPENV_RANGE_WARNING = /Warning:\sPython\s[<>].* was not found/
         
     | 
| 
       48 
45 
     | 
    
         
             
                    # rubocop:enable Layout/LineLength
         
     | 
| 
       49 
46 
     | 
    
         | 
| 
       50 
47 
     | 
    
         
             
                    DEPENDENCY_TYPES = %w(packages dev-packages).freeze
         
     | 
| 
         @@ -293,7 +290,7 @@ module Dependabot 
     | 
|
| 
       293 
290 
     | 
    
         
             
                      end
         
     | 
| 
       294 
291 
     | 
    
         | 
| 
       295 
292 
     | 
    
         
             
                      # Overwrite the .python-version with updated content
         
     | 
| 
       296 
     | 
    
         
            -
                      File.write(".python-version", python_version)
         
     | 
| 
      
 293 
     | 
    
         
            +
                      File.write(".python-version", Helpers.python_major_minor(python_version))
         
     | 
| 
       297 
294 
     | 
    
         | 
| 
       298 
295 
     | 
    
         
             
                      setup_files.each do |file|
         
     | 
| 
       299 
296 
     | 
    
         
             
                        path = file.name
         
     | 
| 
         @@ -323,13 +320,7 @@ module Dependabot 
     | 
|
| 
       323 
320 
     | 
    
         
             
                        nil
         
     | 
| 
       324 
321 
     | 
    
         
             
                      end
         
     | 
| 
       325 
322 
     | 
    
         | 
| 
       326 
     | 
    
         
            -
                       
     | 
| 
       327 
     | 
    
         
            -
             
     | 
| 
       328 
     | 
    
         
            -
                      requirements_path = NativeHelpers.python_requirements_path
         
     | 
| 
       329 
     | 
    
         
            -
                      run_command("pyenv install -s #{python_version}")
         
     | 
| 
       330 
     | 
    
         
            -
                      run_command("pyenv exec pip install --upgrade pip")
         
     | 
| 
       331 
     | 
    
         
            -
                      run_command("pyenv exec pip install -r " \
         
     | 
| 
       332 
     | 
    
         
            -
                                  "#{requirements_path}")
         
     | 
| 
      
 323 
     | 
    
         
            +
                      Helpers.install_required_python(python_version)
         
     | 
| 
       333 
324 
     | 
    
         
             
                    end
         
     | 
| 
       334 
325 
     | 
    
         | 
| 
       335 
326 
     | 
    
         
             
                    def sanitized_setup_file_content(file)
         
     | 
| 
         @@ -350,6 +341,7 @@ module Dependabot 
     | 
|
| 
       350 
341 
     | 
    
         
             
                      content = freeze_other_dependencies(content)
         
     | 
| 
       351 
342 
     | 
    
         
             
                      content = set_target_dependency_req(content, updated_requirement)
         
     | 
| 
       352 
343 
     | 
    
         
             
                      content = add_private_sources(content)
         
     | 
| 
      
 344 
     | 
    
         
            +
                      content = update_python_requirement(content)
         
     | 
| 
       353 
345 
     | 
    
         
             
                      content
         
     | 
| 
       354 
346 
     | 
    
         
             
                    end
         
     | 
| 
       355 
347 
     | 
    
         | 
| 
         @@ -359,6 +351,12 @@ module Dependabot 
     | 
|
| 
       359 
351 
     | 
    
         
             
                        freeze_top_level_dependencies_except([dependency])
         
     | 
| 
       360 
352 
     | 
    
         
             
                    end
         
     | 
| 
       361 
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 
     | 
    
         
            +
             
     | 
| 
       362 
360 
     | 
    
         
             
                    # rubocop:disable Metrics/PerceivedComplexity
         
     | 
| 
       363 
361 
     | 
    
         
             
                    def set_target_dependency_req(pipfile_content, updated_requirement)
         
     | 
| 
       364 
362 
     | 
    
         
             
                      return pipfile_content unless updated_requirement
         
     | 
| 
         @@ -470,7 +468,7 @@ module Dependabot 
     | 
|
| 
       470 
468 
     | 
    
         
             
                    end
         
     | 
| 
       471 
469 
     | 
    
         | 
| 
       472 
470 
     | 
    
         
             
                    def run_pipenv_command(command, env: pipenv_env_variables)
         
     | 
| 
       473 
     | 
    
         
            -
                      run_command("pyenv local #{python_version}")
         
     | 
| 
      
 471 
     | 
    
         
            +
                      run_command("pyenv local #{Helpers.python_major_minor(python_version)}")
         
     | 
| 
       474 
472 
     | 
    
         
             
                      run_command(command, env: env)
         
     | 
| 
       475 
473 
     | 
    
         
             
                    end
         
     | 
| 
       476 
474 
     | 
    
         | 
| 
         @@ -28,10 +28,14 @@ module Dependabot 
     | 
|
| 
       28 
28 
     | 
    
         
             
                      'checkout',
         
     | 
| 
       29 
29 
     | 
    
         
             
                      '(?<tag>.+?)'
         
     | 
| 
       30 
30 
     | 
    
         
             
                      |
         
     | 
| 
      
 31 
     | 
    
         
            +
                      Failed to checkout
         
     | 
| 
      
 32 
     | 
    
         
            +
                      (?<tag>.+?)
         
     | 
| 
      
 33 
     | 
    
         
            +
                      (?<url>.+?).git at '(?<tag>.+?)'
         
     | 
| 
      
 34 
     | 
    
         
            +
                      |
         
     | 
| 
       31 
35 
     | 
    
         
             
                      ...Failedtoclone
         
     | 
| 
       32 
36 
     | 
    
         
             
                      (?<url>.+?).gitat'(?<tag>.+?)',
         
     | 
| 
       33 
37 
     | 
    
         
             
                      verifyrefexistsonremote)
         
     | 
| 
       34 
     | 
    
         
            -
                    /x 
     | 
| 
      
 38 
     | 
    
         
            +
                    /x # TODO: remove the first clause and | when py3.6 support is EoL
         
     | 
| 
       35 
39 
     | 
    
         
             
                    GIT_DEPENDENCY_UNREACHABLE_REGEX = /
         
     | 
| 
       36 
40 
     | 
    
         
             
                      (?:'\['git',
         
     | 
| 
       37 
41 
     | 
    
         
             
                      \s+'clone',
         
     | 
| 
         @@ -43,7 +47,7 @@ module Dependabot 
     | 
|
| 
       43 
47 
     | 
    
         
             
                      \s+Failed\sto\sclone
         
     | 
| 
       44 
48 
     | 
    
         
             
                      \s+(?<url>.+?),
         
     | 
| 
       45 
49 
     | 
    
         
             
                      \s+check\syour\sgit\sconfiguration)
         
     | 
| 
       46 
     | 
    
         
            -
                    /mx 
     | 
| 
      
 50 
     | 
    
         
            +
                    /mx # TODO: remove the first clause and | when py3.6 support is EoL
         
     | 
| 
       47 
51 
     | 
    
         | 
| 
       48 
52 
     | 
    
         
             
                    attr_reader :dependency, :dependency_files, :credentials
         
     | 
| 
       49 
53 
     | 
    
         | 
| 
         @@ -88,13 +92,11 @@ module Dependabot 
     | 
|
| 
       88 
92 
     | 
    
         
             
                            write_temporary_dependency_files(updated_req: requirement)
         
     | 
| 
       89 
93 
     | 
    
         
             
                            add_auth_env_vars
         
     | 
| 
       90 
94 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
                             
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                                "#{NativeHelpers.python_requirements_path}"
         
     | 
| 
       97 
     | 
    
         
            -
                              )
         
     | 
| 
      
 95 
     | 
    
         
            +
                            Helpers.install_required_python(python_version)
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                            # use system git instead of the pure Python dulwich
         
     | 
| 
      
 98 
     | 
    
         
            +
                            unless python_version&.start_with?("3.6")
         
     | 
| 
      
 99 
     | 
    
         
            +
                              run_poetry_command("pyenv exec poetry config experimental.system-git-client true")
         
     | 
| 
       98 
100 
     | 
    
         
             
                            end
         
     | 
| 
       99 
101 
     | 
    
         | 
| 
       100 
102 
     | 
    
         
             
                            # Shell out to Poetry, which handles everything for us.
         
     | 
| 
         @@ -200,7 +202,7 @@ module Dependabot 
     | 
|
| 
       200 
202 
     | 
    
         
             
                      end
         
     | 
| 
       201 
203 
     | 
    
         | 
| 
       202 
204 
     | 
    
         
             
                      # Overwrite the .python-version with updated content
         
     | 
| 
       203 
     | 
    
         
            -
                      File.write(".python-version", python_version) if python_version
         
     | 
| 
      
 205 
     | 
    
         
            +
                      File.write(".python-version", Helpers.python_major_minor(python_version)) if python_version
         
     | 
| 
       204 
206 
     | 
    
         | 
| 
       205 
207 
     | 
    
         
             
                      # Overwrite the pyproject with updated content
         
     | 
| 
       206 
208 
     | 
    
         
             
                      if update_pyproject
         
     | 
| 
         @@ -282,7 +284,7 @@ module Dependabot 
     | 
|
| 
       282 
284 
     | 
    
         
             
                      pyproject_object = TomlRB.parse(pyproject_content)
         
     | 
| 
       283 
285 
     | 
    
         
             
                      poetry_object = pyproject_object.dig("tool", "poetry")
         
     | 
| 
       284 
286 
     | 
    
         | 
| 
       285 
     | 
    
         
            -
                      Dependabot::Python::FileParser:: 
     | 
| 
      
 287 
     | 
    
         
            +
                      Dependabot::Python::FileParser::PyprojectFilesParser::POETRY_DEPENDENCY_TYPES.each do |type|
         
     | 
| 
       286 
288 
     | 
    
         
             
                        names = poetry_object[type]&.keys || []
         
     | 
| 
       287 
289 
     | 
    
         
             
                        pkg_name = names.find { |nm| normalise(nm) == dependency.name }
         
     | 
| 
       288 
290 
     | 
    
         
             
                        next unless pkg_name
         
     | 
| 
         @@ -335,7 +337,7 @@ module Dependabot 
     | 
|
| 
       335 
337 
     | 
    
         
             
                      stdout, process = Open3.capture2e(command)
         
     | 
| 
       336 
338 
     | 
    
         
             
                      time_taken = Time.now - start
         
     | 
| 
       337 
339 
     | 
    
         | 
| 
       338 
     | 
    
         
            -
                      # Raise an error with the output from the shell session if  
     | 
| 
      
 340 
     | 
    
         
            +
                      # Raise an error with the output from the shell session if poetry
         
     | 
| 
       339 
341 
     | 
    
         
             
                      # returns a non-zero status
         
     | 
| 
       340 
342 
     | 
    
         
             
                      return if process.success?
         
     | 
| 
       341 
343 
     | 
    
         | 
| 
         @@ -9,8 +9,8 @@ module Dependabot 
     | 
|
| 
       9 
9 
     | 
    
         
             
              module Python
         
     | 
| 
       10 
10 
     | 
    
         
             
                class UpdateChecker
         
     | 
| 
       11 
11 
     | 
    
         
             
                  class RequirementsUpdater
         
     | 
| 
       12 
     | 
    
         
            -
                    PYPROJECT_OR_SEPARATOR = /(?<=[a-zA-Z0-9*])\s 
     | 
| 
       13 
     | 
    
         
            -
                    PYPROJECT_SEPARATOR = /#{PYPROJECT_OR_SEPARATOR} 
     | 
| 
      
 12 
     | 
    
         
            +
                    PYPROJECT_OR_SEPARATOR = /(?<=[a-zA-Z0-9*])\s*\|+/
         
     | 
| 
      
 13 
     | 
    
         
            +
                    PYPROJECT_SEPARATOR = /#{PYPROJECT_OR_SEPARATOR}|,/
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
                    class UnfixableRequirement < StandardError; end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
         @@ -175,11 +175,25 @@ module Dependabot 
     | 
|
| 
       175 
175 
     | 
    
         
             
                    end
         
     | 
| 
       176 
176 
     | 
    
         
             
                    # rubocop:enable Metrics/PerceivedComplexity
         
     | 
| 
       177 
177 
     | 
    
         | 
| 
       178 
     | 
    
         
            -
                    # rubocop:disable Metrics/PerceivedComplexity
         
     | 
| 
       179 
178 
     | 
    
         
             
                    def updated_requirement(req)
         
     | 
| 
       180 
179 
     | 
    
         
             
                      return req unless latest_resolvable_version
         
     | 
| 
       181 
180 
     | 
    
         
             
                      return req unless req.fetch(:requirement)
         
     | 
| 
       182 
181 
     | 
    
         | 
| 
      
 182 
     | 
    
         
            +
                      case update_strategy
         
     | 
| 
      
 183 
     | 
    
         
            +
                      when :bump_versions
         
     | 
| 
      
 184 
     | 
    
         
            +
                        update_requirement(req)
         
     | 
| 
      
 185 
     | 
    
         
            +
                      when :bump_versions_if_necessary
         
     | 
| 
      
 186 
     | 
    
         
            +
                        update_requirement_if_needed(req)
         
     | 
| 
      
 187 
     | 
    
         
            +
                      end
         
     | 
| 
      
 188 
     | 
    
         
            +
                    end
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
                    def update_requirement_if_needed(req)
         
     | 
| 
      
 191 
     | 
    
         
            +
                      return req if new_version_satisfies?(req)
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                      update_requirement(req)
         
     | 
| 
      
 194 
     | 
    
         
            +
                    end
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                    def update_requirement(req)
         
     | 
| 
       183 
197 
     | 
    
         
             
                      requirement_strings = req[:requirement].split(",").map(&:strip)
         
     | 
| 
       184 
198 
     | 
    
         | 
| 
       185 
199 
     | 
    
         
             
                      new_requirement =
         
     | 
| 
         @@ -197,7 +211,6 @@ module Dependabot 
     | 
|
| 
       197 
211 
     | 
    
         
             
                    rescue UnfixableRequirement
         
     | 
| 
       198 
212 
     | 
    
         
             
                      req.merge(requirement: :unfixable)
         
     | 
| 
       199 
213 
     | 
    
         
             
                    end
         
     | 
| 
       200 
     | 
    
         
            -
                    # rubocop:enable Metrics/PerceivedComplexity
         
     | 
| 
       201 
214 
     | 
    
         | 
| 
       202 
215 
     | 
    
         
             
                    def new_version_satisfies?(req)
         
     | 
| 
       203 
216 
     | 
    
         
             
                      requirement_class.
         
     |