Module: dataclass_type_decl
Expand source code
# Copyright (C) 2023-present The Project Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import dataclasses
from dataclasses import dataclass
from typing import Set
from typing import Type
from typing import get_type_hints
from memoization import cached
from typing_extensions import Self
from cl.runtime.schema.element_decl import ElementDecl
from cl.runtime.schema.for_dataclasses.dataclass_field_decl import DataclassFieldDecl
from cl.runtime.schema.type_decl import TypeDecl
from cl.runtime.schema.type_decl import for_type_key_maker
@dataclass(slots=True, kw_only=True)
class DataclassTypeDecl(TypeDecl):
"""Type declaration for a dataclass."""
@classmethod
@cached(custom_key_maker=for_type_key_maker)
def for_type(
cls,
record_type: Type,
*,
dependencies: Set[Type] | None = None,
skip_fields: bool = False,
skip_handlers: bool = False,
) -> Self:
"""
Create or return cached object for the specified record type.
Args:
record_type: Type of the record for which the declaration is created
dependencies: Set of types used in field or methods of the specified type, populated only if not None
skip_fields: Use this flag to skip fields generation when the method is invoked from a derived class
skip_handlers: Use this flag to skip handlers generation when the method is invoked internal methods
"""
if not dataclasses.is_dataclass(record_type):
raise RuntimeError(f"DataclassTypeDecl used for {record_type.__name__} which is not a dataclass.")
# Populate using TypeDecl base
result = TypeDecl.for_type(record_type, dependencies=dependencies, skip_fields=True)
# Use this flag to skip fields generation when the method is invoked from a derived class
if not skip_fields:
# Information about dataclass fields including the metadata (does not resolve ForwardRefs)
fields = dataclasses.fields(record_type)
# Get type hints to resolve ForwardRefs
type_hints = get_type_hints(record_type)
# Dictionary of member comments (docstrings), currently requires source parsing due Python limitations
member_comments = cls.get_member_comments(record_type)
# Add elements
result.elements = []
for field in fields:
# Get type from type hints because they resolve forward references
field_type = type_hints[field.name]
# Field comment (docstring)
field_comment = member_comments.get(field.name, None)
# Get the rest of the data from the field itself
field_decl = DataclassFieldDecl.create(record_type, field, field_type, field_comment)
# Convert to element and add
element_decl = ElementDecl.create(field_decl)
result.elements.append(element_decl)
return result
Classes
class DataclassTypeDecl (*, module: ModuleDeclKey = None, name: str = None, label: str | None = None, comment: str | None = None, kind: TypeKind | None = None, display_kind: DisplayKindLiteral = None, inherit: TypeDeclKey | None = None, declare: HandlerDeclareBlockDecl | None = None, elements: List[ElementDecl] | None = None, keys: List[str] | None = None, immutable: bool | None = None, permanent: bool | None = None)
-
Type declaration for a dataclass.
Expand source code
@dataclass(slots=True, kw_only=True) class DataclassTypeDecl(TypeDecl): """Type declaration for a dataclass.""" @classmethod @cached(custom_key_maker=for_type_key_maker) def for_type( cls, record_type: Type, *, dependencies: Set[Type] | None = None, skip_fields: bool = False, skip_handlers: bool = False, ) -> Self: """ Create or return cached object for the specified record type. Args: record_type: Type of the record for which the declaration is created dependencies: Set of types used in field or methods of the specified type, populated only if not None skip_fields: Use this flag to skip fields generation when the method is invoked from a derived class skip_handlers: Use this flag to skip handlers generation when the method is invoked internal methods """ if not dataclasses.is_dataclass(record_type): raise RuntimeError(f"DataclassTypeDecl used for {record_type.__name__} which is not a dataclass.") # Populate using TypeDecl base result = TypeDecl.for_type(record_type, dependencies=dependencies, skip_fields=True) # Use this flag to skip fields generation when the method is invoked from a derived class if not skip_fields: # Information about dataclass fields including the metadata (does not resolve ForwardRefs) fields = dataclasses.fields(record_type) # Get type hints to resolve ForwardRefs type_hints = get_type_hints(record_type) # Dictionary of member comments (docstrings), currently requires source parsing due Python limitations member_comments = cls.get_member_comments(record_type) # Add elements result.elements = [] for field in fields: # Get type from type hints because they resolve forward references field_type = type_hints[field.name] # Field comment (docstring) field_comment = member_comments.get(field.name, None) # Get the rest of the data from the field itself field_decl = DataclassFieldDecl.create(record_type, field, field_type, field_comment) # Convert to element and add element_decl = ElementDecl.create(field_decl) result.elements.append(element_decl) return result
Ancestors
- TypeDecl
- TypeDeclKey
- KeyMixin
- abc.ABC
- RecordMixin
- typing.Generic
Static methods
def by_pair(iterable)
-
Inherited from:
TypeDecl
.by_pair
s -> (s0,s1), (s1,s2), (s2, s3), …
def for_class_path(class_path: str) -> Self
-
Inherited from:
TypeDecl
.for_class_path
Create or return cached object for the specified class path in module.ClassName format.
def for_key(key: TypeDeclKey) -> Self
-
Inherited from:
TypeDecl
.for_key
Create or return cached object for the specified type declaration key.
def for_type(cls, record_type: Type, *, dependencies: Optional[Set[Type]] = None, skip_fields: bool = False, skip_handlers: bool = False) -> Self
-
Inherited from:
TypeDecl
.for_type
Create or return cached object for the specified record type …
def get_key_type() -> Type
-
Inherited from:
TypeDecl
.get_key_type
Return key type even when called from a record.
def get_member_comments(cls, record_type: type) -> Dict[str, str]
-
Inherited from:
TypeDecl
.get_member_comments
Extract class member comments.
Fields
var comment -> str | None
-
Inherited from:
TypeDecl
.comment
Type comment. Contains additional information.
var declare -> HandlerDeclareBlockDecl | None
-
Inherited from:
TypeDecl
.declare
Handler declaration block.
var display_kind -> Literal['Basic', 'Singleton', 'Dashboard']
-
Inherited from:
TypeDecl
.display_kind
Display kind.
var elements -> Optional[List[ElementDecl]]
-
Inherited from:
TypeDecl
.elements
Element declaration block.
var immutable -> bool | None
-
Inherited from:
TypeDecl
.immutable
Immutable flag.
var inherit -> TypeDeclKey | None
-
Inherited from:
TypeDecl
.inherit
Parent type reference.
var keys -> Optional[List[str]]
-
Array of key element names (specify in base class only).
var kind -> Optional[Literal['final', 'abstract', 'element', 'abstract_element']]
-
Type kind.
var label -> str | None
-
Inherited from:
TypeDecl
.label
Type label.
var module -> ModuleDeclKey
-
Inherited from:
TypeDecl
.module
Module reference.
var name -> str
-
Type name is unique when combined with module.
var permanent -> bool | None
-
Inherited from:
TypeDecl
.permanent
When the record is saved, also save it permanently.
Methods
def get_key(self) -> TypeDeclKey
-
Inherited from:
TypeDecl
.get_key
Return a new key object whose fields populated from self, do not return self.
def init_all(self) -> None
-
Inherited from:
TypeDecl
.init_all
Invoke ‘init’ for each class in the order from base to derived, then validate against schema.
def to_type_decl_dict(self) -> Dict[str, Any]
-
Inherited from:
TypeDecl
.to_type_decl_dict
Convert to dictionary using type declaration conventions.