Skip to content

Commit ee2de71

Browse files
committed
refactor: extract *ComplexAttribute classes in their own file
1 parent db9e367 commit ee2de71

16 files changed

+89
-75
lines changed

scim2_models/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
from .annotations import Required
44
from .annotations import Returned
55
from .annotations import Uniqueness
6+
from .attributes import ComplexAttribute
7+
from .attributes import MultiValuedComplexAttribute
68
from .base import BaseModel
7-
from .base import ComplexAttribute
8-
from .base import MultiValuedComplexAttribute
99
from .context import Context
1010
from .reference import ExternalReference
1111
from .reference import Reference

scim2_models/attributes.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from inspect import isclass
2+
from typing import Annotated
3+
from typing import Any
4+
from typing import Optional
5+
from typing import get_origin
6+
7+
from pydantic import Field
8+
9+
from .annotations import Mutability
10+
11+
# This import will work because we'll import this module after BaseModel is defined
12+
from .base import BaseModel
13+
from .reference import Reference
14+
15+
16+
class ComplexAttribute(BaseModel):
17+
"""A complex attribute as defined in :rfc:`RFC7643 §2.3.8 <7643#section-2.3.8>`."""
18+
19+
_schema: Optional[str] = None
20+
21+
def get_attribute_urn(self, field_name: str) -> str:
22+
"""Build the full URN of the attribute.
23+
24+
See :rfc:`RFC7644 §3.10 <7644#section-3.10>`.
25+
"""
26+
alias = (
27+
self.__class__.model_fields[field_name].serialization_alias or field_name
28+
)
29+
return f"{self._schema}.{alias}"
30+
31+
32+
class MultiValuedComplexAttribute(ComplexAttribute):
33+
type: Optional[str] = None
34+
"""A label indicating the attribute's function."""
35+
36+
primary: Optional[bool] = None
37+
"""A Boolean value indicating the 'primary' or preferred attribute value
38+
for this attribute."""
39+
40+
display: Annotated[Optional[str], Mutability.immutable] = None
41+
"""A human-readable name, primarily used for display purposes."""
42+
43+
value: Optional[Any] = None
44+
"""The value of an entitlement."""
45+
46+
ref: Optional[Reference] = Field(None, serialization_alias="$ref")
47+
"""The reference URI of a target resource, if the attribute is a
48+
reference."""
49+
50+
51+
def is_complex_attribute(type_: type) -> bool:
52+
# issubclass raise a TypeError with 'Reference' on python < 3.11
53+
return (
54+
get_origin(type_) != Reference
55+
and isclass(type_)
56+
and issubclass(type_, (ComplexAttribute, MultiValuedComplexAttribute))
57+
)

scim2_models/base.py

Lines changed: 4 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from inspect import isclass
2-
from typing import Annotated
32
from typing import Any
43
from typing import Optional
54
from typing import get_args
@@ -8,7 +7,6 @@
87
from pydantic import AliasGenerator
98
from pydantic import BaseModel as PydanticBaseModel
109
from pydantic import ConfigDict
11-
from pydantic import Field
1210
from pydantic import FieldSerializationInfo
1311
from pydantic import SerializationInfo
1412
from pydantic import SerializerFunctionWrapHandler
@@ -25,7 +23,6 @@
2523
from scim2_models.annotations import Required
2624
from scim2_models.annotations import Returned
2725
from scim2_models.context import Context
28-
from scim2_models.reference import Reference
2926
from scim2_models.utils import normalize_attribute_name
3027
from scim2_models.utils import to_camel
3128

@@ -341,6 +338,8 @@ def check_mutability_issues(
341338
cls, original: "BaseModel", replacement: "BaseModel"
342339
) -> None:
343340
"""Compare two instances, and check for differences of values on the fields marked as immutable."""
341+
from .attributes import is_complex_attribute
342+
344343
model = replacement.__class__
345344
for field_name in model.model_fields:
346345
mutability = model.get_field_annotation(field_name, Mutability)
@@ -371,6 +370,8 @@ def mark_with_schema(self) -> None:
371370
"""
372371
from scim2_models.rfc7643.resource import Resource
373372

373+
from .attributes import is_complex_attribute
374+
374375
for field_name in self.__class__.model_fields:
375376
attr_type = self.get_field_root_type(field_name)
376377
if not attr_type or not is_complex_attribute(attr_type):
@@ -579,48 +580,4 @@ def get_attribute_urn(self, field_name: str) -> str:
579580
return full_urn
580581

581582

582-
class ComplexAttribute(BaseModel):
583-
"""A complex attribute as defined in :rfc:`RFC7643 §2.3.8 <7643#section-2.3.8>`."""
584-
585-
_schema: Optional[str] = None
586-
587-
def get_attribute_urn(self, field_name: str) -> str:
588-
"""Build the full URN of the attribute.
589-
590-
See :rfc:`RFC7644 §3.10 <7644#section-3.10>`.
591-
"""
592-
alias = (
593-
self.__class__.model_fields[field_name].serialization_alias or field_name
594-
)
595-
return f"{self._schema}.{alias}"
596-
597-
598-
class MultiValuedComplexAttribute(ComplexAttribute):
599-
type: Optional[str] = None
600-
"""A label indicating the attribute's function."""
601-
602-
primary: Optional[bool] = None
603-
"""A Boolean value indicating the 'primary' or preferred attribute value
604-
for this attribute."""
605-
606-
display: Annotated[Optional[str], Mutability.immutable] = None
607-
"""A human-readable name, primarily used for display purposes."""
608-
609-
value: Optional[Any] = None
610-
"""The value of an entitlement."""
611-
612-
ref: Optional[Reference] = Field(None, serialization_alias="$ref")
613-
"""The reference URI of a target resource, if the attribute is a
614-
reference."""
615-
616-
617-
def is_complex_attribute(type_: type) -> bool:
618-
# issubclass raise a TypeError with 'Reference' on python < 3.11
619-
return (
620-
get_origin(type_) != Reference
621-
and isclass(type_)
622-
and issubclass(type_, (ComplexAttribute, MultiValuedComplexAttribute))
623-
)
624-
625-
626583
BaseModelType: type = type(BaseModel)

scim2_models/rfc7643/enterprise_user.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
from pydantic import Field
66

7-
from ..base import ComplexAttribute
8-
from ..base import Mutability
9-
from ..base import Required
7+
from ..annotations import Mutability
8+
from ..annotations import Required
9+
from ..attributes import ComplexAttribute
1010
from ..reference import Reference
1111
from .resource import Extension
1212

scim2_models/rfc7643/group.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66

77
from pydantic import Field
88

9-
from ..base import ComplexAttribute
10-
from ..base import MultiValuedComplexAttribute
11-
from ..base import Mutability
12-
from ..base import Required
9+
from ..annotations import Mutability
10+
from ..annotations import Required
11+
from ..attributes import ComplexAttribute
12+
from ..attributes import MultiValuedComplexAttribute
1313
from ..reference import Reference
1414
from .resource import Resource
1515

scim2_models/rfc7643/resource.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
from ..annotations import Required
2525
from ..annotations import Returned
2626
from ..annotations import Uniqueness
27+
from ..attributes import ComplexAttribute
28+
from ..attributes import MultiValuedComplexAttribute
29+
from ..attributes import is_complex_attribute
2730
from ..base import BaseModel
2831
from ..base import BaseModelType
29-
from ..base import ComplexAttribute
30-
from ..base import MultiValuedComplexAttribute
31-
from ..base import is_complex_attribute
3232
from ..reference import ExternalReference
3333
from ..reference import URIReference
3434
from ..utils import UNION_TYPES

scim2_models/rfc7643/resource_type.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from ..annotations import Mutability
1111
from ..annotations import Required
1212
from ..annotations import Returned
13-
from ..base import ComplexAttribute
13+
from ..attributes import ComplexAttribute
1414
from ..reference import Reference
1515
from ..reference import URIReference
1616
from ..utils import UNION_TYPES

scim2_models/rfc7643/schema.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
from ..annotations import Required
2222
from ..annotations import Returned
2323
from ..annotations import Uniqueness
24+
from ..attributes import ComplexAttribute
25+
from ..attributes import MultiValuedComplexAttribute
26+
from ..attributes import is_complex_attribute
2427
from ..base import BaseModel
25-
from ..base import ComplexAttribute
26-
from ..base import MultiValuedComplexAttribute
27-
from ..base import is_complex_attribute
2828
from ..constants import RESERVED_WORDS
2929
from ..reference import ExternalReference
3030
from ..reference import Reference

scim2_models/rfc7643/service_provider_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from ..annotations import Required
99
from ..annotations import Returned
1010
from ..annotations import Uniqueness
11-
from ..base import ComplexAttribute
11+
from ..attributes import ComplexAttribute
1212
from ..reference import ExternalReference
1313
from ..reference import Reference
1414
from .resource import Resource

scim2_models/rfc7643/user.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
from ..annotations import Required
1414
from ..annotations import Returned
1515
from ..annotations import Uniqueness
16-
from ..base import ComplexAttribute
17-
from ..base import MultiValuedComplexAttribute
16+
from ..attributes import ComplexAttribute
17+
from ..attributes import MultiValuedComplexAttribute
1818
from ..reference import ExternalReference
1919
from ..reference import Reference
2020
from ..utils import Base64Bytes

0 commit comments

Comments
 (0)