{% import "class_parameters.py.j2" as class_parameters %}
from datetime import datetime, date, time
{% set ns = namespace(abstract_found=false) -%}
{% for class in classes -%}
    {% if class.is_abstract -%}
        {% set ns.abstract_found = true -%}
    {% endif -%}    
{% endfor -%}
{% if ns.abstract_found -%}
from abc import ABC, abstractmethod
{% endif -%}
{# Two newlines are added here unconditionally #}
{% for class in classes %}
class {{ class.name }}{% if class.parents() %}({% for parent in class.parents() %}{{parent.name}}{{ ", " if not loop.last else "" }}{% endfor %}){% elif class.is_abstract %}(ABC){% endif %}:
    def __init__({{ class_parameters.init_parameters(class) }}):
        {{ class_parameters.init_parameters_definition(class) }}

    {%- for attribute in class.attributes %}
    @property
    def {{ attribute.name }}(self) -> {{ attribute.type.name }}:
        return self.__{{ attribute.name }}
    
    @{{ attribute.name }}.setter
    def {{ attribute.name }}(self, {{ attribute.name }}: {{ attribute.type.name }}):
        self.__{{ attribute.name }} = {{ attribute.name }}
    {% endfor -%}

    {% for end in class.association_ends() %}{% if end.is_navigable == True %}
    @property
    def {{ end.name }}(self):
        return self.__{{ end.name }}
    
    @{{ end.name }}.setter
    def {{ end.name }}(self, {{ end.name }}):
        self.__{{ end.name }} = {{ end.name }}
    {% endif -%}{% endfor -%}

{% endfor %}