diff --git a/gitlab_api/utils.py b/gitlab_api/utils.py index 7a2094d..bdfdfa7 100644 --- a/gitlab_api/utils.py +++ b/gitlab_api/utils.py @@ -50,12 +50,18 @@ def pydantic_to_sqlalchemy(pydantic_model): for key, value in pydantic_model.model_dump(exclude_unset=True).items(): if isinstance(value, list): related_instances = [ - pydantic_to_sqlalchemy(item) if hasattr(item, 'Meta') and hasattr(item.Meta, 'orm_model') else item + ( + pydantic_to_sqlalchemy(item) + if hasattr(item, "Meta") and hasattr(item.Meta, "orm_model") + else item + ) for item in value ] setattr(sqlalchemy_instance, key, related_instances) elif isinstance(value, dict): - related_sqlalchemy_model = getattr(sqlalchemy_model, key).property.mapper.class_ + related_sqlalchemy_model = getattr( + sqlalchemy_model, key + ).property.mapper.class_ related_instance = pydantic_to_sqlalchemy(related_sqlalchemy_model(**value)) setattr(sqlalchemy_instance, key, related_instance) else: diff --git a/test/test_utils.py b/test/test_utils.py index c92b23a..c06500a 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -94,14 +94,14 @@ def milestone_fixture(): title="Milestone Title", description="Milestone Description", state="active", - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - updated_at=datetime(2023, 1, 2, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - closed_at=datetime(2023, 1, 3, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + updated_at=datetime(2023, 1, 2, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + closed_at=datetime(2023, 1, 3, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), due_date="2023-02-01", start_date="2023-01-01", web_url="http://example.com", - #issue_stats={"total":10, "closed":5, "opened":5}, - #issue_stats=IssueStats(total=10, closed=5, opened=5), + # issue_stats={"total":10, "closed":5, "opened":5}, + # issue_stats=IssueStats(total=10, closed=5, opened=5), ) @@ -159,8 +159,8 @@ def runner_manager_fixture(): revision="rev1", platform="linux", architecture="x86_64", - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - contacted_at=datetime(2023, 1, 2, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + contacted_at=datetime(2023, 1, 2, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), ip_address="127.0.0.1", status="active", ) @@ -191,8 +191,8 @@ def iteration_fixture(): title="Iteration Title", description="Iteration Description", state=1, - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - updated_at=datetime(2023, 1, 2, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + updated_at=datetime(2023, 1, 2, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), start_date="2023-01-01", due_date="2023-02-01", web_url="http://example.com", @@ -240,7 +240,7 @@ def user_fixture(): locked=False, avatar_url="http://example.com/avatar", web_url="http://example.com", - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), is_admin=False, bio="User bio", location="User location", @@ -251,13 +251,13 @@ def user_fixture(): website_url="http://example.com", organization="User organization", job_title="User job title", - last_sign_in_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - confirmed_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + last_sign_in_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + confirmed_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), theme_id=1, - last_activity_on=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + last_activity_on=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), color_scheme_id=1, projects_limit=10, - current_sign_in_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + current_sign_in_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), note="User note", identities=[], can_create_group=True, @@ -269,8 +269,8 @@ def user_fixture(): last_sign_in_ip="127.0.0.1", namespace_id=1, created_by=1, - email_reset_offered_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - expires_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + email_reset_offered_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + expires_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), access_level=10, group_saml_identity=None, approved=False, @@ -287,7 +287,7 @@ def user_fixture(): extra_shared_runners_minutes_limit=100, membership_type="member", removable=True, - last_login_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + last_login_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), ) @@ -316,7 +316,7 @@ def container_expiration_policy_fixture(): older_than="1w", name_regex=".*", name_regex_keep=".*", - next_run_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + next_run_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), ) @@ -375,7 +375,7 @@ def diff_fixture(): head_commit_sha="abc123", base_commit_sha="def456", start_commit_sha="ghi789", - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), state="active", real_size="large", patch_id_sha="jkl012", @@ -451,7 +451,7 @@ def package_version_fixture(): base_type="PackageVersion", id=1, version="1.0.0", - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), pipelines=None, ) @@ -464,8 +464,8 @@ def package_fixture(): name="package_name", version="1.0.0", package_type="npm", - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - last_downloaded_at=datetime(2023, 1, 2, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + last_downloaded_at=datetime(2023, 1, 2, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), conan_package_name="conan_package", links=None, pipelines=None, @@ -525,8 +525,8 @@ def comment_fixture(): note="Note content", attachment=None, author=None, - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - updated_at=datetime(2023, 1, 2, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + updated_at=datetime(2023, 1, 2, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), system=False, noteable_id=1, noteable_type="Issue", @@ -548,8 +548,8 @@ def membership_fixture(): source_id=1, source_full_name="Source Full Name", source_members_url="http://example.com/members", - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - expires_at=datetime(2023, 1, 2, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + expires_at=datetime(2023, 1, 2, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), access_level={"access_level": 40, "notification_level": 3}, ) @@ -570,8 +570,8 @@ def project_fixture(): name_with_namespace="Namespace / Project Name", path="project_path", path_with_namespace="namespace/project_path", - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - updated_at=datetime(2023, 1, 2, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + updated_at=datetime(2023, 1, 2, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), default_branch="main", tag_list=["tag1", "tag2"], topics=["topic1", "topic2"], @@ -582,7 +582,7 @@ def project_fixture(): avatar_url="http://example.com/avatar", forks_count=10, star_count=20, - last_activity_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + last_activity_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), namespace=None, container_registry_image_prefix="registry.example.com/namespace/project_path", additional_links=None, @@ -718,7 +718,7 @@ def runner_fixture(): name="Runner name", online=True, status="online", - contacted_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + contacted_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), architecture="x86_64", platform="linux", revision="1.0.0", @@ -739,15 +739,15 @@ def job_fixture(): coverage=85.5, archived=False, allow_failure=True, - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - started_at=datetime(2023, 1, 1, 1, 0).strftime('%Y-%m-%d %H:%M:%S'), - finished_at=datetime(2023, 1, 1, 2, 0).strftime('%Y-%m-%d %H:%M:%S'), - erased_at=datetime(2023, 1, 1, 3, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + started_at=datetime(2023, 1, 1, 1, 0).strftime("%Y-%m-%d %H:%M:%S"), + finished_at=datetime(2023, 1, 1, 2, 0).strftime("%Y-%m-%d %H:%M:%S"), + erased_at=datetime(2023, 1, 1, 3, 0).strftime("%Y-%m-%d %H:%M:%S"), duration=3600, queued_duration=600, artifacts_file=None, artifacts=[], - artifacts_expire_at=datetime(2023, 1, 2, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + artifacts_expire_at=datetime(2023, 1, 2, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), tag_list=["tag1", "tag2"], id=1, name="Job name", @@ -820,8 +820,8 @@ def merge_request_fixture(): title="Merge Request Title", description="Merge Request Description", state="opened", - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), - updated_at=datetime(2023, 1, 2, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), + updated_at=datetime(2023, 1, 2, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), target_branch="main", source_branch="feature_branch", upvotes=10, @@ -923,13 +923,13 @@ def issue_fixture(): assignees=[], assignee=None, type="issue", - updated_at=datetime(2023, 1, 2, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + updated_at=datetime(2023, 1, 2, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), closed_at=None, closed_by=None, changes_count="1", id=1, title="Issue title", - created_at=datetime(2023, 1, 1, 0, 0).strftime('%Y-%m-%d %H:%M:%S'), + created_at=datetime(2023, 1, 1, 0, 0).strftime("%Y-%m-%d %H:%M:%S"), moved_to_id=None, iid=101, labels=["label1", "label2"], @@ -1238,7 +1238,9 @@ def test_parse_pydantic_schema(fixture, request): pydantic_model = request.getfixturevalue(fixture) try: sqlalchemy_model = pydantic_to_sqlalchemy(pydantic_model) - pydantic_model_dict = {k: v for k, v in pydantic_model.model_dump().items() if v is not None} + pydantic_model_dict = { + k: v for k, v in pydantic_model.model_dump().items() if v is not None + } logger.debug(f"sqlalchemy_model for {fixture}:\n{sqlalchemy_model}\n") sqlalchemy_model_dict = {k: v for k, v in sqlalchemy_model.__dict__.items()} sqlalchemy_model_dict.pop("_sa_instance_state", None)