Skip to content

Commit 8d5458b

Browse files
committed
Fix test harness to support py37.
1 parent 5d67344 commit 8d5458b

File tree

6 files changed

+101
-14
lines changed

6 files changed

+101
-14
lines changed

conftest.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,47 @@ def isolate_logging():
4242
sys.stderr = sys.__stderr__
4343
logging.shutdown()
4444
reload(logging)
45+
46+
47+
def pytest_collection_modifyitems(config, items):
48+
"""Skip async-related tests on Python 3.7 since Starlette requires Python 3.8+"""
49+
if sys.version_info >= (3, 8):
50+
return
51+
52+
skip_async = pytest.mark.skip(
53+
reason="Async features require Python 3.8+ (Starlette dependency)"
54+
)
55+
56+
for item in items:
57+
skip_test = False
58+
59+
if hasattr(item, "callspec") and hasattr(item.callspec, "params"):
60+
for param_name, param_value in item.callspec.params.items():
61+
# Check if test has fixtures with async parameters
62+
if isinstance(param_value, str) and (
63+
"async" in param_value or param_value.startswith("async_")
64+
):
65+
skip_test = True
66+
break
67+
# Check if test is parametrized with create_asgi_app
68+
if (
69+
hasattr(param_value, "__name__")
70+
and param_value.__name__ == "create_asgi_app"
71+
):
72+
skip_test = True
73+
break
74+
75+
# Check test file and function names for async-related test files
76+
test_file = str(item.fspath)
77+
test_name = item.name
78+
79+
# Skip tests in async-specific test files
80+
if "test_aio" in test_file:
81+
skip_test = True
82+
83+
# Skip tests that explicitly test async functionality
84+
if "async" in test_name.lower() or "asgi" in test_name.lower():
85+
skip_test = True
86+
87+
if skip_test:
88+
item.add_marker(skip_async)

pyproject.toml

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ name = "functions-framework"
33
version = "3.8.3"
44
description = "An open source FaaS (Function as a service) framework for writing portable Python functions -- brought to you by the Google Cloud Functions team."
55
readme = "README.md"
6-
requires-python = ">=3.5, <4"
6+
requires-python = ">=3.7, <4"
77
# Once we drop support for Python 3.7 and 3.8, this can become
88
# license = "Apache-2.0"
9-
license = {text = "Apache-2.0"}
10-
authors = [
11-
{ name = "Google LLC", email = "[email protected]" }
12-
]
9+
license = { text = "Apache-2.0" }
10+
authors = [{ name = "Google LLC", email = "[email protected]" }]
1311
maintainers = [
14-
{ name = "Google LLC", email = "[email protected]" }
12+
{ name = "Google LLC", email = "[email protected]" },
1513
]
1614
keywords = ["functions-framework"]
1715
classifiers = [
@@ -31,13 +29,14 @@ dependencies = [
3129
"gunicorn>=22.0.0; platform_system!='Windows'",
3230
"cloudevents>=1.2.0,<2.0.0",
3331
"Werkzeug>=0.14,<4.0.0",
32+
"httpx>=0.24.1",
3433
]
3534

3635
[project.urls]
3736
Homepage = "https://github.com/googlecloudplatform/functions-framework-python"
3837

3938
[project.optional-dependencies]
40-
async = ["starlette>=0.37.0,<1.0.0"]
39+
async = ["starlette>=0.37.0,<1.0.0; python_version>='3.8'"]
4140

4241
[project.scripts]
4342
ff = "functions_framework._cli:_cli"
@@ -58,3 +57,15 @@ functions_framework = ["py.typed"]
5857

5958
[tool.setuptools.package-dir]
6059
"" = "src"
60+
61+
[dependency-groups]
62+
dev = [
63+
"black>=23.3.0",
64+
"isort>=5.11.5",
65+
"mypy>=1.4.1",
66+
"pretend>=1.0.9",
67+
"pytest>=7.4.4",
68+
"pytest-asyncio>=0.21.2",
69+
"pytest-cov>=4.1.0",
70+
"pytest-integration>=0.2.3",
71+
]

tests/test_cloud_event_functions.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,24 @@
1313
# limitations under the License.
1414
import json
1515
import pathlib
16+
import sys
1617

1718
import pytest
1819

1920
from cloudevents import conversion as ce_conversion
2021
from cloudevents.http import CloudEvent
21-
from starlette.testclient import TestClient as StarletteTestClient
22+
23+
if sys.version_info >= (3, 8):
24+
from starlette.testclient import TestClient as StarletteTestClient
25+
else:
26+
StarletteTestClient = None
2227

2328
from functions_framework import create_app
24-
from functions_framework.aio import create_asgi_app
29+
30+
if sys.version_info >= (3, 8):
31+
from functions_framework.aio import create_asgi_app
32+
else:
33+
create_asgi_app = None
2534

2635
TEST_FUNCTIONS_DIR = pathlib.Path(__file__).resolve().parent / "test_functions"
2736
TEST_DATA_DIR = pathlib.Path(__file__).resolve().parent / "test_data"

tests/test_decorator_functions.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,26 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
import pathlib
15+
import sys
1516

1617
import pytest
1718

1819
from cloudevents import conversion as ce_conversion
1920
from cloudevents.http import CloudEvent
20-
from starlette.testclient import TestClient as StarletteTestClient
21+
22+
# Conditional import for Starlette
23+
if sys.version_info >= (3, 8):
24+
from starlette.testclient import TestClient as StarletteTestClient
25+
else:
26+
StarletteTestClient = None
2127

2228
from functions_framework import create_app
23-
from functions_framework.aio import create_asgi_app
29+
30+
# Conditional import for async functionality
31+
if sys.version_info >= (3, 8):
32+
from functions_framework.aio import create_asgi_app
33+
else:
34+
create_asgi_app = None
2435

2536
TEST_FUNCTIONS_DIR = pathlib.Path(__file__).resolve().parent / "test_functions"
2637

tests/test_functions.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,27 @@
1515
import json
1616
import pathlib
1717
import re
18+
import sys
1819
import time
1920

2021
import pretend
2122
import pytest
2223

23-
from starlette.testclient import TestClient as StarletteTestClient
24+
# Conditional import for Starlette
25+
if sys.version_info >= (3, 8):
26+
from starlette.testclient import TestClient as StarletteTestClient
27+
else:
28+
StarletteTestClient = None
2429

2530
import functions_framework
2631

2732
from functions_framework import LazyWSGIApp, create_app, errorhandler, exceptions
28-
from functions_framework.aio import create_asgi_app
33+
34+
# Conditional import for async functionality
35+
if sys.version_info >= (3, 8):
36+
from functions_framework.aio import create_asgi_app
37+
else:
38+
create_asgi_app = None
2939

3040
TEST_FUNCTIONS_DIR = pathlib.Path.cwd() / "tests" / "test_functions"
3141

tox.ini

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ deps =
3030
pytest-integration
3131
pretend
3232
extras =
33-
async
33+
# Only include async extra for Python 3.8+
34+
py{38,39,310,311,312}: async
3435
setenv =
3536
PYTESTARGS = --cov=functions_framework --cov-branch --cov-report term-missing --cov-fail-under=100
3637
windows-latest: PYTESTARGS =
@@ -44,6 +45,7 @@ deps =
4445
isort
4546
mypy
4647
build
48+
extras = async
4749
commands =
4850
black --check src tests conftest.py --exclude tests/test_functions/background_load_error/main.py
4951
isort -c src tests conftest.py

0 commit comments

Comments
 (0)