Skip to content

fix: Python 3.12+ compatibility (distutils removed)#26

Open
Mounstroya wants to merge 6 commits into
Junyi-99:mainfrom
Mounstroya:fix/python313-distutils
Open

fix: Python 3.12+ compatibility (distutils removed)#26
Mounstroya wants to merge 6 commits into
Junyi-99:mainfrom
Mounstroya:fix/python313-distutils

Conversation

@Mounstroya
Copy link
Copy Markdown

Problem

Two issues when running on Python 3.12+:

  1. Google blocks Selenium's default Chrome driver showing:
    "This browser or app may not be secure"
    This prevents users from logging into GitHub.

  2. Switching to undetected-chromedriver (which fixes the detection)
    causes a secondary error:
    ModuleNotFoundError: No module named 'distutils'
    because distutils was removed in Python 3.12+.

Solution

  • Switched from webdriver.Chrome to uc.Chrome (undetected-chromedriver)
    to bypass Google's bot detection
  • Added setuptools to requirements.txt to restore distutils
    for Python 3.12+ compatibility

Tested on

  • Debian, Python 3.13

@Junyi-99
Copy link
Copy Markdown
Owner

@Mounstroya please update the requirements.txt because you introduced a new package undetected_chromedriver

Mounstroya and others added 2 commits April 13, 2026 11:42
- Split merged `ruff>=0.2.0setuptools` onto separate lines so pip can
  actually parse the file.
- Pin `setuptools<70` — setuptools 70+ dropped the vendored distutils
  shim, so the Py 3.12+ fix only holds below 70.
- Pin `undetected-chromedriver>=3.5.5` for reproducible installs.
- Use `uc.ChromeOptions()` instead of `webdriver.ChromeOptions()` —
  the undetected-chromedriver docs require its own options subclass
  so uc's internal patching is applied.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Junyi-99
Copy link
Copy Markdown
Owner

Hi @Mounstroya, thanks for the PR! I pushed a small follow-up commit (9d3eb37) to address a few issues — feel free to revert if you disagree:

  1. requirements.txt was unparseable. ruff>=0.2.0setuptools was on one line with no newline, so pip install -r requirements.txt would fail. Split into separate lines.

  2. Pinned setuptools<70. setuptools 70 dropped the vendored distutils shim, so a bare setuptools dependency doesn't reliably fix the Py 3.12+ issue on fresh installs — <70 keeps the shim.

  3. Pinned undetected-chromedriver>=3.5.5 for reproducible installs.

  4. uc.ChromeOptions() instead of webdriver.ChromeOptions() at src/main.py:63. undetected-chromedriver ships its own ChromeOptions subclass; using the stock selenium one can cause uc's internal patching (the whole point of using uc) to be bypassed for some flags.

Let me know if anything looks off.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Junyi-99
Copy link
Copy Markdown
Owner

Hi @Mounstroya, thanks again for the PR. I tested the branch locally (macOS, Python 3.13, Chrome 147.0.7727.56) and hit a blocker:

selenium.common.exceptions.NoSuchWindowException: no such window: target window already closed
from unknown error: web view not found
  (Session info: chrome=147.0.7727.56)

uc spawns Chrome, but the initial window closes before driver.get("https://github.com/login") can run. Known failure mode with recent Chrome versions.

Root cause: undetected-chromedriver 3.5.5 was released 2024-02-17 and there have been no releases since. Chrome has moved from ~122 to 147 in that time — the project is effectively unmaintained and can't keep up with current Chrome.

Your diagnosis (distutils removal + Google's Selenium block) was correct — uc just isn't a viable dependency anymore. I'll explore a different path (likely reusing the user's real Chrome profile via --user-data-dir). Thanks for the effort on this.

Junyi-99 and others added 2 commits April 17, 2026 13:56
Replaces the undetected-chromedriver approach. uc 3.5.5 (last release
2024-02-17) is unmaintained and breaks on Chrome 147+ with
NoSuchWindowException. SeleniumBase's UC mode is actively maintained,
auto-downloads the correct chromedriver for the installed Chrome, and
uses `uc_open_with_reconnect` to clear anti-bot checks on the login page.

- Drop `undetected-chromedriver` + `setuptools<70` from deps; replace
  `selenium` with `seleniumbase` in pyproject.toml.
- Rewrite `APIKeyLeakageScanner.login_to_github` to construct `Driver(uc=True)`
  and open the login page via `uc_open_with_reconnect(url, reconnect_time=3)`.
- All other `self.driver.*` call sites (find_elements, page_source, refresh,
  quit, implicitly_wait, get) are unchanged — SB's Driver is selenium-compatible.

Verified: SB downloads chromedriver 147.0.7727.57, launches cleanly,
navigates to a real page.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Junyi-99
Copy link
Copy Markdown
Owner

Update: I pushed two commits to this branch (8b2cae1 + merge of main) pivoting to SeleniumBase UC mode instead of raw undetected-chromedriver.

Why this instead of --user-data-dir (which I mentioned earlier): SB's UC mode is a better fit — actively maintained, auto-downloads the matching chromedriver for the installed Chrome (just tested with Chrome 147.0.7727.57), and handles the Google anti-bot check via uc_open_with_reconnect on the login page only.

What changed

  • pyproject.toml: replaced selenium with seleniumbase; dropped undetected-chromedriver + setuptools<70
  • src/main.py: swapped driver construction to Driver(uc=True, chromium_arg=...), and switched the login-page navigation from .get() to .uc_open_with_reconnect() — that's the call that clears the bot check
  • Rest of the scanner is untouched; SB's Driver is a drop-in for the standard selenium methods it already uses

Verified

  • uv sync clean
  • uv run main.py --help works
  • Headless smoke test launches Chrome 147 via SB and fetches a real page successfully

Still needs a real interactive login test to confirm the Google block is cleared — happy to let you try that end on your side if you want. Otherwise I'll merge and close out.

@Mounstroya
Copy link
Copy Markdown
Author

Tested on Linux, Python 3.14, Chrome 147. uv sync was clean, uv run main.py --help works, and the interactive login launched Chrome via SeleniumBase UC mode without issues — GitHub login page loaded correctly with no bot check triggered. LGTM, feel free to merge

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants