Class: Language::Python::Virtualenv::Virtualenv Private

Inherits:
Object
  • Object
show all
Defined in:
language/python.rb

Overview

This class is part of a private API. This class may only be used in the Homebrew/brew repository. Third parties should avoid using this class if possible, as it may be removed or changed without warning.

Convenience wrapper for creating and installing packages into Python virtualenvs.

Instance Method Summary collapse

Constructor Details

#initialize(formula, venv_root, python) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Initializes a Virtualenv instance. This does not create the virtualenv on disk; #create does that.

Parameters:



340
341
342
343
344
# File 'language/python.rb', line 340

def initialize(formula, venv_root, python)
  @formula = formula
  @venv_root = T.let(Pathname(venv_root), Pathname)
  @python = python
end

Instance Method Details

#create(system_site_packages: true, without_pip: true) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.

Obtains a copy of the virtualenv library and creates a new virtualenv on disk.

Parameters:

  • system_site_packages (Boolean) (defaults to: true)
  • without_pip (Boolean) (defaults to: true)


360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# File 'language/python.rb', line 360

def create(system_site_packages: true, without_pip: true)
  return if (@venv_root/"bin/python").exist?

  args = ["-m", "venv"]
  args << "--system-site-packages" if system_site_packages
  args << "--without-pip" if without_pip
  @formula.system @python, *args, @venv_root

  # Robustify symlinks to survive python patch upgrades
  @venv_root.find do |f|
    next unless f.symlink?
    next unless f.readlink.expand_path.to_s.start_with? HOMEBREW_CELLAR

    rp = f.realpath.to_s
    version = rp.match %r{^#{HOMEBREW_CELLAR}/python@(.*?)/}o
    version = "@#{version.captures.first}" unless version.nil?

    new_target = rp.sub(
      %r{#{HOMEBREW_CELLAR}/python#{version}/[^/]+},
      Utils::Path.formula_opt_prefix("python#{version}").to_s,
    )
    f.unlink
    f.make_symlink new_target
  end

  Pathname.glob(@venv_root/"lib/python*/orig-prefix.txt").each do |prefix_file|
    prefix_path = prefix_file.read

    version = prefix_path.match %r{^#{HOMEBREW_CELLAR}/python@(.*?)/}o
    version = "@#{version.captures.first}" unless version.nil?

    prefix_path.sub!(
      %r{^#{HOMEBREW_CELLAR}/python#{version}/[^/]+},
      Utils::Path.formula_opt_prefix("python#{version}").to_s,
    )
    prefix_file.atomic_write prefix_path
  end

  # Reduce some differences between macOS and Linux venv
  lib64 = @venv_root/"lib64"
  lib64.make_symlink "lib" unless lib64.exist?
  if (cfg_file = @venv_root/"pyvenv.cfg").exist?
    cfg = cfg_file.read
    framework = "Frameworks/Python.framework/Versions"
    match = cfg.match(%r{= *(#{HOMEBREW_CELLAR}/(python@[\d.]+)/[^/]+(?:/#{framework}/[\d.]+)?/bin)})
    if match && (python_formula = match[2])
      cfg.sub! match[1].to_s, Utils::Path.formula_opt_bin(python_formula).to_s
      cfg_file.atomic_write cfg
    end
  end

  # Remove unnecessary activate scripts
  (@venv_root/"bin").glob("[Aa]ctivate*").map(&:unlink)
end

#pip_install(targets, build_isolation: true) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.

Installs packages represented by targets into the virtualenv.

Parameters:

  • targets (String, Pathname, Resource, Array<String, Pathname, Resource>)

    (A) token(s) passed to pip representing the object to be installed. This can be a directory containing a setup.py, a Resource which will be staged and installed, or a package identifier to be fetched from PyPI. Multiline strings are allowed and treated as though they represent the contents of a requirements.txt.

  • build_isolation (Boolean) (defaults to: true)


431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
# File 'language/python.rb', line 431

def pip_install(targets, build_isolation: true)
  targets = Array(targets)
  targets.each do |t|
    if t.is_a?(Resource)
      t.stage do
        target = Pathname.pwd
        target /= t.downloader.basename if t.url&.match?("[.-]py3[^-]*-none-any.whl$")
        do_install(target, build_isolation:)
      end
    else
      t = t.lines.map(&:strip) if t.is_a?(String) && t.include?("\n")
      do_install(t, build_isolation:)
    end
  end
end

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.

Installs packages represented by targets into the virtualenv, but unlike #pip_install also links new scripts to Formula#bin.

Parameters:



459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# File 'language/python.rb', line 459

def pip_install_and_link(targets, link_manpages: true, build_isolation: true)
  bin_before = Dir[@venv_root/"bin/*"].to_set
  man_before = Dir[@venv_root/"share/man/man*/*"].to_set if link_manpages

  pip_install(targets, build_isolation:)

  bin_after = Dir[@venv_root/"bin/*"].to_set
  bin_to_link = (bin_after - bin_before).to_a
  @formula.bin.install_symlink(bin_to_link)
  return unless link_manpages

  man_after = Dir[@venv_root/"share/man/man*/*"].to_set
  man_to_link = (man_after - man_before).to_a
  man_to_link.each do |manpage|
    (@formula.man/Pathname.new(manpage).dirname.basename).install_symlink manpage
  end
end

#rootPathname

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



347
348
349
# File 'language/python.rb', line 347

def root
  @venv_root
end

#site_packagesPathname

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



352
353
354
# File 'language/python.rb', line 352

def site_packages
  @venv_root/Language::Python.site_packages(@python)
end