Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 238ad3d

Browse files
authored
Merge pull request #3684 from seleniumbase/mostly-memory-improvements
Mostly memory improvements
2 parents b9a89f7 + 5b30240 commit 238ad3d

File tree

8 files changed

+115
-44
lines changed

8 files changed

+115
-44
lines changed

‎mkdocs_build/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ regex>=2024年11月6日
55
pymdown-extensions>=10.14.3
66
pipdeptree>=2.26.0
77
python-dateutil>=2.8.2
8-
Markdown==3.7
8+
Markdown==3.8
99
click==8.1.8
1010
ghp-import==2.1.0
1111
watchdog==6.0.0
@@ -14,7 +14,7 @@ pathspec==0.12.1
1414
Babel==2.17.0
1515
paginate==0.5.7
1616
mkdocs==1.6.1
17-
mkdocs-material==9.6.11
17+
mkdocs-material==9.6.12
1818
mkdocs-exclude-search==0.6.6
1919
mkdocs-simple-hooks==0.1.5
2020
mkdocs-material-extensions==1.3.1

‎requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pip>=25.0.1
2-
packaging>=24.2
2+
packaging>=25.0
33
setuptools~=70.2;python_version<"3.10"
44
setuptools>=78.1.0;python_version>="3.10"
55
wheel>=0.45.1
@@ -61,7 +61,7 @@ pytest-xdist==3.6.1
6161
parameterized==0.9.0
6262
behave==1.2.6
6363
soupsieve==2.6
64-
beautifulsoup4==4.13.3
64+
beautifulsoup4==4.13.4
6565
pyotp==2.9.0
6666
python-xlib==0.33;platform_system=="Linux"
6767
markdown-it-py==3.0.0

‎seleniumbase/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# seleniumbase package
2-
__version__ = "4.37.2"
2+
__version__ = "4.37.3"

