Skip to content

Commit

Permalink
Consistently use lowercase "pip" (#242)
Browse files Browse the repository at this point in the history
Since the upstream name of the project is all lowercase.

See:
https://pip.pypa.io
pypa/pip#7793
  • Loading branch information
edmorley authored Aug 7, 2024
1 parent 1b30ed1 commit 1ee3732
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 36 deletions.
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Stopped manually creating a `src` directory inside the Pip dependencies layer. Pip will create the directory itself if needed (when there are editable VCS dependencies). ([#228](https://github.com/heroku/buildpacks-python/pull/228))
- Stopped manually creating a `src` directory inside the pip dependencies layer. pip will create the directory itself if needed (when there are editable VCS dependencies). ([#228](https://github.com/heroku/buildpacks-python/pull/228))
- Stopped setting `CPATH` and `PKG_CONFIG_PATH` at launch time. ([#231](https://github.com/heroku/buildpacks-python/pull/231))
- The `bin` directory in the Pip dependencies layer is now always added to `PATH` instead of only when an installed dependency has an entry point script. ([#232](https://github.com/heroku/buildpacks-python/pull/232))
- The Pip cache layer is now exposed to Pip invocations in later buildpacks. ([#234](https://github.com/heroku/buildpacks-python/pull/234))
- The `bin` directory in the pip dependencies layer is now always added to `PATH` instead of only when an installed dependency has an entry point script. ([#232](https://github.com/heroku/buildpacks-python/pull/232))
- The pip cache layer is now exposed to pip invocations in later buildpacks. ([#234](https://github.com/heroku/buildpacks-python/pull/234))

## [0.12.1] - 2024-07-15

Expand Down
2 changes: 1 addition & 1 deletion src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn on_determine_package_manager_error(error: DeterminePackageManagerError) {
DeterminePackageManagerError::NoneFound => log_error(
"No Python package manager files were found",
indoc! {"
A Pip requirements file was not found in your application's source code.
A pip requirements file was not found in your application's source code.
This file is required so that your application's dependencies can be installed.
Please add a file named exactly 'requirements.txt' to the root directory of your
Expand Down
2 changes: 1 addition & 1 deletion src/layers/pip_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use libcnb::Env;
use libherokubuildpack::log::log_info;
use serde::{Deserialize, Serialize};

/// Creates a build-only layer for Pip's cache of HTTP requests/downloads and built package wheels.
/// Creates a build-only layer for pip's cache of HTTP requests/downloads and built package wheels.
// See: https://pip.pypa.io/en/stable/topics/caching/
pub(crate) fn prepare_pip_cache(
context: &BuildContext<PythonBuildpack>,
Expand Down
14 changes: 7 additions & 7 deletions src/layers/pip_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@ use libherokubuildpack::log::log_info;
use std::path::{Path, PathBuf};
use std::process::Command;

/// Creates a layer containing the application's Python dependencies, installed using Pip.
/// Creates a layer containing the application's Python dependencies, installed using pip.
//
// To do this we use `pip install --user` so that the dependencies are installed into the user
// `site-packages` directory in this layer (set by `PYTHONUSERBASE`), rather than the system
// `site-packages` subdirectory of the Python installation layer.
//
// Note: We can't instead use Pip's `--target` option along with `PYTHONPATH`, since:
// Note: We can't instead use pip's `--target` option along with `PYTHONPATH`, since:
// - Directories on `PYTHONPATH` take precedence over the Python stdlib (unlike the system or
// user site-packages directories), which can cause hard to debug stdlib shadowing issues
// if one of the app's transitive dependencies is an outdated stdlib backport package.
// - `--target` has bugs, eg: <https://github.com/pypa/pip/issues/8799>
//
// This layer is not cached, since:
// - Pip is a package installer rather than a project/environment manager, and so does not
// - pip is a package installer rather than a project/environment manager, and so does not
// deterministically manage installed Python packages. For example, if a package entry in
// a requirements file is later removed, Pip will not uninstall the package. In addition,
// a requirements file is later removed, pip will not uninstall the package. In addition,
// there is no official lockfile support, so changes in transitive dependencies add yet
// more opportunity for non-determinism between each install.
// - The Pip HTTP/wheel cache is itself cached in a separate layer (exposed via `PIP_CACHE_DIR`),
// - The pip HTTP/wheel cache is itself cached in a separate layer (exposed via `PIP_CACHE_DIR`),
// which covers the most time consuming part of performing a pip install: downloading the
// dependencies and then generating wheels for any packages that don't provide them.
pub(crate) fn install_dependencies(
Expand Down Expand Up @@ -62,7 +62,7 @@ pub(crate) fn install_dependencies(
"requirements.txt",
// For VCS dependencies installed in editable mode, the repository clones must be
// kept after installation, since their directories are added to the Python path
// directly (via `.pth` files in `site-packages`). By default Pip will store the
// directly (via `.pth` files in `site-packages`). By default pip will store the
// repositories in the current working directory (the app dir), but we want them
// in the dependencies layer instead.
"--src",
Expand Down Expand Up @@ -103,7 +103,7 @@ fn generate_layer_env(layer_path: &Path) -> LayerEnv {
)
}

/// Errors that can occur when installing the project's dependencies into a layer using Pip.
/// Errors that can occur when installing the project's dependencies into a layer using pip.
#[derive(Debug)]
pub(crate) enum PipDependenciesLayerError {
PipInstallCommand(StreamedCommandError),
Expand Down
26 changes: 13 additions & 13 deletions src/layers/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ pub(crate) fn install_python_and_packaging_tools(
python_version.major, python_version.minor
));

// Python bundles Pip within its standard library, which we can use to install our chosen
// Python bundles pip within its standard library, which we can use to install our chosen
// pip version from PyPI, saving us from having to download the usual pip bootstrap script.
let bundled_pip_module_path =
bundled_pip_module_path(&python_stdlib_dir).map_err(PythonLayerError::LocateBundledPip)?;
Expand All @@ -136,7 +136,7 @@ pub(crate) fn install_python_and_packaging_tools(
.args([
&bundled_pip_module_path.to_string_lossy(),
"install",
// There is no point using Pip's cache here, since the layer itself will be cached.
// There is no point using pip's cache here, since the layer itself will be cached.
"--no-cache-dir",
"--no-input",
"--quiet",
Expand All @@ -150,11 +150,11 @@ pub(crate) fn install_python_and_packaging_tools(
)
.map_err(PythonLayerError::BootstrapPipCommand)?;

// By default Pip installs into the system site-packages directory if it is writeable by the
// By default pip installs into the system site-packages directory if it is writeable by the
// current user. Whilst the buildpack's own `pip install` invocations always use `--user` to
// ensure app dependencies are installed into the user site-packages, it's possible other
// buildpacks or custom scripts may forget to do so. By making the system site-packages
// directory read-only, Pip will automatically use user installs in such cases:
// directory read-only, pip will automatically use user installs in such cases:
// https://github.com/pypa/pip/blob/24.1.2/src/pip/_internal/commands/install.py#L662-L720
let site_packages_dir = python_stdlib_dir.join("site-packages");
fs::set_permissions(site_packages_dir, Permissions::from_mode(0o555))
Expand Down Expand Up @@ -276,7 +276,7 @@ fn generate_layer_env(layer_path: &Path, python_version: &PythonVersion) -> Laye
"LANG",
"C.UTF-8",
)
// We use a curated Pip version, so disable the update check to speed up Pip invocations,
// We use a curated pip version, so disable the update check to speed up pip invocations,
// reduce build log spam and prevent users from thinking they need to manually upgrade.
// This uses an env var (rather than the `--disable-pip-version-check` arg) so that it also
// takes effect for any pip invocations in later buildpacks or when debugging at run-time.
Expand Down Expand Up @@ -324,7 +324,7 @@ fn generate_layer_env(layer_path: &Path, python_version: &PythonVersion) -> Laye
// By default, Python's cached bytecode files (`.pyc` files) embed the last-modified time of
// their `.py` source file, so Python can determine when they need regenerating. This causes
// `.pyc` files (and thus layer SHA256) to be non-deterministic in cases where the source
// file's last-modified time can vary (such as for packages installed by Pip). In addition,
// file's last-modified time can vary (such as for packages installed by pip). In addition,
// when lifecycle exports layers it resets the timestamps on all files to a fixed value:
// https://buildpacks.io/docs/features/reproducibility/#consequences-and-caveats
//
Expand All @@ -351,13 +351,13 @@ fn generate_layer_env(layer_path: &Path, python_version: &PythonVersion) -> Laye
// and not `.pyc` generation as part of Python importing a file during normal operation.
//
// We use the env var, since:
// - Pip calls `compileall` itself after installing packages, and doesn't allow us to
// - pip calls `compileall` itself after installing packages, and doesn't allow us to
// customise the options passed to it, which would mean we'd have to pass `--no-compile`
// to Pip followed by running `compileall` manually ourselves, meaning more complexity
// to pip followed by running `compileall` manually ourselves, meaning more complexity
// every time we (or a later buildpack) use `pip install`.
// - When we add support for Poetry, we'll have to use an env var regardless, since Poetry
// doesn't allow customising the options passed to its internal Pip invocations, so we'd
// have no way of passing `--no-compile` to Pip.
// doesn't allow customising the options passed to its internal pip invocations, so we'd
// have no way of passing `--no-compile` to pip.
.chainable_insert(
Scope::Build,
ModificationBehavior::Default,
Expand All @@ -372,18 +372,18 @@ fn generate_layer_env(layer_path: &Path, python_version: &PythonVersion) -> Laye
)
}

/// The path to the Pip module bundled in Python's standard library.
/// The path to the pip module bundled in Python's standard library.
fn bundled_pip_module_path(python_stdlib_dir: &Path) -> io::Result<PathBuf> {
let bundled_wheels_dir = python_stdlib_dir.join("ensurepip/_bundled");

// The wheel filename includes the Pip version (for example `pip-XX.Y-py3-none-any.whl`),
// The wheel filename includes the pip version (for example `pip-XX.Y-py3-none-any.whl`),
// which varies from one Python release to the next (including between patch releases).
// As such, we have to find the wheel based on the known filename prefix of `pip-`.
for entry in fs::read_dir(bundled_wheels_dir)? {
let entry = entry?;
if entry.file_name().to_string_lossy().starts_with("pip-") {
let pip_wheel_path = entry.path();
// The Pip module exists inside the pip wheel (which is a zip file), however,
// The pip module exists inside the pip wheel (which is a zip file), however,
// Python can load it directly by appending the module name to the zip filename,
// as though it were a path. For example: `pip-XX.Y-py3-none-any.whl/pip`
let pip_module_path = pip_wheel_path.join("pip");
Expand Down
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl Buildpack for PythonBuildpack {
// In the future support will be added for package managers other than pip.
let dependencies_layer_dir = match package_manager {
PackageManager::Pip => {
log_header("Installing dependencies using Pip");
log_header("Installing dependencies using pip");
pip_cache::prepare_pip_cache(
&context,
&mut env,
Expand Down Expand Up @@ -112,7 +112,7 @@ pub(crate) enum BuildpackError {
DjangoCollectstatic(DjangoCollectstaticError),
/// IO errors when detecting whether Django is installed.
DjangoDetection(io::Error),
/// Errors installing the project's dependencies into a layer using Pip.
/// Errors installing the project's dependencies into a layer using pip.
PipDependenciesLayer(PipDependenciesLayerError),
/// Errors installing Python and required packaging tools into a layer.
PythonLayer(PythonLayerError),
Expand Down
2 changes: 1 addition & 1 deletion tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn default_build_config(fixture_path: impl AsRef<Path>) -> BuildConfig {
config.target_triple(target_triple);

// Ensure that potentially broken user-provided env vars don't take precedence over those set
// by this buildpack and break running Python/Pip. Some of these are based on the env vars that
// by this buildpack and break running Python/pip. Some of these are based on the env vars that
// used to be set by `bin/release` by very old versions of the classic Python buildpack:
// https://github.com/heroku/heroku-buildpack-python/blob/27abdfe7d7ad104dabceb45641415251e965671c/bin/release#L11-L18
config.envs([
Expand Down
2 changes: 1 addition & 1 deletion tests/package_manager_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn no_package_manager_detected() {
context.pack_stderr,
indoc! {"
[Error: No Python package manager files were found]
A Pip requirements file was not found in your application's source code.
A pip requirements file was not found in your application's source code.
This file is required so that your application's dependencies can be installed.
Please add a file named exactly 'requirements.txt' to the root directory of your
Expand Down
14 changes: 7 additions & 7 deletions tests/pip_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn pip_basic_install_and_cache_reuse() {
Installing Python {DEFAULT_PYTHON_VERSION}
Installing pip {pip_version}, setuptools {setuptools_version} and wheel {wheel_version}
[Installing dependencies using Pip]
[Installing dependencies using pip]
Running pip install
Collecting typing-extensions==4.7.1 (from -r requirements.txt (line 2))
Downloading typing_extensions-4.7.1-py3-none-any.whl.metadata (3.1 kB)
Expand All @@ -39,9 +39,9 @@ fn pip_basic_install_and_cache_reuse() {

// Check that:
// - The correct env vars are set at run-time.
// - Pip is available at run-time too (and not just during the build).
// - pip is available at run-time too (and not just during the build).
// - The correct versions of pip/setuptools/wheel were installed.
// - Pip uses (via 'PYTHONUSERBASE') the user site-packages in the dependencies
// - pip uses (via 'PYTHONUSERBASE') the user site-packages in the dependencies
// layer, and so can find the typing-extensions package installed there.
// - The "pip update available" warning is not shown (since it should be suppressed).
// - The system site-packages directory is protected against running 'pip install'
Expand Down Expand Up @@ -91,7 +91,7 @@ fn pip_basic_install_and_cache_reuse() {
Using cached Python {DEFAULT_PYTHON_VERSION}
Using cached pip {pip_version}, setuptools {setuptools_version} and wheel {wheel_version}
[Installing dependencies using Pip]
[Installing dependencies using pip]
Using cached pip download/wheel cache
Running pip install
Collecting typing-extensions==4.7.1 (from -r requirements.txt (line 2))
Expand Down Expand Up @@ -141,7 +141,7 @@ fn pip_cache_invalidation_with_compatible_metadata() {
Installing Python {DEFAULT_PYTHON_VERSION}
Installing pip {pip_version}, setuptools {setuptools_version} and wheel {wheel_version}
[Installing dependencies using Pip]
[Installing dependencies using pip]
Discarding cached pip download/wheel cache
Running pip install
Collecting typing-extensions==4.7.1 (from -r requirements.txt (line 2))
Expand Down Expand Up @@ -195,7 +195,7 @@ fn pip_cache_invalidation_with_incompatible_metadata() {
Installing Python {DEFAULT_PYTHON_VERSION}
Installing pip {pip_version}, setuptools {setuptools_version} and wheel {wheel_version}
[Installing dependencies using Pip]
[Installing dependencies using pip]
Discarding cached pip download/wheel cache
Running pip install
Collecting typing-extensions==4.7.1 (from -r requirements.txt (line 2))
Expand Down Expand Up @@ -243,7 +243,7 @@ fn pip_install_error() {
assert_contains!(
context.pack_stdout,
indoc! {"
[Installing dependencies using Pip]
[Installing dependencies using pip]
Running pip install
"}
);
Expand Down

0 comments on commit 1ee3732

Please sign in to comment.