krrood.class_diagrams.class_diagram

Contents

krrood.class_diagrams.class_diagram#

Attributes#

Exceptions#

ParseError

Error that will be raised when the parser encounters something that can/should not be parsed.

Classes#

ClassRelation

Abstract base class representing a relationship between two classes in a UML class diagram.

Inheritance

Represents an inheritance (generalization) relationship in UML.

Association

Represents a general association relationship between two classes.

HasRoleTaker

This is an association between a role and a role taker where the role class contains a role taker field.

AssociationThroughRoleTaker

This is an association between a role and a role taker where the role taker class contains an association. This

WrappedClass

A node wrapper around a Python class used in the class diagram graph.

WrappedSpecializedGeneric

Specialization of WrappedClass for completely parameterized generic types, e.g. Generic[float].

ClassDiagram

A graph of classes and their relations discovered via attribute introspection.

Functions#

make_specialized_dataclass(→ Type)

Build a concrete dataclass for a fully specialized generic alias, e.g., GenericClass[float].

Module Contents#

krrood.class_diagrams.class_diagram.RWXNode = None#
krrood.class_diagrams.class_diagram.logger#
class krrood.class_diagrams.class_diagram.ClassRelation#

Bases: abc.ABC

Abstract base class representing a relationship between two classes in a UML class diagram.

source: WrappedClass#

The source class in the relation.

target: WrappedClass#

The target class in the relation.

index: int | None = None#

The index of the relation in the dependency graph. This is used to uniquely identify the relation.

inferred: bool = False#

Whether this relation was inferred (e.g. associations from role takers) or explicitly defined.

property color: str#

Default edge color used when visualizing the relation.

class krrood.class_diagrams.class_diagram.Inheritance#

Bases: ClassRelation

Represents an inheritance (generalization) relationship in UML.

This is an “is-a” relationship where the source class inherits from the target class. In UML notation, this is represented by a solid line with a hollow triangle pointing to the parent class.

class krrood.class_diagrams.class_diagram.Association#

Bases: ClassRelation

Represents a general association relationship between two classes.

This is the most general form of relationship, indicating that instances of one class are connected to instances of another class. In UML notation, this is shown as a solid line.

wrapped_field: krrood.class_diagrams.wrapped_field.WrappedField#

The field in the source class that creates this association with the target class.

get_original_source_instance_given_this_relation_source_instance(source_instance: Any)#

Given a source instance, returns the original source instance that has the wrapped field of this association.

property many_to_many: bool#

Whether the association is one-to-many (True) or many-to-one (False).

get_key(include_field_name: bool = False) tuple#

A tuple representing the key of the association.

class krrood.class_diagrams.class_diagram.HasRoleTaker#

Bases: Association

This is an association between a role and a role taker where the role class contains a role taker field.

class krrood.class_diagrams.class_diagram.AssociationThroughRoleTaker#

Bases: Association

This is an association between a role and a role taker where the role taker class contains an association. This applies transitively to the role taker’s role takers and so on. The path is a list of fields that are traversed to get to the target class.

wrapped_field: krrood.class_diagrams.wrapped_field.WrappedField#

The last field in the path that is the association to the target class.

association_path: List[Association]#

The path of associations that are traversed to get to the target class.

field_path: List[krrood.class_diagrams.wrapped_field.WrappedField]#

The path of fields that are traversed to get to the target class.

inferred: bool = True#

Redefined inferred to be always true, and never initialized through the init method.

get_original_source_instance_given_this_relation_source_instance(source_instance: Any)#

Resolve the instance that actually owns the target, following the role-taker path.

Walks every field in the path except the last (the association to the target), so the returned instance is the role taker on which the target association is declared.

Parameters:

source_instance – The role instance this association starts from.

Returns:

The instance along the role-taker path that owns the target association.

exception krrood.class_diagrams.class_diagram.ParseError#

Bases: TypeError

Error that will be raised when the parser encounters something that can/should not be parsed.

For instance, Union types

class krrood.class_diagrams.class_diagram.WrappedClass#

Bases: Generic[krrood.utils.T], krrood.patterns.subclass_safe_generic.SubClassSafeGeneric

A node wrapper around a Python class used in the class diagram graph.

index: int | None = None#

The class unique index in the graph.

clazz: Type[krrood.utils.T]#

The class to be wrapped.

property class_to_introspect: Type#
Returns:

The class where the introspector should be called on.

property roles: Tuple[WrappedClass, Ellipsis]#
A tuple of roles that this class plays, represented by the HasRoleTaker instances.

There are HasRoleTaker edges connecting the roles to this class.

property own_fields: List[krrood.class_diagrams.wrapped_field.WrappedField]#
property fields: List[krrood.class_diagrams.wrapped_field.WrappedField]#

Return wrapped fields discovered by the diagram’s attribute introspector.

Public names from the introspector are used to index _wrapped_field_name_map_.

property name: str#
Returns:

The name of the class that is wrapped.

property factory_methods: Tuple[str, Ellipsis]#
Returns:

The names of the factory classmethods of the wrapped class (see krrood.class_diagrams.method_classifier.is_factory_method()).

property name_with_entire_path: str#
class krrood.class_diagrams.class_diagram.WrappedSpecializedGeneric#

Bases: WrappedClass

Specialization of WrappedClass for completely parameterized generic types, e.g. Generic[float].

property name_with_entire_path: str#
property class_to_introspect#
Returns:

The class where the introspector should be called on.

property name#
Returns:

The name of the class that is wrapped.

class krrood.class_diagrams.class_diagram.ClassDiagram#

A graph of classes and their relations discovered via attribute introspection.

classes: List[Type]#

A list of classes to be represented in the diagram.

introspector: krrood.class_diagrams.attribute_introspector.AttributeIntrospector#

The attribute introspector used to discover class attributes.

get_roles_of_class(cls: Type) Tuple[WrappedClass[krrood.patterns.role.Role], Ellipsis]#

Get all roles that are subclasses of the given class.

Parameters:

cls – The class for which to retrieve roles.

Returns:

A tuple of role classes that are roles for the given class (the role taker).

property role_takers: Tuple[Type, Ellipsis]#
Returns:

all classes that are role takers.

get_outgoing_associations_with_condition(clazz: Type | WrappedClass, condition: Callable[[Association], bool]) Iterator[Association]#

Get all outgoing associations that match the condition.

Parameters:
  • clazz – The source class or wrapped class for which outgoing edges are to be retrieved.

  • condition – The condition to filter relations by.

get_incoming_associations_with_condition(clazz: Type | WrappedClass, condition: Callable[[Association], bool]) Iterator[Association]#

Get all incoming associations that match the condition.

Parameters:
  • clazz – The target (class or wrapped class) for which incoming associations are to be retrieved.

  • condition – The condition to filter relations by.

get_outgoing_relations(clazz: Type | WrappedClass) Iterable[ClassRelation]#

Get all outgoing edge relations of the given class.

Parameters:

clazz – The source class or wrapped class for which outgoing edges are to be retrieved.

get_incoming_relations(clazz: Type | WrappedClass) Iterable[ClassRelation]#

Get all incoming edge relations of the given class.

Parameters:

clazz – The target class or wrapped class for which incoming edges are to be retrieved.

get_common_role_taker_associations(cls1: Type | WrappedClass, cls2: Type | WrappedClass) Tuple[HasRoleTaker | None, HasRoleTaker | None]#

Return pair of role-taker associations if both classes point to the same target.

The method checks whether both classes have a HasRoleTaker association to the same target class and returns the matching associations, otherwise (None, None).

get_role_taker_associations_of_cls(cls: Type | WrappedClass) HasRoleTaker | None#

Return the role-taker association of a class if present.

A role taker is a field that is a one-to-one relationship and is not optional.

get_neighbors_with_relation_type(cls: Type | WrappedClass, relation_type: Type[ClassRelation]) Tuple[WrappedClass, Ellipsis]#

Return all neighbors of a class whose connecting edge matches the relation type.

Parameters:
  • cls – The class or wrapped class for which neighbors are to be found.

  • relation_type – The type of the relation to filter edges by.

Returns:

A tuple containing the neighbors of the class, filtered by the specified relation type.

get_outgoing_neighbors_with_relation_type(cls: Type | WrappedClass, relation_type: Type[ClassRelation]) Tuple[WrappedClass, Ellipsis]#

Caches and retrieves the outgoing neighbors of a given class with a specific relation type using the dependency graph.

Parameters:

cls – The class or wrapped class for which outgoing neighbors are to be found. relation_type: The type of the relation to filter edges by.

Returns:

A tuple containing the outgoing neighbors of the class, filtered by the specified relation type.

Raises:

Any exceptions raised internally by find_successors_by_edge or during class wrapping.

get_incoming_neighbors_with_relation_type(cls: Type | WrappedClass, relation_type: Type[ClassRelation]) Tuple[WrappedClass, Ellipsis]#
get_out_edges(cls: Type | WrappedClass) Tuple[ClassRelation, Ellipsis]#

Caches and retrieves the outgoing edges (relations) for the provided class in a dependency graph.

Parameters:

cls – The class or wrapped class for which outgoing edges are to be retrieved.

Returns:

A tuple of outgoing edges (relations) associated with the provided class.

get_in_edges(cls: Type | WrappedClass) Tuple[ClassRelation, Ellipsis]#

Caches and retrieves the incoming edges (relations) for the provided class in a dependency graph.

Parameters:

cls – The class or wrapped class for which incoming edges are to be retrieved.

Returns:

A tuple of incoming edges (relations) associated with the provided class.

property parent_map#

Build parent map from inheritance edges: child_idx -> set(parent_idx)

all_ancestors(node_idx: int) set[int]#

DFS to compute all ancestors for each node index

get_assoc_keys_by_source(include_field_name: bool = False) dict[int, set[tuple]]#

Fetches association keys grouped by their source from the internal dependency graph.

This method traverses the edges of the dependency graph, identifies associations, and groups their keys by their source nodes. Optionally includes the field name of associations in the resulting keys.

Include_field_name:

Optional; If True, includes the field name in the association keys. Defaults to False.

Returns:

A dictionary where the keys are source node identifiers (int), and the values are sets of tuples representing association keys.

to_subdiagram_without_inherited_associations(include_field_name: bool = False) ClassDiagram#

Return a new class diagram where association edges that are present on any ancestor of the source class are removed from descendants.

Inheritance edges are preserved.

remove_edges(edges)#

Remove edges from the dependency graph

property wrapped_classes#

Return all wrapped classes present in the diagram.

property associations: List[Association]#

Return all association relations present in the diagram.

property inheritance_relations: List[Inheritance]#

Return all inheritance relations present in the diagram.

ensure_wrapped_class(clazz: Type) WrappedClass#

Ensures that the provided class type has a corresponding WrappedClass instance. If the class type is already a WrappedClass, it is returned as is. Otherwise, a new WrappedClass instance is created and added to the internal mapping.

Parameters:

clazz – The class type to ensure has a WrappedClass instance.

Returns:

The associated WrappedClass instance.

get_wrapped_class(clazz: Type) WrappedClass#

Gets the wrapped class corresponding to the provided class type.

If the class type is already a WrappedClass, it will be returned as is. Otherwise, the method checks if the class type has an associated WrappedClass in the internal mapping and returns it if found.

:param clazz : The class type to check or retrieve the associated WrappedClass. :return: The associated WrappedClass if it exists, None otherwise.

add_node(clazz: Type | WrappedClass)#

Adds a new node to the dependency graph for the specified wrapped class.

The method sets the position of the given wrapped class in the dependency graph, links it with the current class diagram, and updates the mapping of the underlying class to the wrapped class.

Parameters:

clazz – The wrapped class object to be added to the dependency graph.

property wrapped_classes_of_role_associations_subgraph_in_topological_order: List[WrappedClass]#
Returns:

List of all classes in the association subgraph in topological order.

property wrapped_classes_of_inheritance_subgraph_in_topological_order: List[WrappedClass]#
Returns:

List of all classes in the inheritance subgraph in topological order.

property inheritance_subgraph_without_unreachable_nodes#
Returns:

The subgraph containing only inheritance relations and their incident nodes.

property inheritance_subgraph#
Returns:

The subgraph containing only inheritance relations and their incident nodes.

role_chain_starting_from_node(node: WrappedClass) Tuple[HasRoleTaker]#
Returns:

The role chain starting from the given node following HasRoleTaker edges.

property role_association_subgraph#
Returns:

The subgraph containing only association relations and their incident nodes.

add_relation(relation: ClassRelation)#

Adds a relation to the internal dependency graph.

The method establishes a directed edge in the graph between the source and target indices of the provided relation. This function is used to model dependencies among entities represented within the graph.

Relation:

The relation object that contains the source and target entities and

encapsulates the relationship between them.

to_dot(filepath: str, format_: str = 'svg', graph: rustworkx.PyDiGraph | None = None, without_inherited_associations: bool = True)#

Convert the given graph or the current one if none is given to a dot file that can be converted to the given specified output format.

Parameters:
  • filepath – Filepath to save the output file in.

  • format – Format of the output file.

  • graph – Graph to save the output file to.

  • without_inherited_associations – Whether to remove association relations that are inherited or not.

static graph_to_dot(filepath: str, graph: rustworkx.PyDiGraph, format_: str = 'dot')#

Convert the given graph to a dot file then output it in the given format. The format is dot by default which will output the raw dot file.

Parameters:
  • filepath – Filepath to save the output file in.

  • graph – Graph to save the output file to.

  • format – Format of the output file.

clear()#
krrood.class_diagrams.class_diagram.make_specialized_dataclass(alias: _GenericAlias) Type#

Build a concrete dataclass for a fully specialized generic alias, e.g., GenericClass[float].

The resulting class is intended for internal use only and should never be used directly.

Parameters:

alias – The fully specialized generic alias to build a dataclass for.

Returns:

A concrete dataclass corresponding to the provided alias.