Strict dependencies allows binary packages for indirect dependencies
Metadata
Current evaluation
Strict-mode dependency handling was fixed by PR #1728 (c3b69774), with follow-up PR #1740 (55434e07) blocking indirect binary packages by default.
Resolution: closed resolved
Reason: The issue was resolved by PR #1728, followed by merged PR #1740 at commit 55434e07, which applies --no-binary=:all: when possible so undeclared indirect dependencies cannot silently use wheels.
Evaluated by: mr-cal-bot
No scores available.
Issue body
### Bug Description
`charm-strict-dependencies: true` changes the behavior of `charm-binary-python-packages` ([source](https://discourse.charmhub.io/t/upcoming-charmcraft-changes-and-a-call-for-testers/12175))
If requirements.txt does not contain all dependencies (e.g. it contains `ops` but not `pyyaml`, which is a dependency of `ops`), indirect dependencies (e.g. `pyyaml`) will be installed from binary wheels instead of from source—even if they are not specified in `charm-binary-python-packages`
This is because charmcraft uses `pip install --no-binary` with a list of package names in requirements.txt
To solve this, charmcraft should use `pip install --no-binary :all: --only-binary` with a list of package names in `charm-binary-python-packages` (allowlist binary packages instead of blocklist source packages, since not all packages are necessarily in requirements.txt). Note that **order matters**
### To Reproduce
```
python3 -m venv venv3
source venv3/bin/activate
pip install ops --no-binary ops
```
### Environment
N/A
### charmcraft.yaml
```shell
N/A
```
### Relevant log output
```shell
ubuntu@j31-3:~$ python3 -m venv venv3
ubuntu@j31-3:~$ source venv3/bin/activate
(venv3) ubuntu@j31-3:~$ pip install ops --no-binary ops
Collecting ops
Downloading ops-2.9.0.tar.gz (255 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 255.8/255.8 KB 3.1 MB/s eta 0:00:00
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Collecting PyYAML==6.*
Downloading PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (705 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 705.5/705.5 KB 38.4 MB/s eta 0:00:00
Collecting websocket-client==1.*
Downloading websocket_client-1.7.0-py3-none-any.whl (58 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 58.5/58.5 KB 11.2 MB/s eta 0:00:00
Building wheels for collected packages: ops
Building wheel for ops (pyproject.toml) ... done
Created wheel for ops: filename=ops-2.9.0-py3-none-any.whl size=153069 sha256=4962af468d3e4794aab1fe44b2c69890d9b3adc4e3d9e1b154dd8bbbb212f4d4
Stored in directory: /home/ubuntu/.cache/pip/wheels/a9/87/9f/a3316be80c2829313331b849dd89a0f5eff5673a67a52b386d
Successfully built ops
Installing collected packages: websocket-client, PyYAML, ops
Successfully installed PyYAML-6.0.1 ops-2.9.0 websocket-client-1.7.0
(venv3) ubuntu@j31-3:~$ deactivate
ubuntu@j31-3:~$ python3 -m venv venv4
ubuntu@j31-3:~$ source venv4/bin/activate
(venv4) ubuntu@j31-3:~$ pip install ops --no-binary :all: --only-binary websocket-client
Collecting ops
Using cached ops-2.9.0.tar.gz (255 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Collecting websocket-client==1.*
Using cached websocket_client-1.7.0-py3-none-any.whl (58 kB)
Collecting PyYAML==6.*
Using cached PyYAML-6.0.1.tar.gz (125 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: ops, PyYAML
Building wheel for ops (pyproject.toml) ... done
Created wheel for ops: filename=ops-2.9.0-py3-none-any.whl size=153069 sha256=1a128b785e34dceab8d3b7c1a67e00f81e325cca5828b4ee84d87c880e272f86
Stored in directory: /home/ubuntu/.cache/pip/wheels/a9/87/9f/a3316be80c2829313331b849dd89a0f5eff5673a67a52b386d
Building wheel for PyYAML (pyproject.toml) ... done
Created wheel for PyYAML: filename=PyYAML-6.0.1-cp310-cp310-linux_x86_64.whl size=45360 sha256=112934fbc8667a9e61883db5bff2cab57f3fbda7e15741578df5c98be8100ae3
Stored in directory: /home/ubuntu/.cache/pip/wheels/31/d1/78/088142cfc0422adcca7bb0af40ef696b55b777a44f2e10739c
Successfully built ops PyYAML
Installing collected packages: websocket-client, PyYAML, ops
Successfully installed PyYAML-6.0.1 ops-2.9.0 websocket-client-1.7.0
(venv4) ubuntu@j31-3:~$ deactivate
ubuntu@j31-3:~$ python3 -m venv venv5
ubuntu@j31-3:~$ source venv5/bin/activate
(venv5) ubuntu@j31-3:~$ pip install ops --only-binary websocket-client --no-binary :all:
Collecting ops
Using cached ops-2.9.0.tar.gz (255 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Collecting PyYAML==6.*
Using cached PyYAML-6.0.1.tar.gz (125 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Collecting websocket-client==1.*
Downloading websocket-client-1.7.0.tar.gz (54 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.0/54.0 KB 1.9 MB/s eta 0:00:00
Preparing metadata (setup.py) ... done
Skipping wheel build for websocket-client, due to binaries being disabled for it.
Building wheels for collected packages: ops, PyYAML
Building wheel for ops (pyproject.toml) ... done
Created wheel for ops: filename=ops-2.9.0-py3-none-any.whl size=153069 sha256=9b6992b436b4be1ea685e53a257e3aef43410d259d08f584855e7b2bbef74946
Stored in directory: /home/ubuntu/.cache/pip/wheels/a9/87/9f/a3316be80c2829313331b849dd89a0f5eff5673a67a52b386d
Building wheel for PyYAML (pyproject.toml) ... done
Created wheel for PyYAML: filename=PyYAML-6.0.1-cp310-cp310-linux_x86_64.whl size=45360 sha256=c25a49eb3e7e60d13a6424662d8087ea7ec5c7cbe740e0cab842c7bad7e58fdf
Stored in directory: /home/ubuntu/.cache/pip/wheels/31/d1/78/088142cfc0422adcca7bb0af40ef696b55b777a44f2e10739c
Successfully built ops PyYAML
Installing collected packages: websocket-client, PyYAML, ops
Running setup.py install for websocket-client ... done
Successfully installed PyYAML-6.0.1 ops-2.9.0 websocket-client-1.7.0
```
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| stealth/space-bunny-alpha | — | closed resolved | Strict-mode dependency handling was fixed by PR #1728 (c3b69774), with follow-up PR #1740 (55434e07) blocking indirect binary packages by default. | |
| stealth/space-bunny-alpha | — | closed resolved | Fixed by #1728 (c3b69774), with follow-up #1740 (55434e07) making strict mode block binary indirect dependencies by default. | |
| stealth/space-bunny-alpha | — | closed resolved | Fixed by PR #1728 (c3b69774), with follow-up PR #1740 (55434e07) ensuring strict mode blocks indirect binary packages by default. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Closed with a resolution to enforce strict mode via --no-dependencies, targeting v3.1. A v2.x warning will prevent indirect dependencies from silently using binary wheels. | |
| qwen/qwen3.6-35b-a3b | — | — | Fixed by switching pip commands to use --no-dependencies in strict mode, preventing unintended binary installations for indirect dependencies. The change was merged to enforce strict source-only builds. | |
| qwen/qwen3.6-35b-a3b | — | — | Closed. Agreed resolution uses --no-dependencies in strict mode to block indirect binary installs, planned for v3.1. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Closed after agreeing to use --no-dependencies for strict mode. No further activity confirms implementation, indicating the issue remains unresolved or was abandoned. |
Update history
No update history recorded yet.
Related work
-
Likely Fixed By:
canonical/charmcraft#1728
(confidence 100%)
Primary resolving PR, associated with commit c3b69774.
-
Likely Fixed By:
canonical/charmcraft#1740
(confidence 100%)
Follow-up fix merged as commit 55434e07; sets --no-binary=:all: when possible.
Related issues
No related issues found above the similarity threshold.