diff --git a/README.md b/README.md index 11443b40d4a..ee1b20192b4 100755 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@
Includes stealth options for bypassing bot-detection and CAPTCHAs.
seleniumbase sb_cdp (Pure CDP Mode):seleniumbase sb_cdp (*[Pure CDP Mode](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md#Pure_CDP_Mode)*):
@@ -92,37 +102,16 @@ sb.quit()
(All Sannysoft bot-detection tests passed successfully)
seleniumbase sb_cdp (Pure CDP Mode):+
+
(Cloudflare Turnstile bypassed successfully on Planet Minecraft)
sb.solve_captcha() handles CAPTCHAs that aren't bypassed automatically.sb.assert_* methods wait up to 7 seconds for the expected condition to occur.
+âšī¸ sb.assert_* methods wait up to 7 seconds for the expected condition.pytest, pynose, or pure python. Not all test runners can run all test formats. For example, tests that use the `sb` pytest fixture can only be run with `pytest`. (See Syntax Formats) There's also a Gherkin test format that runs with behave.
+Most SeleniumBase scripts can be run with pytest, pynose, or pure python. Not all test runners can run all test formats. For example, tests that use the `sb` pytest fixture can only be run with `pytest`. (See Syntax Formats) There's also a Gherkin test format that runs with behave.
```zsh
pytest coffee_cart_tests.py --rs
@@ -797,10 +786,15 @@ pytest test_coffee_cart.py --trace
--sjw # (Skip JS Waits for readyState to be "complete" or Angular to load.)
--wfa # (Wait for AngularJS to be done loading after specific web actions.)
--pls=PLS # (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".)
---headless # (The default headless mode. Linux uses this mode by default.)
---headless1 # (Use Chrome's old headless mode. Fast, but has limitations.)
---headless2 # (Use Chrome's new headless mode, which supports extensions.)
+--headless # (Use headless mode. Linux uses this mode by default.)
+--chs # (Use Chrome-Headless-Shell, a limited Chrome without stealth.)
--headed # (Run tests in headed/GUI mode on Linux OS, where not default.)
+--incognito # (Enable Chrome's Incognito mode.)
+--guest # (Enable Chrome's Guest mode.)
+--uc # (Use undetected-chromedriver to evade bot-detection.)
+--uc-cdp-events # (Capture CDP events in UC Mode. NOT related to CDP Mode.)
+--log-cdp # ("goog:loggingPrefs", {"performance": "ALL", "browser": "ALL"})
+--remote-debug # (Sync to Chrome Remote Debugger chrome://inspect/#devices)
--xvfb # (Run tests using the Xvfb virtual display server on Linux OS.)
--xvfb-metrics=STRING # (Set Xvfb display size on Linux: "Width,Height".)
--locale=LOCALE_CODE # (Set the Language Locale Code for the web browser.)
@@ -834,17 +828,11 @@ pytest test_coffee_cart.py --trace
--disable-ws # (Disable Web Security on Chromium-based browsers.)
--enable-ws # (Enable Web Security on Chromium-based browsers.)
--enable-sync # (Enable "Chrome Sync" on websites.)
---uc | --undetected # (Use undetected-chromedriver to evade bot-detection.)
---uc-cdp-events # (Capture CDP events when running in "--undetected" mode.)
---log-cdp # ("goog:loggingPrefs", {"performance": "ALL", "browser": "ALL"})
---remote-debug # (Sync to Chrome Remote Debugger chrome://inspect/#devices)
--ftrace | --final-trace # (Debug Mode after each test. Don't use with CI!)
--dashboard # (Enable the SeleniumBase Dashboard. Saved at: dashboard.html)
--dash-title=STRING # (Set the title shown for the generated dashboard.)
--enable-3d-apis # (Enables WebGL and 3D APIs.)
--swiftshader # (Chrome "--use-gl=angle" / "--use-angle=swiftshader-webgl")
---incognito # (Enable Chrome's Incognito mode.)
---guest # (Enable Chrome's Guest mode.)
--dark # (Enable Chrome's Dark mode.)
--devtools # (Open Chrome's DevTools when the browser opens.)
--rs | --reuse-session # (Reuse browser session for all tests.)
@@ -1413,21 +1401,13 @@ self.activate_jquery()
```python
self.execute_script("jQuery, window.scrollTo(0, 600)") # Scrolling the page
-
self.execute_script("jQuery('#annoying-widget').hide()") # Hiding elements on a page
-
self.execute_script("jQuery('#hidden-widget').show(0)") # Showing hidden elements on a page
-
self.execute_script("jQuery('#annoying-button a').remove()") # Removing elements on a page
-
self.execute_script("jQuery('%s').mouseover()" % (mouse_over_item)) # Mouse-over elements on a page
-
self.execute_script("jQuery('input#the_id').val('my_text')") # Fast text input on a page
-
self.execute_script("jQuery('div#dropdown a.link').click()") # Click elements on a page
-
self.execute_script("return jQuery('div#amazing')[0].text") # Returns the css "text" of the element given
-
self.execute_script("return jQuery('textarea')[2].value") # Returns the css "value" of the 3rd textarea element on the page
```
diff --git a/SKILLS.md b/SKILLS.md
index 0ac539f85dc..923482bc301 100644
--- a/SKILLS.md
+++ b/SKILLS.md
@@ -192,7 +192,7 @@ pytest tests/ -n=4 --headless # parallel across 4 workers
pytest tests/ --xvfb # Linux virtual display when a headed browser is needed
```
-- Linux runs headless by default; use `--headed` to force a GUI. `--headless2` supports extensions.
+- Linux runs headless by default; use `--headed` to force a GUI.
- `--rs` reuses one browser session for all tests (faster, but state leaks between tests; use `--crumbs` to clear cookies between them).
- Set `--driver-version=VER` to pin the driver.
- No `--pdb`, `--trace`, or `--show-report` in CI.
diff --git a/examples/cdp_mode/raw_planetmc.py b/examples/cdp_mode/raw_planetmc.py
index faf3401ead5..fd69152e276 100644
--- a/examples/cdp_mode/raw_planetmc.py
+++ b/examples/cdp_mode/raw_planetmc.py
@@ -7,8 +7,8 @@
sb.assert_text("Sign in to Planet Minecraft")
sb.type('input[name="email"]', "test@example.com")
sb.type('input[name="password"]', "Fake_Password")
- sb.click("input#autologin") # The checkbox
+ sb.click("input#autologin") # Unchecks checkbox
if sb.is_element_visible("input[disabled]"):
- sb.solve_captcha() # Enables the input button
+ sb.solve_captcha() # Enables input button
sb.assert_element_absent("input[disabled]")
sb.sleep(1.5)
diff --git a/examples/migration/protractor/example_test.py b/examples/migration/protractor/example_script.py
similarity index 100%
rename from examples/migration/protractor/example_test.py
rename to examples/migration/protractor/example_script.py
diff --git a/examples/raw_cdp_mode.py b/examples/raw_cdp_mode.py
index 1354c3ecb43..9cc792e9514 100644
--- a/examples/raw_cdp_mode.py
+++ b/examples/raw_cdp_mode.py
@@ -1,7 +1,7 @@
"""Bypass bot-detection with SeleniumBase CDP Mode"""
from seleniumbase import sb_cdp
-sb = sb_cdp.Chrome()
+sb = sb_cdp.Chrome() # Launch a stealth browser
sb.goto("https://browserscan.net/bot-detection")
sb.assert_element('strong:contains("Normal")')
sb.sleep(1)
@@ -14,8 +14,9 @@
sb.goto("https://www.planetminecraft.com/account")
sb.type('[name="email"]', "Name123")
sb.type('[name="password"]', "Pass")
-sb.solve_captcha()
+sb.click("input#autologin")
+sb.solve_captcha() # Works on different CAPTCHAs
sb.assert_element('input[name="login"]')
sb.assert_element_not_visible("input[disabled]")
sb.sleep(1)
-sb.quit()
+sb.quit() # Quit browser before end-of-program
diff --git a/examples/test_apple_site.py b/examples/test_apple_site.py
index 86fcd69d998..44153d19da5 100644
--- a/examples/test_apple_site.py
+++ b/examples/test_apple_site.py
@@ -15,8 +15,6 @@ def test_apple_developer_site_webdriver_instructions(self):
self.goto_if_not_url("about:blank")
print("\n Unsupported mode for this test.")
self.skip("Unsupported mode for this test.")
- elif self.is_chromium():
- self.get_new_driver(browser=self.browser, headless2=True)
self.goto("https://developer.apple.com/search/")
title = "Testing with WebDriver in Safari"
self.type("input#searchField", title + "\n")
diff --git a/examples/test_download_files.py b/examples/test_download_files.py
index 0820588d20b..11fc0721a5b 100644
--- a/examples/test_download_files.py
+++ b/examples/test_download_files.py
@@ -27,11 +27,11 @@ def test_download_chromedriver_notes(self):
def test_download_files_from_pypi(self):
if self._multithreaded or not self.undetectable:
self.goto_if_not_url("about:blank")
- self.skip("Skipping test in multi-threaded mode.")
+ self.skip("Skip: Requires stealth and not multi-threaded.")
self.goto("https://pypi.org/project/sbvirtualdisplay/#files")
self.assert_element("span#pip-command")
- self.assert_text("Download files", "div#files h2.page-title")
- self.assert_text("Download files", "a#files-tab")
+ self.assert_text("Release files", "div#files h2.page-title")
+ self.assert_text("Release files", "a#files-tab")
pkg_header = self.get_text('h1[class*="header__name"]').strip()
pkg_name = pkg_header.replace(" ", "-")
whl_file = pkg_name + "-py3-none-any.whl"
@@ -48,7 +48,7 @@ def test_download_files_from_pypi(self):
or self.browser == "ie"
or self.browser == "edge"
or (self.is_chromium() and self.guest_mode)
- or (self.is_chromium() and (self.headless or self.headless2))
+ or (self.is_chromium() and self.headless)
):
whl_href = self.get_attribute(whl_selector, "href")
tar_href = self.get_attribute(tar_selector, "href")
@@ -85,12 +85,12 @@ def test_download_files_from_pypi(self):
# Get file sizes in kB to compare actual values with displayed values
whl_file_kb = whl_file_bytes / 1000.0
whl_line_fi = self.get_text('a[href$=".whl"]').strip()
- whl_line = self.get_text('div.file:contains("%s")' % whl_line_fi)
- whl_display_kb = float(whl_line.split("(")[1].split(" ")[0])
+ whl_line = self.get_text('td:contains("%s")' % whl_line_fi)
+ whl_display_kb = float(whl_line.split(" ")[1].split(" ")[0])
tar_gz_file_kb = tar_gz_file_bytes / 1000.0
tar_gz_line_fi = self.get_text('a[href$=".tar.gz"]').strip()
- tar_gz_line = self.get_text('div.file:contains("%s")' % tar_gz_line_fi)
- tar_gz_display_kb = float(tar_gz_line.split("(")[1].split(" ")[0])
+ tar_gz_line = self.get_text('tr:contains("%s")' % tar_gz_line_fi)
+ tar_gz_display_kb = float(tar_gz_line.split(" ")[1].split(" ")[0])
# Verify downloaded files are the correct size (account for rounding)
self.assert_true(
diff --git a/examples/test_download_images.py b/examples/test_download_images.py
index 3f76999b824..dd10169971a 100644
--- a/examples/test_download_images.py
+++ b/examples/test_download_images.py
@@ -42,8 +42,6 @@ def test_download_images_via_screenshot(self):
count = 0
for src in unique_src_values:
self.goto(src)
- if not self.headless and not self.headless2:
- self.sleep(0.3)
image = self.find_element("img")
if src.startswith("data:") or ";base64" in src:
# Special Cases: SVGs, etc. Convert to PNG.
@@ -53,6 +51,11 @@ def test_download_images_via_screenshot(self):
filename = src.split("/")[-1]
folder = "downloaded_files"
file_path = os.path.join(folder, filename)
+ # Too much screen flicker if not slowed
+ if not self.headless:
+ self.sleep(0.15)
image.screenshot(file_path)
+ if not self.headless:
+ self.sleep(0.15)
self.assert_downloaded_file(filename)
print(file_path)
diff --git a/help_docs/customizing_test_runs.md b/help_docs/customizing_test_runs.md
index 575d6c4f254..2ceb52730ec 100644
--- a/help_docs/customizing_test_runs.md
+++ b/help_docs/customizing_test_runs.md
@@ -171,10 +171,15 @@ pytest my_first_test.py --settings-file=custom_settings.py
--sjw # (Skip JS Waits for readyState to be "complete" or Angular to load.)
--wfa # (Wait for AngularJS to be done loading after specific web actions.)
--pls=PLS # (Set pageLoadStrategy on Chrome: "normal", "eager", or "none".)
---headless # (The default headless mode. Linux uses this mode by default.)
---headless1 # (Use Chrome's old headless mode. Fast, but has limitations.)
---headless2 # (Use Chrome's new headless mode, which supports extensions.)
+--headless # (Use headless mode. Linux uses this mode by default.)
+--chs # (Use Chrome-Headless-Shell, a limited Chrome without stealth.)
--headed # (Run tests in headed/GUI mode on Linux OS, where not default.)
+--incognito # (Enable Chrome's Incognito mode.)
+--guest # (Enable Chrome's Guest mode.)
+--uc # (Use undetected-chromedriver to evade bot-detection.)
+--uc-cdp-events # (Capture CDP events in UC Mode. NOT related to CDP Mode.)
+--log-cdp # ("goog:loggingPrefs", {"performance": "ALL", "browser": "ALL"})
+--remote-debug # (Sync to Chrome Remote Debugger chrome://inspect/#devices)
--xvfb # (Run tests using the Xvfb virtual display server on Linux OS.)
--xvfb-metrics=STRING # (Set Xvfb display size on Linux: "Width,Height".)
--locale=LOCALE_CODE # (Set the Language Locale Code for the web browser.)
@@ -208,17 +213,11 @@ pytest my_first_test.py --settings-file=custom_settings.py
--disable-ws # (Disable Web Security on Chromium-based browsers.)
--enable-ws # (Enable Web Security on Chromium-based browsers.)
--enable-sync # (Enable "Chrome Sync" on websites.)
---uc | --undetected # (Use undetected-chromedriver to evade bot-detection.)
---uc-cdp-events # (Capture CDP events when running in "--undetected" mode.)
---log-cdp # ("goog:loggingPrefs", {"performance": "ALL", "browser": "ALL"})
---remote-debug # (Sync to Chrome Remote Debugger chrome://inspect/#devices)
--ftrace | --final-trace # (Debug Mode after each test. Don't use with CI!)
--dashboard # (Enable the SeleniumBase Dashboard. Saved at: dashboard.html)
--dash-title=STRING # (Set the title shown for the generated dashboard.)
--enable-3d-apis # (Enables WebGL and 3D APIs.)
--swiftshader # (Chrome "--use-gl=angle" / "--use-angle=swiftshader-webgl")
---incognito # (Enable Chrome's Incognito mode.)
---guest # (Enable Chrome's Guest mode.)
--dark # (Enable Chrome's Dark mode.)
--devtools # (Open Chrome's DevTools when the browser opens.)
--rs | --reuse-session # (Reuse browser session for all tests.)
@@ -461,7 +460,7 @@ You can specify a Language Locale Code to customize web pages on supported websi
pytest --locale=CODE # Example: --locale=ru
```
-Visit đž Locales for a full list of codes.
+Visit **[đž Locales](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/locale_codes.md))** for a full list of codes.
--------
@@ -650,9 +649,7 @@ test=None # Test Mode: Output, Logging, Continue on failure unless "rtf".
rtf=None # Shortcut / Duplicate of "raise_test_failure".
raise_test_failure=None # If "test" mode, raise Exception on 1st failure.
browser=None # Choose from "chrome", "edge", "firefox", or "safari".
-headless=None # Use the default headless mode for Chromium and Firefox.
-headless1=None # Use Chromium's old headless mode. (Fast, but limited)
-headless2=None # Use Chromium's new headless mode. (Has more features)
+headless=None # Use headless mode for Chromium/Firefox. (headless=True)
locale_code=None # Set the Language Locale Code for the web browser.
protocol=None # The Selenium Grid protocol: "http" or "https".
servername=None # The Selenium Grid server/IP used for tests.
@@ -761,9 +758,7 @@ Example: [SeleniumBase/examples/raw_robot.py](https://github.com/seleniumbase/Se
```python
browser=None # Choose from "chrome", "edge", "firefox", or "safari".
-headless=None # Use the default headless mode for Chromium and Firefox.
-headless1=None # Use Chromium's old headless mode. (Fast, but limited)
-headless2=None # Use Chromium's new headless mode. (Has more features)
+headless=None # Use headless mode for Chromium/Firefox. (headless=True)
headed=None # Run tests in headed/GUI mode on Linux, where not default.
locale_code=None # Set the Language Locale Code for the web browser.
protocol=None # The Selenium Grid protocol: "http" or "https".
@@ -846,7 +841,7 @@ Example: [SeleniumBase/examples/raw_driver_manager.py](https://github.com/seleni
```python
url: Optional[str] = None
user_data_dir: Optional[PathLike] = None
-headless: Optional[bool] = False
+headless: Optional[bool] = False # Set `headless=True` to activate
incognito: Optional[bool] = False
guest: Optional[bool] = False
browser_executable_path: Optional[PathLike] = None
diff --git a/help_docs/method_summary.md b/help_docs/method_summary.md
index 0df9584098c..00956232ad4 100644
--- a/help_docs/method_summary.md
+++ b/help_docs/method_summary.md
@@ -215,8 +215,6 @@ self.get_new_driver(
log_cdp_events=None,
no_sandbox=None,
disable_gpu=None,
- headless1=None,
- headless2=None,
incognito=None,
guest_mode=None,
dark_mode=None,
@@ -327,7 +325,7 @@ self.get_domain_url(url)
self.get_active_element_css()
self.get_beautiful_soup(source=None)
self.get_unique_links()
-self.get_link_status_code(link, allow_redirects=False, timeout=5, verify=False)
+self.get_link_status_code(link, allow_redirects=False, timeout=5, verify=True)
self.assert_link_status_code_is_not_404(link)
self.assert_no_404_errors(multithreaded=True, timeout=None)
# Duplicates:
diff --git a/help_docs/syntax_formats.md b/help_docs/syntax_formats.md
index 2289ed6de28..98c2303ea4e 100644
--- a/help_docs/syntax_formats.md
+++ b/help_docs/syntax_formats.md
@@ -645,7 +645,7 @@ class MiClaseDePrueba(CasoDePrueba):
print() should output Virtual Manager, which means that the automation successfully passed the Turnstile.
+The 2nd print() outputs the expected page title, which means that the automation successfully clicked & bypassed the Turnstile.
(Note: UC Mode has a special virtual display on Linux: Xvfb, which is enabled by default when not changing headed/headless settings.)
diff --git a/mcp_servers/pyproject.toml b/mcp_servers/pyproject.toml
index 9dc48906062..a735e844b06 100644
--- a/mcp_servers/pyproject.toml
+++ b/mcp_servers/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "seleniumbase-mcp"
-version = "1.5.4dev0"
+version = "1.5.5dev0"
description = "MCP server exposing SeleniumBase CDP Mode as tools for MCP clients."
readme = "README.md"
requires-python = ">=3.10"
diff --git a/mkdocs_build/prepare.py b/mkdocs_build/prepare.py
index 103f7f3004e..8c560573180 100644
--- a/mkdocs_build/prepare.py
+++ b/mkdocs_build/prepare.py
@@ -168,6 +168,9 @@ def main(*args, **kwargs):
"/help_docs/uc_mode/", "/../help_docs/uc_mode/"
)
changed = True
+ if ".md#-" in line:
+ line = line.replace(".md#-", ".md#")
+ changed = True
if "" in line:
changed = True
continue
diff --git a/mkdocs_build/requirements.txt b/mkdocs_build/requirements.txt
index e74fc59d6ed..7aa11c1fd9f 100644
--- a/mkdocs_build/requirements.txt
+++ b/mkdocs_build/requirements.txt
@@ -2,14 +2,15 @@
# For docs generation, you'll need Python 3.11 or newer
regex>=2026.9.29
-pipdeptree>=4.2.9
-platformdirs>=4.13.5
-nab>=0.0.22
+platformdirs>=4.14.0
+nab>=0.0.23
backrefs>=8.1
pymdown-extensions>=12.3
python-dateutil>=3.0.0
click>=8.5.0
+tzdata>=2026.5
Markdown>=3.11.2
+pipdeptree==4.2.9
ghp-import==2.1.0
watchdog==6.0.0
cairocffi==1.7.1
diff --git a/requirements.txt b/requirements.txt
index 242daa35c44..127d202e275 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -71,7 +71,9 @@ rich>=15.0.0,<16
coverage>=7.16.2;python_version=="3.10"
coverage>=7.17.0;python_version>="3.11"
pytest-cov>=7.1.0
-flake8==7.4.1
+flake8==7.4.1;python_version=="3.10"
+flake8==7.5.0;python_version>="3.11"
mccabe==0.7.0
-pyflakes==4.0.3
+pyflakes==4.0.3;python_version=="3.10"
+pyflakes==4.1.0;python_version>="3.11"
pycodestyle==2.15.0
diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py
index 8a64abdb2f2..2fac590e366 100755
--- a/seleniumbase/__version__.py
+++ b/seleniumbase/__version__.py
@@ -1,2 +1,2 @@
# seleniumbase package
-__version__ = "4.56.4"
+__version__ = "4.56.5"
diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py
index c80823e4046..aeff3c134e6 100644
--- a/seleniumbase/fixtures/base_case.py
+++ b/seleniumbase/fixtures/base_case.py
@@ -7632,7 +7632,7 @@ def get_link_status_code(
link,
allow_redirects=False,
timeout=5,
- verify=False,
+ verify=True,
):
"""Get the status code of a link.
If the timeout is set to less than 1, it becomes 1.
diff --git a/seleniumbase/fixtures/page_utils.py b/seleniumbase/fixtures/page_utils.py
index 55fc005c8af..9506eda4d66 100644
--- a/seleniumbase/fixtures/page_utils.py
+++ b/seleniumbase/fixtures/page_utils.py
@@ -260,7 +260,7 @@ def _get_link_status_code(
link,
allow_redirects=False,
timeout=5,
- verify=False,
+ verify=True,
):
"""Get the status code of a link.
If the timeout is exceeded, will return a 404.
diff --git a/seleniumbase/undetected/cdp_driver/element.py b/seleniumbase/undetected/cdp_driver/element.py
index 14c21c2bb08..984bc600bd0 100644
--- a/seleniumbase/undetected/cdp_driver/element.py
+++ b/seleniumbase/undetected/cdp_driver/element.py
@@ -1268,7 +1268,8 @@ async def highlight_overlay_async(self):
await self.tab.send(cdp.dom.disable())
await self.tab.send(cdp.overlay.disable())
return
- await self.tab.send(cdp.dom.enable())
+ with suppress(Exception):
+ await self.tab.send(cdp.dom.enable())
await self.tab.send(cdp.overlay.enable())
conf = cdp.overlay.HighlightConfig(
show_info=True, show_extension_lines=True, show_styles=True
diff --git a/server.json b/server.json
index 388a49f0d5e..8b16d721c78 100644
--- a/server.json
+++ b/server.json
@@ -3,7 +3,7 @@
"name": "io.github.seleniumbase/seleniumbase",
"title": "SeleniumBase MCP",
"description": "Stealthy browser automation, testing, and web-scraping via CDP Mode.",
- "version": "4.56.4",
+ "version": "4.56.5",
"repository": {
"url": "https://github.com/seleniumbase/SeleniumBase",
"source": "github"
@@ -13,7 +13,7 @@
{
"registryType": "pypi",
"identifier": "seleniumbase",
- "version": "4.56.4",
+ "version": "4.56.5",
"transport": {
"type": "stdio"
},
diff --git a/setup.py b/setup.py
index 6cb18c22f2e..9f544da4c7f 100755
--- a/setup.py
+++ b/setup.py
@@ -41,7 +41,7 @@
print("You are currently using Python %s\n" % current_ver)
sys.exit()
print("\n*** Checking code health with flake8:\n")
- os.system("python -m pip install 'flake8==7.4.1'")
+ os.system("python -m pip install 'flake8==7.5.0'")
flake8_status = os.system(
"flake8 --exclude=recordings,temp,venv,.venv"
)
@@ -250,9 +250,11 @@
# pip install -e .[flake8]
# Usage: flake8
"flake8": [
- 'flake8==7.4.1',
+ 'flake8==7.4.1;python_version=="3.10"',
+ 'flake8==7.5.0;python_version>="3.11"',
'mccabe==0.7.0',
- 'pyflakes==4.0.3',
+ 'pyflakes==4.0.3;python_version=="3.10"',
+ 'pyflakes==4.1.0;python_version>="3.11"',
'pycodestyle==2.15.0',
],
# pip install -e .[mcp]
@@ -310,7 +312,7 @@
# pip install -e .[uv]
# (For the MCP integration and more.)
"uv": [
- "uv>=0.13.5"
+ "uv>=0.13.6"
],
},
packages=[