6
6
Collection )
7
7
import warnings
8
8
9
- from .ast_utils import get_enclosing_namespace
9
+ from .ast_utils import get_enclosing_namespace , g
67E6
et_enum_module_and_export_name
10
10
11
11
from .predefined_types import PREDEFINED_TYPES
12
12
13
- from .nodes import (ASTNode , NamespaceNode , ClassNode , FunctionNode ,
13
+ from .nodes import (ASTNode , ASTNodeType , NamespaceNode , ClassNode , FunctionNode ,
14
14
EnumerationNode , ConstantNode )
15
15
16
16
from .nodes .type_node import (TypeNode , AliasTypeNode , AliasRefTypeNode ,
17
- AggregatedTypeNode )
17
+ AggregatedTypeNode , ASTNodeTypeNode )
18
18
19
19
20
20
def generate_typing_stubs (root : NamespaceNode , output_path : Path ):
@@ -616,29 +616,67 @@ def register_alias_links_from_aggregated_type(type_node: TypeNode) -> None:
616
616
for item in filter (lambda i : isinstance (i , AliasRefTypeNode ), type_node ):
617
617
register_alias (PREDEFINED_TYPES [item .ctype_name ]) # type: ignore
618
618
619
+ def create_alias
A3E2
_for_enum_node (enum_node : ASTNode ) -> AliasTypeNode :
620
+ """Create int alias corresponding to the given enum node.
621
+
622
+ Args:
623
+ enum_node (ASTNodeTypeNode): Enumeration node to create int alias for.
624
+
625
+ Returns:
626
+ AliasTypeNode: int alias node with same export name as enum.
627
+ """
628
+ assert enum_node .node_type == ASTNodeType .Enumeration , \
629
+ f"{ enum_node } has wrong node type. Expected type: Enumeration."
630
+
631
+ enum_export_name , enum_module_name = get_enum_module_and_export_name (
632
+ enum_node
633
+ )
634
+ enum_full_export_name = f"{ enum_module_name } .{ enum_export_name } "
635
+ alias_node = AliasTypeNode .int_ (enum_full_export_name ,
636
+ enum_export_name )
637
+ type_checking_time_definitions .add (alias_node )
638
+ return alias_node
639
+
619
640
def register_alias (alias_node : AliasTypeNode ) -> None :
620
641
typename = alias_node .typename
621
642
# Check if alias is already registered
622
643
if typename in aliases :
623
644
return
645
+
646
+ # Collect required imports for alias definition
647
+ for required_import in alias_node .required_definition_imports :
648
+ required_imports .add (required_import )
649
+
624
650
if isinstance (alias_node .value , AggregatedTypeNode ):
625
651
# Check if collection contains a link to another alias
626
652
register_alias_links_from_aggregated_type (alias_node .value )
627
653
654
+ # Remove references to alias nodes
655
+ for i , item in enumerate (alias_node .value .items ):
656
+ # Process enumerations only
657
+ if not isinstance (item , ASTNodeTypeNode ) or item .ast_node is None :
658
+ continue
659
+ if item .ast_node .node_type != ASTNodeType .Enumeration :
660
+ continue
661
+ alias_node .value .items [i ] = create_alias_for_enum_node (item .ast_node )
662
+
663
+ if isinstance (alias_node .value , ASTNodeTypeNode ) \
664
+ and alias_node .value .ast_node == ASTNodeType .Enumeration :
665
+ alias_node .value = create_alias_for_enum_node (alias_node .ast_node )
666
+
628
667
# Strip module prefix from aliased types
629
668
aliases [typename ] = alias_node .value .full_typename .replace (
630
669
root .export_name + ".typing." , ""
631
670
)
632
671
if alias_node .doc is not None :
633
672
aliases [typename ] += f'\n """{ alias_node .doc } """'
634
- for required_import in alias_node .required_definition_imports :
635
- required_imports .add (required_import )
636
673
637
674
output_path = Path (output_path ) / root .export_name / "typing"
638
675
output_path .mkdir (parents = True , exist_ok = True )
639
676
640
677
required_imports : Set [str ] = set ()
641
678
aliases : Dict [str , str ] = {}
679
+ type_checking_time_definitions : Set [AliasTypeNode ] = set ()
642
680
643
681
# Resolve each node and register aliases
644
682
TypeNode .compatible_to_runtime_usage = True
@@ -655,11 +693,16 @@ def register_alias(alias_node: AliasTypeNode) -> None:
655
693
656
694
_write_required_imports (required_imports , output_stream )
657
695
696
+ # Add type checking time definitions as generated __init__.py content
697
+ for alias in type_checking_time_definitions :
698
+ output_stream .write ("if typing.TYPE_CHECKING:\n " )
699
+ output_stream .write (f"{ alias .typename } = { alias .ctype_name } \n else:\n " )
700
+ output_stream .write (f" { alias .typename } = { alias .value .ctype_name } \n " )
701
+ if type_checking_time_definitions :
702
+ output_stream .write ("\n \n " )
703
+
658
704
for alias_name , alias_type in aliases .items ():
659
- output_stream .write (alias_name )
660
- output_stream .write (" = " )
661
- output_stream .write (alias_type )
662
- output_stream .write ("\n " )
705
+ output_stream .write (f"{ alias_name } = { alias_type } \n " )
663
706
664
707
TypeNode .compatible_to_runtime_usage = False
665
708
(output_path / "__init__.py" ).write_text (output_stream .getvalue ())
0 commit comments