Duplicite teardown (and setup) with Dynamic test cases

I found an example how to dynamically create tests. Only problem is, that the teardown is beeing executed 2 times for test that PASS and 1 time for FAILED test. I was playing with _end_test(self, data, result), but didn’t move much. Is there any simple way how to avoid to run the teardown 2 times?

Here is Robot code:

*** Settings ***
Documentation   Test cases for dynamic test cases.
# Library files
Library     Lib/DynamicTestCases.py

*** Keywords ***
Keyword To Execute
    [Arguments]    ${variable}
    Log    The variable sent to the test was: ${variable}
    Log To Console  This is keyword to execute ${variable}
    should be equal        ${variable}    "Test 1"

Setup keyword
    ${variable}    Set Variable    \nThis is from the setup keyword
    Log  ${variable}
    Log To Console  ${variable}

Teardown keyword
    [TAGS]    placeholder
    ${variable}    Set Variable    This is from the teardown keyword
    Log  ${variable}
    Log To Console  ${variable}

*** Test Cases ***
Create Dynamic Test Cases
    @{TestNamesList}    Create List    "Test 1"    "Test 2"
    FOR    ${element}    IN    @{TestNamesList}
        ${testCase} =  AddTestCase  ${element}  dynamic_tag_${element}
        AddSetupToTestCase  ${testCase}  Setup keyword
        AddKeywordToTestCase  ${testCase}  Keyword To Execute  ${element}
        AddTeardownToTestCase  ${testCase}  Teardown keyword
    END

This is python code:

from robot.running.model import  TestCase, Keyword       
from robot.api import logger
import sys
class DynamicTestCases:
    ROBOT_LISTENER_API_VERSION = 3
    ROBOT_LIBRARY_SCOPE = 'TEST SUITE'

    def __init__(self):
        self.ROBOT_LIBRARY_LISTENER = self
        self.currentSuite = None

    def _start_suite(self, suite, result):
        self.currentSuite = suite

	#following didn't work and therefore commented:
    #def _end_test(self, data, result):
    #    if data.has_teardown:
    #    	if result.failed:
    #    	   data.teardown = data.teardown

    def AddTestCase(self, name, tags):
        """
        Adds a test case to the current suite

        Args:
            - name: is the test case name
            - tags: is a list of tags to add to the test case

        Returns: The test case that was added
        """
        testCase = self.currentSuite.tests.create(name=name, tags=tags)
        return testCase

    def AddKeywordToTestCase(self, testCase, keywordName, *args):
        """
        Adds a keyword to the given test case.

        Args:
            - testCase: The test case to add the keyword to
            - keywordName: The name of the keyword to add
            - *args: The arguments to pass to the keyword
        """
        testCase.body.create_keyword(name=keywordName, args=args)


    def AddSetupToTestCase(self, testCase: TestCase, keywordName: str, *args) -> Keyword:
        """
        Adds a setup keyword to the given test case.

        Args:
            - testCase: The test case to add the keyword to
            - keywordName: The name of the keyword to add
            - *args: The arguments to pass to the keyword
        """
        setupKeyword = testCase.body.create_keyword(name=keywordName, args=args, type='setup')
        #Commented as it crete setup 2x
		#testCase.setup = setupKeyword
        return setupKeyword

    def AddTeardownToTestCase(self, testCase: TestCase, keywordName: str, *args) -> Keyword:
        """
        Adds a teardown keyword to the given test case.
        It is executed twice if the test PASS, and once if test FAIL

        Args:
            - testCase: The test case to add the keyword to
            - keywordName: The name of the keyword to add
            - *args: The arguments to pass to the keyword
        """
        # following create 1st teardown, that is executed as normal keyword and it's not executed when the test fails 
        teardownKeyword = testCase.body.create_keyword(name=keywordName, args=args, type='teardown')
        #Following ads the teardown that works as teardown - run no matter of test result
        testCase.teardown = teardownKeyword
        return teardownKeyword

I found the answer:

    teardownKeyword = testCase.body.create_keyword(name=keywordName, args=args, type='teardown')
    # remove duplicite teardown
    testCase.body.remove(teardownKeyword) 
    testCase.teardown = teardownKeyword
    return teardownKeyword

Better idea:

testCase.teardown = Keyword(name=keywordName, args=args, type='teardown')