yaal-coop / scim2-models

SCIM resources serialization and validation with Pydantic
https://scim2-models.readthedocs.io
Apache License 2.0
5 stars 2 forks source link

Multiple extensions do not work as described in the Tutorial #37

Closed ccoors closed 1 week ago

ccoors commented 1 week ago

In the tutorial it says that schema extensions can be added to Resources like this:

user = User[EnterpriseUser, SuperHero]

Unfortunately that doesn't work, neither with the provided models nor with custom models. I added this test case in test_dynamic_resources.py:

def test_make_custom_model_schema(load_sample):
    payload_base = {
            "id": "test:foo:Object",
            "name": "Object",
            "description": "Base Object",
            "attributes": [
                {
                    "name": "description",
                    "type": "string",
                    "multiValued": False,
                    "description": "The description of the object",
                    "required": False,
                    "caseExact": False,
                    "mutability": "readWrite",
                    "returned": "default",
                    "uniqueness": "server"
                }
            ],
            "meta": {
                "resourceType": "Schema",
                "location": "/v2/Schemas/test:foo:Object"
            }
        }
    payload_extension_1 = {
        "id": "test:foo:Extension1",
        "name": "Object Extension 1",
        "description": "Object Extension 1",
        "attributes": [
            {
                "name": "color",
                "type": "string",
                "multiValued": False,
                "description": "The color of the object",
                "required": False,
                "caseExact": False,
                "mutability": "readWrite",
                "returned": "default",
                "uniqueness": "server"
            }
        ],
        "meta": {
            "resourceType": "Schema",
            "location": "/v2/Schemas/test:foo:Extension1"
        }
    }
    payload_extension_2 = {
        "id": "test:foo:Extension2",
        "name": "Object Extension 2",
        "description": "Object Extension 2",
        "attributes": [
                {
                    "name": "weight",
                    "type": "integer",
                    "multiValued": False,
                    "description": "The weight of the object",
                    "required": False,
                    "caseExact": False,
                    "mutability": "readWrite",
                    "returned": "default",
                    "uniqueness": "server"
                }
            ],
        "meta": {
            "resourceType": "Schema",
            "location": "/v2/Schemas/test:foo:Extension2"
        }
    }
    extension_schema_1 = Schema.model_validate(payload_extension_1)
    extension_model_1 = extension_schema_1.make_model()
    extension_schema_2 = Schema.model_validate(payload_extension_2)
    extension_model_2 = extension_schema_2.make_model()
    base_schema = Schema.model_validate(payload_base)
    ObjectModel = base_schema.make_model()[extension_model_1, extension_model_2]

And get this error message:

[...]
>           raise TypeError(f'Too {description} parameters for {cls}; actual {actual}, expected {expected}')
E           TypeError: Too many parameters for <class 'scim2_models.rfc7643.schema.Object'>; actual 2, expected 1
azmeuk commented 1 week ago

Hi. Thank you for the bug report. I will look at this quickly.

azmeuk commented 1 week ago

This is fixed in 0.1.8. Actually it is needed to use an union user = User[Union[EnterpriseUser, SuperHero]]

The User[EnterpriseUser, SuperHero] syntax could be used starting with python 3.11 thanks to PEP646, but it seems there are missing pieces in pydantic at the moment.