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
8 changes: 0 additions & 8 deletions .evergreen/generated_configs/variants.yml
Original file line number Diff line number Diff line change
Expand Up @@ -319,14 +319,6 @@ buildvariants:
tags: []

# Green framework tests
- name: green-eventlet-rhel8
tasks:
- name: .test-standard .python-3.9 .sync
display_name: Green Eventlet RHEL8
run_on:
- rhel87-small
expansions:
GREEN_FRAMEWORK: eventlet
- name: green-gevent-rhel8
tasks:
- name: .test-standard .sync
Expand Down
6 changes: 1 addition & 5 deletions .evergreen/scripts/generate_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,8 @@ def create_stable_api_variants():
def create_green_framework_variants():
variants = []
host = DEFAULT_HOST
for framework in ["eventlet", "gevent"]:
for framework in ["gevent"]:
tasks = [".test-standard .sync"]
if framework == "eventlet":
# Eventlet has issues with dnspython > 2.0 and newer versions of CPython
# https://jira.mongodb.org/browse/PYTHON-5284
tasks = [".test-standard .python-3.9 .sync"]
expansions = dict(GREEN_FRAMEWORK=framework)
display_name = get_variant_name(f"Green {framework.capitalize()}", host)
variant = create_variant(tasks, display_name, host=host, expansions=expansions)
Expand Down
8 changes: 1 addition & 7 deletions .evergreen/scripts/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,7 @@ def handle_perf(start_time: datetime):


def handle_green_framework() -> None:
if GREEN_FRAMEWORK == "eventlet":
import eventlet

# https://github.com/eventlet/eventlet/issues/401
eventlet.sleep()
eventlet.monkey_patch()
elif GREEN_FRAMEWORK == "gevent":
if GREEN_FRAMEWORK == "gevent":
from gevent import monkey

monkey.patch_all()
Expand Down
2 changes: 1 addition & 1 deletion .evergreen/scripts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def get_test_options(
parser.add_argument(
"--green-framework",
nargs=1,
choices=["eventlet", "gevent"],
choices=["gevent"],
help="Optional green framework to test against.",
)
parser.add_argument(
Expand Down
2 changes: 2 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ PyMongo 4.16 brings a number of changes including:
- Removed invalid documents from :class:`bson.errors.InvalidDocument` error messages as
doing so may leak sensitive user data.
Instead, invalid documents are stored in :attr:`bson.errors.InvalidDocument.document`.
- Removed support for Eventlet.
Eventlet is actively being sunset by its maintainers and has compatibility issues with PyMongo's dnspython dependency.

Changes in Version 4.15.1 (2025/09/16)
--------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion pymongo/asynchronous/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ async def _raise_connection_failure(self, error: BaseException) -> NoReturn:
# signals and throws KeyboardInterrupt into the current frame on the
# main thread.
#
# But in Gevent and Eventlet, the polling mechanism (epoll, kqueue,
# But in Gevent, the polling mechanism (epoll, kqueue,
# ..) is called in Python code, which experiences the signal as a
# KeyboardInterrupt from the start, rather than as an initial
# socket.error, so we catch that, close the socket, and reraise it.
Expand Down
12 changes: 5 additions & 7 deletions pymongo/pool_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,11 @@ def _raise_connection_failure(
msg = msg_prefix + msg
if "configured timeouts" not in msg:
msg += format_timeout_details(timeout_details)
if isinstance(error, socket.timeout):
raise NetworkTimeout(msg) from error
elif isinstance(error, SSLErrors) and "timed out" in str(error):
# Eventlet does not distinguish TLS network timeouts from other
# SSLErrors (https://github.com/eventlet/eventlet/issues/692).
# Luckily, we can work around this limitation because the phrase
# 'timed out' appears in all the timeout related SSLErrors raised.
if (
isinstance(error, socket.timeout)
or isinstance(error, SSLErrors)
and "timed out" in str(error)
):
raise NetworkTimeout(msg) from error
else:
raise AutoReconnect(msg) from error
Expand Down
2 changes: 1 addition & 1 deletion pymongo/synchronous/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ def _raise_connection_failure(self, error: BaseException) -> NoReturn:
# signals and throws KeyboardInterrupt into the current frame on the
# main thread.
#
# But in Gevent and Eventlet, the polling mechanism (epoll, kqueue,
# But in Gevent, the polling mechanism (epoll, kqueue,
# ..) is called in Python code, which experiences the signal as a
# KeyboardInterrupt from the start, rather than as an initial
# socket.error, so we catch that, close the socket, and reraise it.
Expand Down
4 changes: 0 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ dev = [
pip = ["pip"]
# TODO: PYTHON-5464
gevent = ["gevent", "cffi>=2.0.0b1;python_version=='3.14'"]
eventlet = ["eventlet"]
coverage = [
"pytest-cov",
"coverage>=5,<=7.10.6"
Expand Down Expand Up @@ -113,15 +112,12 @@ filterwarnings = [
"module:.*WindowsSelectorEventLoopPolicy:DeprecationWarning",
"module:.*et_event_loop_policy:DeprecationWarning",
# TODO: Remove as part of PYTHON-3923.
"module:unclosed <eventlet.green.ssl.GreenSSLSocket:ResourceWarning",
"module:unclosed <socket.socket:ResourceWarning",
"module:unclosed <ssl.SSLSocket:ResourceWarning",
"module:unclosed <socket object:ResourceWarning",
"module:unclosed transport:ResourceWarning",
# pytest-asyncio known issue: https://github.com/pytest-dev/pytest-asyncio/issues/724
"module:unclosed event loop:ResourceWarning",
# https://github.com/eventlet/eventlet/issues/818
"module:please use dns.resolver.Resolver.resolve:DeprecationWarning",
# https://github.com/dateutil/dateutil/issues/1314
"module:datetime.datetime.utc:DeprecationWarning",
]
Expand Down
2 changes: 1 addition & 1 deletion test/asynchronous/test_encryption.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ async def test_use_after_close(self):
)
@unittest.skipIf(
is_greenthread_patched(),
"gevent and eventlet do not support POSIX-style forking.",
"gevent does not support POSIX-style forking.",
)
@async_client_context.require_sync
async def test_fork(self):
Expand Down
2 changes: 1 addition & 1 deletion test/test_encryption.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ def test_use_after_close(self):
)
@unittest.skipIf(
is_greenthread_patched(),
"gevent and eventlet do not support POSIX-style forking.",
"gevent does not support POSIX-style forking.",
)
@client_context.require_sync
def test_fork(self):
Expand Down
2 changes: 1 addition & 1 deletion test/test_fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
)
@unittest.skipIf(
is_greenthread_patched(),
"gevent and eventlet do not support POSIX-style forking.",
"gevent does not support POSIX-style forking.",
)
class TestFork(IntegrationTest):
def test_lock_client(self):
Expand Down
9 changes: 1 addition & 8 deletions test/utils_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,15 +528,8 @@ def gevent_monkey_patched():
return False


def eventlet_monkey_patched():
"""Check if eventlet's monkey patching is active."""
import threading

return threading.current_thread.__module__ == "eventlet.green.threading"


def is_greenthread_patched():
return gevent_monkey_patched() or eventlet_monkey_patched()
return gevent_monkey_patched()


def parse_read_preference(pref):
Expand Down
19 changes: 1 addition & 18 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading