Conversation
HTTPS failures on Windows are hard to triage because several unrelated toolchains ship their own libssl-3-x64.dll, and only the one the interpreter actually loaded matters. `specify version` reported Python, Platform, Architecture and OS Version, but nothing about OpenSSL, so answering "which OpenSSL is in use?" required a separate snippet. Add an `OpenSSL` row sourced from ssl.OPENSSL_VERSION. The row is skipped when that attribute is unavailable, so the table degrades rather than erroring. Related to github#4433 - this does not fix the abort, it only makes the runtime visible to whoever triages it.
|
This is a useful, focused diagnostic addition; no need to expand it into DLL enumeration or a fix for the separate crash report. Please complete the AI disclosure with the agent/tool, model(s), and mode/settings used. The extent of assistance is already clear. A PR-description edit is sufficient—no code commit is needed for that. The current CI runs require maintainer approval before final review. Drafted for @mnriem with assistance from GitHub Copilot (model: GPT-6 Astra; interactive comment drafting). |
There was a problem hiding this comment.
🟡 Changes recommended
The SSL import failure path can break commands on interpreters without _ssl.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds OpenSSL runtime reporting to specify version for HTTPS troubleshooting.
Changes:
- Displays
ssl.OPENSSL_VERSIONwhen available. - Adds regression coverage for OpenSSL output.
File summaries
| File | Review |
|---|---|
tests/test_cli_version.py |
Add deterministic version patching and coverage for missing OpenSSL. Nit (1 vote). |
src/specify_cli/__init__.py |
Handle unavailable SSL imports without breaking unrelated output. Critical (2 votes). |
Review details
Suppressed comments (2)
src/specify_cli/init.py:497
- The PR promises that the table degrades when
ssl.OPENSSL_VERSIONis unavailable, but the new regression test only exercises the truthy path. Please add a focused case that patches the attribute to an empty value (or removes it) and assertsspecify versionstill exits successfully without anOpenSSLrow, so this fallback cannot regress unnoticed.
openssl_version = getattr(ssl, "OPENSSL_VERSION", "")
if openssl_version:
tests/test_cli_version.py:97
- This test only reads the host's
ssl.OPENSSL_VERSION, so it exercises the truthy row and fails at the test attribute access on the environment where the documented fallback is needed. Add a companion case that patches or removes this attribute and asserts the command still succeeds without an OpenSSL row, while keeping this positive case deterministic with a patched version string.
expected = ssl.OPENSSL_VERSION
assert expected, "test host reports no ssl.OPENSSL_VERSION to assert against"
assert expected in result.output
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite (auto)
Note
Copilot is running an experiment and ran this review at Lite.
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| ): | ||
| """Display version and system information.""" | ||
| import platform | ||
| import ssl |
The eager `import ssl` ran before the --features/--json early returns, so an interpreter without _ssl failed `specify version` outright — including the feature surface that never needed ssl. Import it lazily at the point of use and treat ImportError as an empty OpenSSL value so the row is skipped as documented. Adds regression tests covering both paths.
|
Done — AI disclosure completed in the PR description (agent/tool: Devin CLI; model: SWE-2 High; mode: autonomous terminal session with shell/editor/gh access). I also took care of the Copilot-flagged import ordering while I was here (bfeea28): |
Description
specify versionreported CLI version, Python, Platform, Architecture and OS Version, but nothing about the OpenSSL runtime the interpreter actually loaded.That is the first thing HTTPS triage needs, and on Windows it is genuinely not inferable from outside the process: several unrelated toolchains ship their own
libssl-3-x64.dll(Git for Windows alone has two distinct builds —mingw64\bin\libssl-3-x64.dllandusr\bin\msys-ssl-3.dll), and only the one actually loaded matters.This came out of #4433, where the report is an OpenSSL-level abort (
OPENSSL_Uplink(...): no OPENSSL_Applink) and the working hypothesis is a PATH-preceded OpenSSL DLL. Today, answering "which OpenSSL is in use?" requires the reporter to run a separatepython -csnippet. After this change,specify versionanswers it:The row is skipped when
ssl.OPENSSL_VERSIONis unavailable — including on interpreters built without thesslextension, where the command still succeeds rather than failing onimport ssl.Related to #4433 — this does not fix the abort, it only makes the runtime visible to whoever triages it.
Evidence
New test fails on
main, passes with the change:The +2 tests cover the no-
sslpaths:versionskips the OpenSSL row, andversion --features --jsonnever touchessslat all.Lint matches what CI runs:
Testing
uv run specify --helpuv sync && uv run pytestspecify versiondoes not read a projectOn the second box:
tests/test_cli_version.pypasses (9/9), and thespecify versionCLI surface was exercised directly. I could not complete the full suite on this machine —tests/conftest.pyprobes for a working bash and invokeswsl.exe, which is blocked by my host's security policy, and long runs get cut short. CI will cover the full matrix; I'd rather flag the gap than tick a box I didn't verify.AI Disclosure
I did not use AI assistance for this contribution
I did use AI assistance (describe below)
Agent/tool: Devin CLI — Cognition's interactive command-line agent
Model: SWE-2 High
Mode/settings: normal (autonomous) terminal session on a Linux VM — the agent ran shell commands, edited files, installed the package into a venv, ran pytest/ruff, and used
ghunder my GitHub account. No Devin Cloud web sessions.The agent drafted the change and its tests and ran the local verification shown above; I reviewed the diff and the reported outputs.
Note: why the loaded DLL path is not in this PR
The obvious companion field is the resolved path of the loaded
libssl-3-x64.dll. I left it out on purpose.It would require process-module enumeration, and it only means something once we know a PATH-preceded DLL can be loaded at all — which is exactly what is still unresolved in #4433. On my Windows host,
libssl-3-x64.dllresolves to the interpreter's ownDLLs\directory regardless of what is onPATH(CPython callsSetDefaultDllDirectoriesat startup, bpo-36085, soPATHis no longer part of extension-module resolution). Adding the path now would encode an unverified assumption into the UI.If it turns out to be useful once #4433 is understood, I'm happy to follow up with it as a separate focused change.