Skip to content

Commit

Permalink
chore: support for Python 3.10
Browse files Browse the repository at this point in the history
  • Loading branch information
azmeuk committed Nov 7, 2024
1 parent 3a9d459 commit 5a598a6
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 11 deletions.
1 change: 1 addition & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
- '3.13'
- '3.12'
- '3.11'
- '3.10'
steps:
- uses: actions/checkout@v4
- name: Install uv
Expand Down
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ keywords = ["scim", "scim2", "provisioning", "rfc7643", "rfc7644"]
classifiers = [
"Intended Audience :: Developers",
"Development Status :: 4 - Beta",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
Expand All @@ -26,7 +27,7 @@ classifiers = [
"Operating System :: OS Independent",
]

requires-python = ">= 3.11"
requires-python = ">= 3.10"
dependencies = [
"scim2-filter-parser>=0.7.0",
"scim2-models>=0.2.4",
Expand Down Expand Up @@ -106,6 +107,7 @@ doctest_optionflags= "ALLOW_UNICODE IGNORE_EXCEPTION_DETAIL ELLIPSIS"
requires = ["tox>=4.19"]
env_list = [
"style",
"py310",
"py311",
"py312",
"py313",
Expand Down
8 changes: 5 additions & 3 deletions scim2_server/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def register_resource_type(self, resource_type: ResourceType):
self.models_dict[resource_type.id] = Resource.from_schema(base_schema)
if extensions:
self.models_dict[resource_type.id] = self.models_dict[resource_type.id][
Union[*extensions]
Union[tuple(extensions)] # noqa: UP007
]

def get_resource_types(self):
Expand Down Expand Up @@ -332,7 +332,7 @@ def create_resource(
) -> Resource | None:
resource = resource.model_copy(deep=True)
resource.id = uuid.uuid4().hex
utcnow = datetime.datetime.now(datetime.UTC)
utcnow = datetime.datetime.now(datetime.timezone.utc)
resource.meta = Meta(
resource_type=self.resource_types[resource_type_id].name,
created=utcnow,
Expand Down Expand Up @@ -374,7 +374,9 @@ def update_resource(
updated_resource = self.models_dict[resource_type_id].model_validate(
resource.model_dump()
)
self._touch_resource(updated_resource, datetime.datetime.now(datetime.UTC))
self._touch_resource(
updated_resource, datetime.datetime.now(datetime.timezone.utc)
)

for unique_attribute in self.unique_attributes[resource_type_id]:
new_value = unique_attribute.get_attribute(updated_resource)
Expand Down
2 changes: 1 addition & 1 deletion scim2_server/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def query_resource(self, request: Request, resource: ResourceType | None):
for s in results
]

return ListResponse[Union[*self.backend.get_models()]](
return ListResponse[Union[tuple(self.backend.get_models())]]( # noqa: UP007
total_results=total_results,
items_per_page=search_request.count,
start_index=search_request.start_index,
Expand Down
10 changes: 9 additions & 1 deletion scim2_server/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import datetime
import importlib
import json
import re
import sys
from typing import Any

from pydantic import EmailStr
Expand Down Expand Up @@ -178,7 +180,13 @@ def parse_new_value(model: BaseModel, attribute_name: str, value: Any) -> Any:
if field_root_type is bool and isinstance(value, str):
new_value = not value.lower() == "false"
elif field_root_type is datetime.datetime and isinstance(value, str):
new_value = datetime.datetime.fromisoformat(value)
# ISO 8601 datetime format (notably with the Z suffix) are only supported from Python 3.11
if sys.version_info < (3, 11): # pragma: no cover
new_value = datetime.datetime.fromisoformat(
re.sub(r"Z$", "+00:00", value)
)
else:
new_value = datetime.datetime.fromisoformat(value)
elif field_root_type is EmailStr and isinstance(value, str):
new_value = value
elif hasattr(field_root_type, "model_fields"):
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def test_unique_constraints(self, wsgi):
assert r.json()["userName"] == "[email protected]"

def test_sort(self, provider, wsgi):
TypedListResponse = ListResponse[Union[*provider.backend.get_models()]]
TypedListResponse = ListResponse[Union[tuple(provider.backend.get_models())]] # noqa: UP007

def assert_sorted(sort_by: str, sorted: list[str], endpoint: str = "/v2/Users"):
for order_by, inverted in (
Expand Down
8 changes: 6 additions & 2 deletions tests/integration/test_scim_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,13 +544,17 @@ def test_resource_search_post(self, wsgi, first_fake_user):
assert r.status_code == 404

def test_resource_meta_dates(self, wsgi, fake_user_data):
@time_machine.travel(datetime.datetime(2024, 3, 14, 6, 00, tzinfo=datetime.UTC))
@time_machine.travel(
datetime.datetime(2024, 3, 14, 6, 00, tzinfo=datetime.timezone.utc)
)
def create_user():
r = wsgi.post("/v2/Users", json=fake_user_data[1])
assert r.status_code == 201
return r.json()

@time_machine.travel(datetime.datetime(2024, 3, 16, 8, 30, tzinfo=datetime.UTC))
@time_machine.travel(
datetime.datetime(2024, 3, 16, 8, 30, tzinfo=datetime.timezone.utc)
)
def update_user(user_id):
r = wsgi.put(f"/v2/Users/{user_id}", json={"userName": "Foo"})
assert r.status_code == 200
Expand Down
4 changes: 3 additions & 1 deletion tests/test_operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,9 @@ class Foo(Resource):

f = Foo()
AddOperator("dt", "2010-01-23T04:56:22Z")(f)
assert f.dt == datetime.datetime(2010, 1, 23, 4, 56, 22, tzinfo=datetime.UTC)
assert f.dt == datetime.datetime(
2010, 1, 23, 4, 56, 22, tzinfo=datetime.timezone.utc
)

def test_add_operator_extension_simple(self):
u = User[EnterpriseUser]()
Expand Down
Loading

0 comments on commit 5a598a6

Please sign in to comment.