Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dependencies = [
"faiss-cpu>=1.12.0",
"filelock>=3.18.0",
"google-genai>=1.56.0",
"httpx[socks]>=0.28.1",
"lark-oapi>=1.4.15",
"lxml-html-clean>=0.4.2",
"mcp>=1.8.0",
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ docstring-parser>=0.16
faiss-cpu>=1.12.0
filelock>=3.18.0
google-genai>=1.56.0
httpx[socks]>=0.28.1
lark-oapi>=1.4.15
lxml-html-clean>=0.4.2
mcp>=1.8.0
Expand Down
113 changes: 113 additions & 0 deletions tests/test_httpx_socks_dependency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import re
from pathlib import Path

import pytest
import tomllib

PROJECT_ROOT = Path(__file__).resolve().parents[1]
REQUIREMENTS_PATH = PROJECT_ROOT / "requirements.txt"
PYPROJECT_PATH = PROJECT_ROOT / "pyproject.toml"
HTTPX_SOCKS_PATTERN = re.compile(r"^httpx\[socks\](?:\s*[<>=!~][^;]*)?(?:\s*;.*)?$")


def _read_httpx_socks_dependency(entries: list[str]) -> str | None:
Comment on lines +10 to +13
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.

suggestion (testing): Add negative tests to ensure the pattern does not match non-SOCKS httpx dependencies or malformed entries.

Currently we only verify that HTTPX_SOCKS_PATTERN matches a valid httpx[socks] requirement. Please also add assertions that it does not match invalid cases such as httpx, httpx[http2], httpx[socks-extra], and entries with extra leading/trailing text, so future regex changes that are too broad are caught by tests.

Suggested change
HTTPX_SOCKS_PATTERN = re.compile(r"^httpx\[socks\](?:\s*[<>=!~][^;]*)?(?:\s*;.*)?$")
def _read_httpx_socks_dependency(entries: list[str]) -> str | None:
HTTPX_SOCKS_PATTERN = re.compile(r"^httpx\[socks\](?:\s*[<>=!~][^;]*)?(?:\s*;.*)?$")
def test_httpx_socks_pattern_matches_valid_entries() -> None:
valid_entries = [
"httpx[socks]",
"httpx[socks]==0.27.0",
"httpx[socks]>=0.27.0,<0.28.0",
'httpx[socks]>=0.27.0 ; python_version < "3.13"',
'httpx[socks] ; python_version < "3.13"',
]
for entry in valid_entries:
match = HTTPX_SOCKS_PATTERN.match(entry)
assert match is not None, f"Expected pattern to match valid entry: {entry}"
assert match.group(0) == entry
def test_httpx_socks_pattern_does_not_match_invalid_entries() -> None:
invalid_entries = [
"httpx",
"httpx==0.27.0",
"httpx[http2]",
"httpx[socks-extra]",
"httpx [socks]",
"someprefix httpx[socks]",
"httpx[socks] trailing-text",
"httpx[socks] extra ; markers",
"httpx[socks]andmore",
]
for entry in invalid_entries:
assert HTTPX_SOCKS_PATTERN.match(entry) is None, (
f"Expected pattern not to match invalid entry: {entry}"
)
def _read_httpx_socks_dependency(entries: list[str]) -> str | None:

for entry in entries:
candidate = entry.strip()
if HTTPX_SOCKS_PATTERN.match(candidate):
return candidate
return None


def _read_requirements() -> list[str]:
entries = []
for line in REQUIREMENTS_PATH.read_text(encoding="utf-8").splitlines():
candidate = line.split("#", 1)[0].strip()
if candidate:
entries.append(candidate)
return entries


def _read_pyproject_dependencies() -> list[str]:
with PYPROJECT_PATH.open("rb") as file:
pyproject = tomllib.load(file)
return pyproject["project"]["dependencies"]
Comment on lines +30 to +33
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.

issue (testing): The test only checks presence in project.dependencies, not alignment between requirements.txt and pyproject.toml (e.g. version specifiers).

Right now the tests only assert that each file independently contains httpx[socks]. A change like httpx[socks]==1.0.0 in one file and httpx[socks]>=1.0.0 in the other would still pass. Please add a test that compares the httpx[socks] spec from both files and asserts they are identical (or otherwise compatible under the alignment rule you intend to enforce).



def test_requirements_include_httpx_socks_dependency() -> None:
requirements_dependency = _read_httpx_socks_dependency(_read_requirements())

assert requirements_dependency is not None, (
"Expected httpx[socks] dependency in requirements.txt for SOCKS proxy support"
)


def test_pyproject_declares_httpx_socks_dependency() -> None:
pyproject_dependency = _read_httpx_socks_dependency(_read_pyproject_dependencies())

assert pyproject_dependency is not None, (
"Expected httpx[socks] dependency in pyproject.toml for SOCKS proxy support"
)


def test_httpx_socks_dependency_spec_matches_between_dependency_files() -> None:
requirements_dependency = _read_httpx_socks_dependency(_read_requirements())
pyproject_dependency = _read_httpx_socks_dependency(_read_pyproject_dependencies())

assert requirements_dependency is not None, (
"Expected httpx[socks] dependency in requirements.txt for SOCKS proxy support"
)
assert pyproject_dependency is not None, (
"Expected httpx[socks] dependency in pyproject.toml for SOCKS proxy support"
)
assert requirements_dependency == pyproject_dependency, (
"Expected httpx[socks] dependency spec to match between requirements.txt "
"and pyproject.toml for SOCKS proxy support"
)


@pytest.mark.parametrize(
"entry",
[
"httpx[socks]",
"httpx[socks]==0.27.0",
"httpx[socks]==0.28.1",
"httpx[socks]>=0.27.0,<0.28.0",
"httpx[socks]>=0.27,<0.29",
'httpx[socks]; python_version >= "3.11"',
'httpx[socks]>=0.27.0 ; python_version < "3.13"',
'httpx[socks] ; python_version < "3.13"',
'httpx[socks] >=0.27 ; python_version < "3.13"',
],
)
def test_httpx_socks_pattern_matches_valid_variants(entry: str) -> None:
match = HTTPX_SOCKS_PATTERN.match(entry)

assert match is not None, (
f"Expected httpx[socks] dependency pattern to match valid entry for "
f"SOCKS proxy support: {entry}"
)
assert match.group(0) == entry, (
f"Expected httpx[socks] dependency pattern to fully match valid entry "
f"for SOCKS proxy support: {entry}"
)


@pytest.mark.parametrize(
"entry",
[
"httpx",
"httpx==0.27.0",
"httpx[http2]",
"httpx[socks-extra]",
"httpx [socks]",
"someprefix httpx[socks]",
"httpx[socks] trailing-text",
"httpx[socks] extra ; markers",
"httpx[socks]andmore",
],
)
def test_httpx_socks_pattern_rejects_invalid_variants(entry: str) -> None:
assert HTTPX_SOCKS_PATTERN.match(entry) is None, (
f"Expected httpx[socks] dependency pattern to reject invalid entry for "
f"SOCKS proxy support: {entry}"
)
Loading