class PythonLang

Constants

API_URL
COMPARATORS

For Requirements.txt See iscompatible.readthedocs.io/en/latest/

NAME
PIPFILE_SECTIONS
REGEX
SUFFIX_OPTION
VERSION_NUM

Public Class Methods

latest_version(name) click to toggle source

Find the latest versions of a dependency by name

name - String name of the dependency

Returns a Gem::Version

# File lib/cutting_edge/langs/python.rb, line 74
def latest_version(name)
  begin
    content = HTTP.timeout(::CuttingEdge::LAST_VERSION_TIMEOUT).follow(max_hops: 1).get(::File.join(API_URL, name, 'json')).parse
    version = content['info']['version']
    Gem::Version.new(canonical_version(version))
  rescue StandardError, HTTP::TimeoutError => e
    log_error("Encountered error when fetching latest version of #{name}: #{e.class} #{e.message}")
    nil
  end
end
locations(name = nil) click to toggle source

Defaults for projects in this language

# File lib/cutting_edge/langs/python.rb, line 25
def locations(name = nil)
  ['requirements.txt', 'Pipfile']
end
parse_file(name, content) click to toggle source

Parse a dependency file

name - String contents of the file content - String contents of the file

Returns an Array of tuples of each dependency and its latest version: [[<Gem::Dependency>, <Gem::Version>]]

# File lib/cutting_edge/langs/python.rb, line 39
def parse_file(name, content)
  return nil unless content
  if name =~ /\.txt$/
    results = parse_requirements(content)
  elsif name =~ /Pipfile/
    results = parse_toml(content, PIPFILE_SECTIONS)
  end
  dependency_with_latest(results) if results
end
parse_requirements(content) click to toggle source
# File lib/cutting_edge/langs/python.rb, line 49
def parse_requirements(content)
  results = []
  content.each_line do |line|
    next if line =~ /^\s*-e/ # ignore 'editable' dependencies
    if line =~ COMPARATORS
      next unless match = line.match(REGEX) # Skip this line if it doesn't conform to our expectations
      name, first_comp, first_version, _ignore, second_comp, second_version = match.captures
      first_comp = '=' if first_comp == '=='
      second_comp = '=' if second_comp == '=='
      first_comp = '~>' if first_comp == '~='
      dep = Gem::Dependency.new(name.strip, "#{first_comp} #{first_version}")
      dep.requirement.concat(["#{second_comp} #{second_version}"]) if second_comp && second_version
    else
      dep = Gem::Dependency.new(line.strip) # requries version to be >= 0
    end
    results << dep
  end
  results
end
translate_requirement(req) click to toggle source

Translate version requirement syntax for Pipfiles to a String or Array of Strings that Gem::Dependency.new understands Pipfile support * and != requirements, which Ruby does not See www.python.org/dev/peps/pep-0440/#version-matching

req - String version requirement

Returns a translated String version requirement

# File lib/cutting_edge/langs/python.rb, line 92
def translate_requirement(req)
req.sub!('~=', '~>')
req.sub!('==', '=')
  case req
  when /\*/
    translate_wildcard(req)
  when '!='
    req.sub!('!=', '')
    ["< #{req}", "> #{req}"]
  else
    req
  end
end
website(name) click to toggle source
# File lib/cutting_edge/langs/python.rb, line 29
def website(name)
  "https://pypi.org/project/#{name}"
end