‎seleniumbase/fixtures/base_case.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ def __initialize_variables(self):
162162
self.__jqc_default_theme = None
163163
self.__jqc_default_color = None
164164
self.__jqc_default_width = None
165+
self.__saved_id = None
165166
# Requires self._* instead of self.__* for external class use
166167
self._language = "English"
167168
self._presentation_slides = {}
@@ -15676,19 +15677,24 @@ def __get_test_id(self):
1567615677
test_id = "%s.%s" % (file_name, scenario_name)
1567715678
return test_id
1567815679
elif hasattr(self, "is_context_manager") and self.is_context_manager:
15680+
if hasattr(self, "_manager_saved_id"):
15681+
self.__saved_id = self._manager_saved_id
15682+
if self.__saved_id:
15683+
return self.__saved_id
1567915684
filename = self.__class__.__module__.split(".")[-1] + ".py"
1568015685
methodname = self._testMethodName
1568115686
context_id = None
1568215687
if filename == "base_case.py" or methodname == "runTest":
1568315688
import traceback
15684-
stack_base = traceback.format_stack()[0].split(", in ")[0]
15685-
test_base = stack_base.split(", in ")[0].split(os.sep)[-1]
15689+
stack_base = traceback.format_stack()[0].split(os.sep)[-1]
15690+
test_base = stack_base.split(", in ")[0]
1568615691
if hasattr(self, "cm_filename") and self.cm_filename:
1568715692
filename = self.cm_filename
1568815693
else:
1568915694
filename = test_base.split('"')[0]
1569015695
methodname = ".line_" + test_base.split(", line ")[-1]
1569115696
context_id = filename.split(".")[0] + methodname
15697+
self.__saved_id = context_id
1569215698
return context_id
1569315699
test_id = "%s.%s.%s" % (
1569415700
self.__class__.__module__,

‎seleniumbase/plugins/sb_manager.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
2424
#########################################
2525
"""
26-
from contextlib import contextmanager
26+
from contextlib import contextmanager, suppress
2727

2828

2929
@contextmanager # Usage: -> ``with SB() as sb:``
@@ -258,6 +258,7 @@ def SB(
258258
time_limit (float): SECONDS (Safely fail tests that exceed the time limit)
259259
"""
260260
import colorama
261+
import gc
261262
import os
262263
import sys
263264
import time
@@ -1231,6 +1232,15 @@ def SB(
12311232
sb.cap_file = sb_config.cap_file
12321233
sb.cap_string = sb_config.cap_string
12331234
sb._has_failure = False # This may change
1235+
1236+
with suppress(Exception):
1237+
stack_base = traceback.format_stack()[0].split(os.sep)[-1]
1238+
test_base = stack_base.split(", in ")[0]
1239+
filename = test_base.split('"')[0]
1240+
methodname = ".line_" + test_base.split(", line ")[-1]
1241+
context_id = filename.split(".")[0] + methodname
1242+
sb._manager_saved_id = context_id
1243+
12341244
if hasattr(sb_config, "headless_active"):
12351245
sb.headless_active = sb_config.headless_active
12361246
else:
@@ -1357,6 +1367,7 @@ def SB(
13571367
"%s%s%s%s%s"
13581368
% (c1, left_space, end_text, right_space, cr)
13591369
)
1370+
gc.collect()
13601371
if test and test_name and not test_passed and raise_test_failure:
13611372
raise exception
13621373
elif (

‎seleniumbase/undetected/__init__.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,14 @@ def __init__(
145145
debug_port = 9222
146146
special_port_free = False # If the port isn't free, don't use 9222
147147
try:
148-
res = requests.get("http://127.0.0.1:9222", timeout=1)
149-
if res.status_code != 200:
150-
raise Exception("The port is free! It will be used!")
148+
with requests.Session() as session:
149+
res = session.get(
150+
"http://127.0.0.1:9222",
151+
headers={"Connection": "close"},
152+
timeout=2,
153+
)
154+
if res.status_code != 200:
155+
raise Exception("The port is free! It will be used!")
151156
except Exception:
152157
# Use port 9222, which outputs to chrome://inspect/#devices
153158
special_port_free = True
@@ -462,9 +467,7 @@ def reconnect(self, timeout=0.1):
462467
with suppress(Exception):
463468
for window_handle in self.window_handles:
464469
self.switch_to.window(window_handle)
465-
if self.current_url.startswith(
466-
"chrome-extension://"
467-
):
470+
if self.current_url.startswith("chrome-extension://"):
468471
# https://issues.chromium.org/issues/396611138
469472
# (Remove the Linux conditional when resolved)
470473
# (So that close() is always called)
@@ -559,21 +562,31 @@ def quit(self):
559562
logger.debug(e, exc_info=True)
560563
except Exception:
561564
pass
565+
with suppress(Exception):
566+
self.stop_client()
567+
with suppress(Exception):
568+
if hasattr(self, "command_executor") and self.command_executor:
569+
self.command_executor.close()
570+
571+
# Remove instance reference to allow garbage collection
572+
Chrome._instances.discard(self)
573+
562574
if hasattr(self, "service") and getattr(self.service, "process", None):
563575
logger.debug("Stopping webdriver service")
564576
with suppress(Exception):
565-
self.stop_client()
566577
try:
567578
self.service.send_remote_shutdown_command()
568579
except TypeError:
569580
pass
570581
finally:
571582
with suppress(Exception):
572583
self.service._terminate_process()
573-
withsuppress(Exception):
574-
ifself.reactorandisinstance(self.reactor, Reactor):
575-
logger.debug("Shutting down Reactor")
584+
ifself.reactorandhasattr(self.reactor, "event"):
585+
logger.debug("Shutting down Reactor")
586+
withsuppress(Exception):
576587
self.reactor.event.set()
588+
self.reactor.join(timeout=2)
589+
self.reactor = None
577590
if (
578591
hasattr(self, "keep_user_data_dir")
579592
and hasattr(self, "user_data_dir")

‎seleniumbase/undetected/cdp.py

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,58 @@ def __init__(self, options):
5353
self._session = requests.Session()
5454
self._last_resp = None
5555
self._last_json = None
56-
resp = self.get(self.endpoints.json)
57-
self.sessionId = resp[0]["id"]
58-
self.wsurl = resp[0]["webSocketDebuggerUrl"]
56+
with requests.Session() as session:
57+
resp = session.get(
58+
self.server_addr + self.endpoints.json,
59+
headers={"Connection": "close"},
60+
timeout=2,
61+
)
62+
self.sessionId = resp.json()[0]["id"]
63+
self.wsurl = resp.json()[0]["webSocketDebuggerUrl"]
5964

6065
def tab_activate(self, id=None):
6166
if not id:
6267
active_tab = self.tab_list()[0]
6368
id = active_tab.id
6469
self.wsurl = active_tab.webSocketDebuggerUrl
65-
return self.post(self.endpoints["activate"].format(id=id))
70+
with requests.Session() as session:
71+
resp = session.post(
72+
self.server_addr + self.endpoints["activate"].format(id=id),
73+
headers={"Connection": "close"},
74+
timeout=2,
75+
)
76+
return resp.json()
6677

6778
def tab_list(self):
68-
retval = self.get(self.endpoints["list"])
69-
return [PageElement(o) for o in retval]
79+
with requests.Session() as session:
80+
resp = session.get(
81+
self.server_addr + self.endpoints["list"],
82+
headers={"Connection": "close"},
83+
timeout=2,
84+
)
85+
retval = resp.json()
86+
return [PageElement(o) for o in retval]
7087

7188
def tab_new(self, url):
72-
return self.post(self.endpoints["new"].format(url=url))
89+
with requests.Session() as session:
90+
resp = session.post(
91+
self.server_addr + self.endpoints["new"].format(url=url),
92+
headers={"Connection": "close"},
93+
timeout=2,
94+
)
95+
return resp.json()
7396

7497
def tab_close_last_opened(self):
7598
sessions = self.tab_list()
7699
opentabs = [s for s in sessions if s["type"] == "page"]
77-
return self.post(self.endpoints["close"].format(id=opentabs[-1]["id"]))
100+
with requests.Session() as session:
101+
endp_close = self.endpoints["close"]
102+
resp = session.post(
103+
self.server_addr + endp_close.format(id=opentabs[-1]["id"]),
104+
headers={"Connection": "close"},
105+
timeout=2,
106+
)
107+
return resp.json()
78108

79109
async def send(self, method, params):
80110
pip_find_lock = fasteners.InterProcessLock(
@@ -101,27 +131,38 @@ def get(self, uri):
101131
from urllib.parse import unquote
102132

103133
uri = unquote(uri, errors="strict")
104-
resp = self._session.get(self.server_addr + uri)
105-
try:
106-
self._last_resp = resp
107-
self._last_json = resp.json()
108-
except Exception:
109-
return
110-
else:
111-
return self._last_json
134+
with requests.Session() as session:
135+
resp = session.get(
136+
self.server_addr + uri,
137+
headers={"Connection": "close"},
138+
timeout=2,
139+
)
140+
try:
141+
self._last_resp = resp
142+
self._last_json = resp.json()
143+
except Exception:
144+
return
145+
else:
146+
return self._last_json
112147

113148
def post(self, uri, data=None):
114149
from urllib.parse import unquote
115150

116151
uri = unquote(uri, errors="strict")
117152
if not data:
118153
data = {}
119-
resp = self._session.post(self.server_addr + uri, json=data)
120-
try:
121-
self._last_resp = resp
122-
self._last_json = resp.json()
123-
except Exception:
124-
return self._last_resp
154+
with requests.Session() as session:
155+
resp = session.post(
156+
self.server_addr + uri,
157+
json=data,
158+
headers={"Connection": "close"},
159+
timeout=2,
160+
)
161+
try:
162+
self._last_resp = resp
163+
self._last_json = resp.json()
164+
except Exception:
165+
return self._last_resp
125166

126167
@property
127168
def last_json(self):

‎setup.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@
148148
python_requires=">=3.8",
149149
install_requires=[
150150
'pip>=25.0.1',
151-
'packaging>=24.2',
151+
'packaging>=25.0',
152152
'setuptools~=70.2;python_version<"3.10"', # Newer ones had issues
153153
'setuptools>=78.1.0;python_version>="3.10"',
154154
'wheel>=0.45.1',
@@ -210,7 +210,7 @@
210210
'parameterized==0.9.0',
211211
"behave==1.2.6",
212212
'soupsieve==2.6',
213-
"beautifulsoup4==4.13.3",
213+
"beautifulsoup4==4.13.4",
214214
'pyotp==2.9.0',
215215
'python-xlib==0.33;platform_system=="Linux"',
216216
'markdown-it-py==3.0.0',
@@ -261,7 +261,7 @@
261261
# (An optional library for parsing PDF files.)
262262
"pdfminer": [
263263
'pdfminer.six==20250324;python_version<"3.9"',
264-
'pdfminer.six==20250327;python_version>="3.9"',
264+
'pdfminer.six==20250416;python_version>="3.9"',
265265
'cryptography==39.0.2;python_version<"3.9"',
266266
'cryptography==44.0.2;python_version>="3.9"',
267267
'cffi==1.17.1',
@@ -271,7 +271,7 @@
271271
# (An optional library for image-processing.)
272272
"pillow": [
273273
'Pillow>=10.4.0;python_version<"3.9"',
274-
'Pillow>=11.2.0;python_version>="3.9"',
274+
'Pillow>=11.2.1;python_version>="3.9"',
275275
],
276276
# pip install -e .[pip-system-certs]
277277
# (If you see [SSL: CERTIFICATE_VERIFY_FAILED], then get this.)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /