From 2a8f715005b424eca83c26f9024ade196f53c8d4 Mon Sep 17 00:00:00 2001 From: Mark Peek Date: Sun, 6 Mar 2022 16:19:55 -0800 Subject: [PATCH] Prototype intellisense by emitting function signatures for all classes --- scripts/gen.py | 46 ++++++++++++++++++++++++++++++++--------- troposphere/__init__.py | 3 ++- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/scripts/gen.py b/scripts/gen.py index 1652b1773..c8217ccb3 100755 --- a/scripts/gen.py +++ b/scripts/gen.py @@ -410,7 +410,6 @@ def __init__(self, service_name: str, service: Service): self.resources: Dict[str, ResourceType] = service.resources self.properties: Dict[str, PropertyType] = service.properties self.property_validators = service.property_validators - self.statement_found = False def generate(self, file=None) -> str: """Generated the troposphere source code.""" @@ -428,6 +427,8 @@ def generate(self, file=None) -> str: if self._walk_for_tags(): code.append("from . import Tags") code.append("from . import PropsDictType") + code.append("from . import Template") + code.append("from typing import Optional") if not stub: # Output imports for commonly used validators @@ -526,13 +527,6 @@ def _build_tree( # prevent recursive properties if property_name == name: continue - # This is a horrible hack to fix an indirect recursion issue in WAFv2 - # XXX - Need to implement a more durable solution to detect recursion - if self.service_name == "wafv2" and property_name == "Statement": - if self.statement_found: - continue - else: - self.statement_found = True try: child = self._build_tree( @@ -676,10 +670,13 @@ def _get_type(self, value: Property, stub=False): if value.type == "List": if value.item_type: - return "[%s]" % value.item_type + if stub: + return "'list[%s]'" % value.item_type + else: + return "[%s]" % value.item_type else: if stub: - return "[%s]" % map_stub_type.get( + return "'list[%s]'" % map_stub_type.get( value.primitive_item_type, value.primitive_item_type ) else: @@ -722,7 +719,36 @@ def _generate_class( code.append(' """') code.append("") + if len(property_type.properties) == 0: + code.append( + " def __init__(self, title: Optional[str], template: Optional[Template] = None, validation: bool = True):" + ) + code.append(" super().__init__(title, template, validation,)") + else: + # Output the __init__ function + code.append( + " def __init__(self, title: Optional[str], template: Optional[Template] = None, validation: bool = True, *," + ) + for key, value in sorted(property_type.properties.items()): + if property_validator and key in property_validator: + value_type = property_validator[key] + elif value.type == "Tags": + value_type = value.type + if value.primitive_type == "Json": + value_type = "dict" + else: + value_type = self._get_type(value, stub=True) + + code.append(f" {key}: {value_type} = None,") + code.append("):") + + code.append(" super().__init__(title, template, validation,") + for key, value in sorted(property_type.properties.items()): + code.append(f" {key}={key}, ") + code.append(" )") + # Output the props dict + code.append("") code.append(" props: PropsDictType = {") for key, value in sorted(property_type.properties.items()): if property_validator and key in property_validator: diff --git a/troposphere/__init__.py b/troposphere/__init__.py index 0116d4955..dacf620f7 100644 --- a/troposphere/__init__.py +++ b/troposphere/__init__.py @@ -200,7 +200,8 @@ def __init__( # Now that it is initialized, populate it with the kwargs for k, v in kwargs.items(): - self.__setattr__(k, v) + if v is not None: + self.__setattr__(k, v) self.add_to_template()