Commit 3f52ac84

stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
2025-11-10 19:28:54
chore(package): drop Python 3.8 support
1 parent 6574bcd
Changed files (3)
src/openai/_utils/_sync.py
@@ -1,10 +1,8 @@
 from __future__ import annotations
 
-import sys
 import asyncio
 import functools
-import contextvars
-from typing import Any, TypeVar, Callable, Awaitable
+from typing import TypeVar, Callable, Awaitable
 from typing_extensions import ParamSpec
 
 import anyio
@@ -15,34 +13,11 @@ T_Retval = TypeVar("T_Retval")
 T_ParamSpec = ParamSpec("T_ParamSpec")
 
 
-if sys.version_info >= (3, 9):
-    _asyncio_to_thread = asyncio.to_thread
-else:
-    # backport of https://docs.python.org/3/library/asyncio-task.html#asyncio.to_thread
-    # for Python 3.8 support
-    async def _asyncio_to_thread(
-        func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs
-    ) -> Any:
-        """Asynchronously run function *func* in a separate thread.
-
-        Any *args and **kwargs supplied for this function are directly passed
-        to *func*. Also, the current :class:`contextvars.Context` is propagated,
-        allowing context variables from the main thread to be accessed in the
-        separate thread.
-
-        Returns a coroutine that can be awaited to get the eventual result of *func*.
-        """
-        loop = asyncio.events.get_running_loop()
-        ctx = contextvars.copy_context()
-        func_call = functools.partial(ctx.run, func, *args, **kwargs)
-        return await loop.run_in_executor(None, func_call)
-
-
 async def to_thread(
     func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs
 ) -> T_Retval:
     if sniffio.current_async_library() == "asyncio":
-        return await _asyncio_to_thread(func, *args, **kwargs)
+        return await asyncio.to_thread(func, *args, **kwargs)
 
     return await anyio.to_thread.run_sync(
         functools.partial(func, *args, **kwargs),
@@ -53,10 +28,7 @@ async def to_thread(
 def asyncify(function: Callable[T_ParamSpec, T_Retval]) -> Callable[T_ParamSpec, Awaitable[T_Retval]]:
     """
     Take a blocking function and create an async one that receives the same
-    positional and keyword arguments. For python version 3.9 and above, it uses
-    asyncio.to_thread to run the function in a separate thread. For python version
-    3.8, it uses locally defined copy of the asyncio.to_thread function which was
-    introduced in python 3.9.
+    positional and keyword arguments.
 
     Usage:
 
pyproject.toml
@@ -17,11 +17,10 @@ dependencies = [
     "tqdm > 4",
     "jiter>=0.10.0, <1",
 ]
-requires-python = ">= 3.8"
+requires-python = ">= 3.9"
 classifiers = [
   "Typing :: Typed",
   "Intended Audience :: Developers",
-  "Programming Language :: Python :: 3.8",
   "Programming Language :: Python :: 3.9",
   "Programming Language :: Python :: 3.10",
   "Programming Language :: Python :: 3.11",
@@ -159,7 +158,7 @@ format-command="ruff format --stdin-filename {filename}"
 # there are a couple of flags that are still disabled by
 # default in strict mode as they are experimental and niche.
 typeCheckingMode = "strict"
-pythonVersion = "3.8"
+pythonVersion = "3.9"
 
 exclude = [
     "_dev",
README.md
@@ -3,7 +3,7 @@
 <!-- prettier-ignore -->
 [![PyPI version](https://img.shields.io/pypi/v/openai.svg?label=pypi%20(stable))](https://pypi.org/project/openai/)
 
-The OpenAI Python library provides convenient access to the OpenAI REST API from any Python 3.8+
+The OpenAI Python library provides convenient access to the OpenAI REST API from any Python 3.9+
 application. The library includes type definitions for all request params and response fields,
 and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
 
@@ -854,7 +854,7 @@ print(openai.__version__)
 
 ## Requirements
 
-Python 3.8 or higher.
+Python 3.9 or higher.
 
 ## Contributing