Skip to content

Fix dependency filtering and require pip 20.3 for inspection - #909

Open
tdstein wants to merge 14 commits into
mainfrom
symphony/posit-dev_rsconnect-python_899-38c6ab791ff8ed78
Open

tdstein wants to merge 14 commits into
mainfrom
symphony/posit-dev_rsconnect-python_899-38c6ab791ff8ed78

Conversation

@tdstein

@tdstein tdstein commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Requirement filtering matched any line containing rsconnect, and local editables were bundled even though Connect can't install them.

 pip_freeze
+  if pip < 20.3: error -> upgrade pip or supply a requirements file
-  pip freeze
+  pip freeze --exclude rsconnect --exclude rsconnect-python

 filter requirements (generated and user-supplied)
-  drop every line containing "rsconnect"
+  drop only the rsconnect / rsconnect-python distributions
+    (parsed name, #egg= name, or an editable pointing at this checkout)

 detect_environment
+  reject editables outside the deployment directory
+    (absolute paths, file: URLs, ../ escapes)
+  allow VCS editables and relative paths inside the deployment directory

Evidence

  • Before: my-rsconnect-utils==0.1 and demo @ file:///work/rsconnect-demo were silently dropped. -e /Users/me/localpkg was bundled and failed on Connect.
    After: Unrelated packages are kept. Local editables fail during inspection, and the error lists each offending line.
  • New tests cover name filtering, editable classification, and the old-pip error. The opt-in test_pip_compatibility.py passed against pip 20.2.4, 20.3, and 26.3.
  • CI is green (27/27 checks).

Merge Danger

Door: two-way

Publishing environments with pip < 20.3 can no longer generate requirements. They can upgrade pip or supply a requirements file. Connect's installer is unaffected. Deploys that used to upload unreachable editables now fail early instead of on the server.

Blast Radius: deployments

Closes #899
Closes #916

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://posit-dev.github.io/rsconnect-python/pr-preview/pr-909/

Built to branch gh-pages at 2026-11-05 18:38 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
11082 9783 88% 0% 🟢

New Files

No new covered files...

Modified Files

File Coverage Status
rsconnect/subprocesses/inspect_environment.py 93% 🟢
TOTAL 93% 🟢

updated for commit: 019dbd3 by action🐍

@tdstein
tdstein enabled auto-merge (squash) October 28, 2026 17:14

@joshyam-k joshyam-k left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so if I understand this correctly, previously a local editable install made the Connect build fail with a clear error. Now the line is removed, so the build succeeds and the content fails later with an ImportError at runtime. Is that behavior really better?

@tdstein tdstein changed the title Fix requirement filtering for local editable installs fix: correct filtering of generated requirements Oct 28, 2026
@tdstein

tdstein commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator Author

so if I understand this correctly, previously a local editable install made the Connect build fail with a clear error. Now the line is removed, so the build succeeds and the content fails later with an ImportError at runtime. Is that behavior really better?

Yeah I agree with your assessment. If the dependency isn't resolvable on Connect, then it should fail-fast. There are types of editable installs which can be resolved on Connect. Such as, git+http references, and local directly resolutions. We should allow those deps and should error when the dep isn't resolvable.

@tdstein tdstein changed the title fix: correct filtering of generated requirements fix: handle rsconnect and local editable requirements Oct 29, 2026
Comment thread docs/CHANGELOG.md Resolved
@tdstein tdstein changed the title fix: handle rsconnect and local editable requirements Fix pip freeze requirement filtering Oct 29, 2026
tdstein and others added 2 commits October 29, 2026 13:49
Parse requirement names with packaging instead of regexes, and classify
editable targets with urlsplit. Editable installs of rsconnect-python
itself are dropped like other rsconnect-python requirements.

Editables are now checked for every requirements source, including
user-provided files. Absolute paths, file: URLs, and relative paths that
leave the deployment directory raise an error; relative paths inside the
bundle, such as uv workspace members, are allowed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tdstein
tdstein requested a review from joshyam-k October 29, 2026 18:12
requirement = Requirement(line.strip())
except InvalidRequirement:
return False
return canonicalize_name(requirement.name) == "rsconnect-python"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not have a list of packages to expunge instead of a if and helper for each one?

Also this seems now wrong because we publish this package both as rsconnect and rsconnect-python so now the rsconnect dependency would slip throw

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Addressed:

  • There's now a single excluded_distributions = {"rsconnect", "rsconnect-python"} set instead of per-package checks. Requirement lines, editable installs, and the pip freeze --exclude arguments all use it (019dbd3).
  • Both published names are filtered, so rsconnect no longer slips through (e89efee). Tests cover rsconnect==…, RSCONNECT @ …, and rsconnect.python, and check that look-alikes such as my-rsconnect-utils are kept.

@tdstein tdstein changed the title Fix pip freeze requirement filtering fix: correct requirement filtering and local editable diagnostics Nov 4, 2026
@tdstein tdstein changed the title fix: correct requirement filtering and local editable diagnostics Fix requirement filtering for local installs Nov 4, 2026
@tdstein
tdstein requested a review from amol- November 4, 2026 19:05
@tdstein tdstein changed the title Fix requirement filtering for local installs Fix dependency filtering and require pip 20.3 for inspection Nov 5, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
from typing import Callable, List, Optional, cast
from urllib.parse import parse_qs, urlsplit

from packaging.requirements import InvalidRequirement, Requirement

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the inspector runs in the users venv so putting things outside of the standard library here could crash the inspection.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be possible to replace the packaging calls with standard library code?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 #889 removes this constraint. The inspector will run on the CLI's own interpreter, where packaging is always installed, and receive the project's interpreter as --python. The project's interpreter only gets asked for three things, and none of them imports rsconnect or its dependencies:

  • its Python version: <python> -I -c "import sys; print(...)"
  • its pip version: <python> -m pip --version (optional; we fall back when pip is missing)
  • its installed packages: <python> -m pip freeze, or uv pip freeze --python <python>

I ran all three in a venv with neither rsconnect nor packaging, and they work. That also fixes the related uv tool install problem, where the project's venv doesn't have rsconnect at all.

Until #889 lands, the risk from this PR is small. The inspector runs as <python> -m rsconnect..., so rsconnect must already be installed there. packaging is a declared dependency of the released 1.32.0, so a normal install already brings it along. The only setups that newly break are rsconnect importable without its dependencies (--no-deps, PYTHONPATH, a source checkout) on Python ≥ 3.11. On Python ≤ 3.10 the inspector already fails there on toml. Given that, I'd rather keep packaging than write stdlib code to parse requirements.

…connect-python_899-38c6ab791ff8ed78

# Conflicts:
#	docs/CHANGELOG.md

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants