Beispiel #1
0
def generate_set_None(gen_dict, class_dict):
    """Generate the code for the _set_None method of the class

    Parameters
    ----------
    gen_dict : dict
        Dict with key = class name and value = class dict (name, package, properties, methods...)

    class_dict : dict
        Dictionnary of the class to generate (keys are name, package, properties, methods...)

    Returns
    -------
    None_str : str
        String containing the code for the _set_None method of the class
    """

    class_name = class_dict["name"]
    None_str = ""  # This string is for the generated code

    # Code line to set every properties to None (except pyleecan object)
    var_str = ""

    for prop in class_dict["properties"]:
        if (
            prop["type"] in PYTHON_TYPE
            or prop["type"] in ["ndarray", "function"]
            or "." in prop["type"]
        ):
            var_str += TAB2 + "self." + prop["name"] + " = None\n"
        elif is_list_pyleecan_type(prop["type"]):
            var_str += TAB2 + "for obj in self." + prop["name"] + ":\n"
            var_str += TAB3 + "obj._set_None()\n"
        elif prop["type"] == "{ndarray}":
            var_str += TAB2 + "self." + prop["name"] + " = dict()\n"
        elif is_dict_pyleecan_type(prop["type"]):
            var_str += TAB2 + "for key, obj in self." + prop["name"] + ".items():\n"
            var_str += TAB3 + "obj._set_None()\n"
        else:  # Pyleecan type
            var_str += TAB2 + "if self." + prop["name"] + " is not None:\n"
            var_str += TAB3 + "self." + prop["name"] + "._set_None()\n"

    # Code generation
    None_str += TAB + "def _set_None(self):\n"
    None_str += (
        TAB2 + '"""Set all the properties to None (except ' + 'pyleecan object)"""\n\n'
    )
    None_str += var_str
    if class_dict["mother"] != "":
        # Get the properties of the mother class (if needed)
        None_str += (
            TAB2
            + "# Set to None the properties inherited from "
            + class_dict["mother"]
            + "\n"
        )
        None_str += TAB2 + "super(" + class_name + ", self)._set_None()\n"

    return None_str
Beispiel #2
0
def generate_properties(gen_dict, class_dict):
    """Generate the code for the getter and setter of the properties of the class

    Parameters
    ----------
    gen_dict : dict
        Dict with key = class name and value = class dict (name, package, properties, methods...)

    class_dict : dict
        Dictionnary of the class to generate (keys are name, package, properties, methods...)

    Returns
    -------
    prop_str : str
        String containing the code for the getter and setter of the properties of the class
    """

    prop_str = ""  # This string is for the generated code

    for prop in class_dict["properties"]:
        # Getter
        prop_str += TAB + "def _get_" + prop["name"] + "(self):\n"
        prop_str += TAB2 + '"""getter of ' + prop["name"] + '"""\n'
        if is_list_pyleecan_type(prop["type"]):
            # TODO: Update the parent should be done only in the setter but
            # their is an issue with .append for list of pyleecan type
            prop_str += TAB2 + "for obj in self._" + prop["name"] + ":\n"
            prop_str += TAB3 + "if obj is not None:\n"
            prop_str += TAB4 + "obj.parent = self\n"
        prop_str += TAB2 + "return self._" + prop["name"] + "\n\n"

        # Setter
        prop_str += TAB + "def _set_" + prop["name"] + "(self, value):\n"
        prop_str += TAB2 + '"""setter of ' + prop["name"] + '"""\n'
        # Convert ndarray if needed
        if prop["type"] == "ndarray":
            prop_str += TAB2 + "if type(value) is list:\n"
            prop_str += TAB3 + "try:\n"
            prop_str += TAB4 + "value = array(value)\n"
            prop_str += TAB3 + "except:\n"
            prop_str += TAB4 + "pass\n"

        # Add check_var("var_name",value, "var_type", min=var_min, max=var_max)
        prop_str += (TAB2 + 'check_var("' + prop["name"] + '", value, "' +
                     prop["type"] + '"')
        # Min and max are added only if needed
        if prop["type"] in ["float", "int", "ndarray"]:
            if str(prop["min"]) is not "":
                prop_str += ", Vmin=" + str(prop["min"])
            if str(prop["max"]) is not "":
                prop_str += ", Vmax=" + str(prop["max"])
        prop_str += ")\n"

        prop_str += TAB2 + "self._" + prop["name"] + " = value\n\n"
        if is_list_pyleecan_type(prop["type"]):
            # List of pyleecan type
            prop_str += TAB2 + "for obj in self._" + prop["name"] + ":\n"
            prop_str += TAB3 + "if obj is not None:\n"
            prop_str += TAB4 + "obj.parent = self\n"
        elif prop["type"] not in PYTHON_TYPE and prop["type"] != "ndarray":
            # pyleecan type
            prop_str += TAB2 + "if self._" + prop["name"] + " is not None:\n"
            prop_str += TAB3 + "self._" + prop["name"] + ".parent = self\n"

        # Property declaration
        # For doxygen : TODO: still needed for sphinx ?
        prop_str += TAB + "# " + prop["desc"] + "\n"
        prop_str += TAB + "# Type : " + prop["type"]
        if str(prop["min"]) is not "":
            prop_str += ", min = " + str(prop["min"])
        if str(prop["max"]) is not "":
            prop_str += ", max = " + str(prop["max"])
        prop_str += "\n"
        # Add "var_name = property(fget=_get_var_name, fset=_set_var_name,
        # doc = "this is doc")"
        prop_str += TAB + prop["name"] + " = property(fget=_get_" + prop["name"]
        prop_str += ", fset=_set_" + prop["name"]
        # "Clean" the doc string from excel
        prop_str += ",\n" + TAB4
        for ii in range(len(prop["name"])):  # Align doc with fget
            prop_str += " "
        prop_str += 'doc=u"""' + prop["desc"] + '""")\n\n'

    return prop_str[:-2]  # Remove last \n\n
Beispiel #3
0
def generate_as_dict(gen_dict, class_dict):
    """Generate the code for the as_dict method of the class

    Parameters
    ----------
    gen_dict : dict
        Dict with key = class name and value = class dict (name, package, properties, methods...)

    class_dict : dict
        Dictionnary of the class to generate (keys are name, package, properties, methods...)

    Returns
    -------
    dict_str : str
        String containing the code for the as_dict method of the class
    """

    class_name = class_dict["name"]
    dict_str = ""  # This string is for the generated code

    var_str = ""  # For the creation of the return dict (in as_dict)

    for prop in class_dict["properties"]:
        if prop["type"] in PYTHON_TYPE:
            # Add => "class_name ["var_name"] = self.var_name" to var_str
            var_str += (TAB2 + class_name + '_dict["' + prop["name"] +
                        '"] = self.' + prop["name"] + "\n")
        elif prop["type"] == "ndarray":
            # Add => "class_name ["var_name"] = self.var_name.tolist()" to
            # var_str
            var_str += TAB2 + "if self." + prop["name"] + " is None:\n"
            var_str += TAB3 + class_name + '_dict["' + prop[
                "name"] + '"] = None\n'
            var_str += TAB2 + "else:\n"
            var_str += (TAB3 + class_name + '_dict["' + prop["name"] +
                        '"] = self.' + prop["name"] + ".tolist()\n")
        elif is_list_pyleecan_type(prop["type"]):
            var_str += TAB2 + class_name + '_dict["' + prop[
                "name"] + '"] = list()\n'
            var_str += TAB2 + "for obj in self." + prop["name"] + ":\n"
            var_str += (TAB3 + class_name + '_dict["' + prop["name"] +
                        '"].append(obj.as_dict())\n')
        else:
            # Add => "class_name ["var_name"] = self.var_name.as_dict()" to
            # var_str
            var_str += TAB2 + "if self." + prop["name"] + " is None:\n"
            var_str += TAB3 + class_name + '_dict["' + prop[
                "name"] + '"] = None\n'
            var_str += TAB2 + "else:\n"
            var_str += (TAB3 + class_name + '_dict["' + prop["name"] +
                        '"] = self.' + prop["name"] + ".as_dict()\n")

    # Code generation
    dict_str += TAB + "def as_dict(self):\n"
    dict_str += (TAB2 + '"""Convert this objet in a json seriable dict (can '
                 "be use in __init__)\n" + TAB2 + '"""\n\n')
    if class_dict["mother"] != "":
        # Get the properties of the mother class (if needed)
        dict_str += (TAB2 + "# Get the properties inherited from " +
                     class_dict["mother"] + "\n")
        dict_str += (TAB2 + class_name + "_dict = super(" + class_name +
                     ", self).as_dict()\n")
    else:
        dict_str += TAB2 + class_name + "_dict = dict()\n"

    dict_str += var_str
    dict_str += (TAB2 + "# The class name is added to the dict for" +
                 "deserialisation purpose\n")
    if class_dict["mother"] != "":
        dict_str += TAB2 + "# Overwrite the mother class name\n"
    dict_str += TAB2 + class_name + '_dict["__class__"] = "' + class_name + '"\n'
    dict_str += TAB2 + "return " + class_name + "_dict\n"

    return dict_str
Beispiel #4
0
def generate_str(gen_dict, class_dict):
    """Generate the code for the __str__ method of the class

    Parameters
    ----------
    gen_dict : dict
        Dict with key = class name and value = class dict (name, package, properties, methods...)

    class_dict : dict
        Dictionnary of the class to generate (keys are name, package, properties, methods...)

    Returns
    -------
    str_str : str
        String containing the code for the __str__ method of the class
    """

    class_name = class_dict["name"]
    str_str = ""  # This string is for the generated code

    var_str = ""  # For the creation of the return string (in __str__)

    # Display parent only in the top mother class __str__ method
    if class_dict["mother"] == "":
        var_str += TAB2 + "if self.parent is None:\n"
        var_str += TAB3 + class_name + '_str += "parent = None " + linesep\n'
        var_str += TAB2 + "else:\n"
        var_str += (TAB3 + class_name + '_str += "parent = " + ' +
                    'str(type(self.parent)) + " object" + linesep\n')

    for ii, prop in enumerate(class_dict["properties"]):
        if prop["type"] == "str":
            # Add => < MyClass_str += 'my_var = "'+self.MyVar+'"' >to var_str
            var_str += (TAB2 + class_name + "_str += '" + prop["name"] +
                        ' = "' + "' + str(self." + prop["name"] + ") + " +
                        """'"'""")
        elif prop["type"] in ["int", "float", "bool", "complex", "dict"]:
            # Add => < MyClass_str += "my_var = "+str(self.my_var) >to var_str
            var_str += (TAB2 + class_name + '_str += "' + prop["name"] +
                        ' = " + str(self.' + prop["name"] + ")")
        elif prop["type"] in ["ndarray", "list"]:
            # For Matrix (skip a line then print the matrix)
            # Add => < MyClass_str += "my_var = "+ linesep + str(
            # self.my_var) >to var_str
            var_str += (TAB2 + class_name + '_str += "' + prop["name"] +
                        ' = " + linesep + str(self.' + prop["name"] + ")")
        elif is_list_pyleecan_type(prop["type"]):
            var_str += TAB2 + "if len(self." + prop["name"] + ") == 0:\n"
            var_str += TAB3 + class_name + '_str += "' + prop[
                "name"] + ' = []"\n'
            var_str += TAB2 + "for ii in range(len(self." + prop[
                "name"] + ")):\n"
            var_str += (TAB3 + class_name + '_str += "' + prop["name"] +
                        '["+str(ii)+"] = "+str(self.' + prop["name"] +
                        '[ii].as_dict())+"\\n"')
        else:  # For pyleecan type print the dict (from as_dict)
            # Add => < "MyClass = "+str(self.my_var.as_dict()) >to var_str
            var_str += (TAB2 + class_name + '_str += "' + prop["name"] +
                        ' = " + str(self.' + prop["name"] + ".as_dict())")

        # Add linesep except for the last line
        if ii == len(class_dict["properties"]) - 1:
            var_str += "\n"
        else:
            if prop["type"] in PYTHON_TYPE:
                var_str += " + linesep\n"
            else:  # Skip two lines for pyleecan type and ndarray
                var_str += " + linesep + linesep\n"
    # Code generation
    str_str += TAB + "def __str__(self):\n"
    str_str += (TAB2 + '"""Convert this objet in a readeable string ' +
                '(for print)"""\n\n')
    str_str += TAB2 + class_name + '_str = ""\n'
    if class_dict["mother"] != "":
        str_str += (TAB2 + "# Get the properties inherited from " +
                    class_dict["mother"] + "\n")
        # Add => "Class_str += super(Class, self).__str__() + linesep
        str_str += (TAB2 + class_name + "_str += super(" + class_name +
                    ", self).__str__() + linesep\n")
    str_str += var_str
    str_str += TAB2 + "return " + class_name + "_str\n"

    return str_str
Beispiel #5
0
def generate_init(gen_dict, class_dict):
    """Generate the code for the __init__ method for the class

    Parameters
    ----------
    gen_dict : dict
        Dict with key = class name and value = class dict (name, package, properties, methods...)

    class_dict : dict
        Dictionnary of the class to generate (keys are name, package, properties, methods...)


    Returns
    -------
    init_str : str
        String containing the __init__ method code
    """

    class_name = class_dict["name"]
    init_str = ""  # This string is for the generated code

    init_by_var = ""  # For the initialisation with the argument
    # Add the parent property only in the top mother classes
    if class_dict["mother"] == "":
        init_by_var += TAB2 + "self.parent = None\n"

    for prop in class_dict["properties"]:
        if prop["type"] in PYTHON_TYPE:
            # Add => "self.my_var = my_var\n" to init_by_var
            init_by_var += TAB2 + "self." + prop["name"] + " = " + prop[
                "name"] + "\n"
        elif prop["type"] == "ndarray":
            # Default value is None which should call the corresponding init
            init_by_var += (TAB2 + "# " + prop["name"] +
                            " can be None, a ndarray or a list\n")
            init_by_var += (TAB2 + 'set_array(self, "' + prop["name"] + '", ' +
                            prop["name"] + ")\n")
        elif is_list_pyleecan_type(prop["type"]):
            # List of pyleecan type
            init_by_var += (TAB2 + "# " + prop["name"] +
                            " can be None or a list of " + prop["type"][1:-1] +
                            " object\n")
            init_by_var += TAB2 + "self." + prop["name"] + " = list()\n"
            init_by_var += TAB2 + "if type(" + prop["name"] + ") is list:\n"
            init_by_var += TAB3 + "for obj in " + prop["name"] + ":\n"
            init_by_var += TAB4 + "if obj is None:  # Default value\n"
            init_by_var += (TAB5 + "self." + prop["name"] + ".append(" +
                            prop["type"][1:-1] + "())\n")
            type_dict = gen_dict[prop["type"][1:-1]]
            daug_list = type_dict["daughters"]
            init_by_var += generate_set_class_by_dict_list(
                prop["name"], prop["type"][1:-1], daug_list)
            init_by_var += TAB4 + "else:\n"
            init_by_var += TAB5 + "self." + prop["name"] + ".append(obj)\n"
            init_by_var += TAB2 + "elif " + prop["name"] + " is None:\n"
            init_by_var += TAB3 + "self." + prop["name"] + " = list()\n"
            init_by_var += TAB2 + "else:\n"
            init_by_var += TAB3 + "self." + prop["name"] + " = " + prop[
                "name"] + "\n"
        else:  # For pyleecan Type
            init_by_var += (TAB2 + "# " + prop["name"] + " can be None, a " +
                            prop["type"] + " object or a dict\n")
            type_dict = gen_dict[prop["type"]]
            daug_list = type_dict["daughters"]
            init_by_var += generate_set_class_by_dict(prop["name"],
                                                      prop["type"], daug_list)
            init_by_var += TAB2 + "else:\n"
            init_by_var += TAB3 + "self." + prop["name"] + " = " + prop[
                "name"] + "\n"

    # Load all the properties including mother ones
    (all_properties,
     mother_prop_list) = get_mother_attr(gen_dict, class_dict, "properties")

    mother_arg_list = ""  # For the call of super init
    for prop in mother_prop_list:
        if mother_arg_list != "":  # Avoid the first coma
            # Add => ", my_var = my_var" to mother_arg_list
            mother_arg_list += ", " + prop["name"] + "=" + prop["name"]
        else:
            # Add => "my_var = my_var" to mother_arg_list
            mother_arg_list += prop["name"] + "=" + prop["name"]

    check_dict = ""  # list of all the property expectable in the init_dict
    init_by_dict = ""  # To overwrite the parameter from init_dict
    arg_list = ""  # For the argument with default value
    init_MType = ""  # To initialize the pyleecan Type default (-1)
    for prop in all_properties:
        # To overwrite the parameter from init_dict
        init_by_dict += TAB3 + 'if "' + prop[
            "name"] + '" in list(init_dict.keys()):\n'
        init_by_dict += TAB4 + prop["name"] + ' = init_dict["' + prop[
            "name"] + '"]\n'
        # For the argument with default value
        if prop["type"] in PYTHON_TYPE:
            # Add => ", my_var = 10" to arg_list
            arg_list += (", " + prop["name"] + "=" +
                         get_value_str(prop["value"], prop["type"]))
        elif prop["type"] == "ndarray":
            arg_list += ", " + prop["name"] + "=None"
        elif prop["type"][0] == "[" and prop["type"][-1] == "]":
            # List of pyleecan type
            arg_list += ", " + prop["name"] + "=list()"
        else:  # pyleecan type
            if prop["value"] == "":
                arg_list += ", " + prop["name"] + "=-1"
            else:  # Default value (most likely None)
                arg_list += (", " + prop["name"] + "=" +
                             get_value_str(prop["value"], prop["type"]))
            # To initialize the pyleecan Type default (-1)
            init_MType += TAB2 + "if " + prop["name"] + " == -1:\n"
            init_MType += TAB3 + prop["name"] + " = " + prop["type"] + "()\n"
        # For check_init_dict
        if check_dict == "":  # First variable
            check_dict += '"' + prop["name"] + '"'
        else:
            check_dict += ', "' + prop["name"] + '"'

    # Code generation in init_str
    init_str += TAB + "def __init__(self" + arg_list + ", init_dict=None):\n"
    init_str += TAB2 + '"""Constructor of the class. Can be use in two ways ' ":\n"
    init_str += (TAB2 + "- __init__ (arg1 = 1, arg3 = 5) every parameters "
                 "have name and default values\n")
    init_str += (TAB3 + "for Matrix, None will initialise the property with "
                 "an empty Matrix\n")
    init_str += TAB3 + "for pyleecan type, None will call the default " "constructor\n"
    init_str += (TAB2 + "- __init__ (init_dict = d) d must be a dictionnary "
                 "wiht every properties as keys\n\n")
    init_str += TAB2 + "ndarray or list can be given for Vector and Matrix\n"
    init_str += TAB2 + 'object or dict can be given for pyleecan Object"""\n\n'

    init_str += init_MType
    init_str += TAB2 + "if init_dict is not None:  # Initialisation by dict\n"
    init_str += TAB3 + "check_init_dict(init_dict, [" + check_dict + "])\n"
    init_str += TAB3 + "# Overwrite default value with init_dict content\n"
    init_str += init_by_dict
    init_str += TAB2 + "# Initialisation by argument\n"
    init_str += init_by_var
    # Add the call to super __init__ if needed
    if class_dict["mother"] != "":
        init_str += TAB2 + "# Call " + class_dict["mother"] + " init\n"
        init_str += (TAB2 + "super(" + class_name + ", self).__init__(" +
                     mother_arg_list + ")\n")
        init_str += (TAB2 + "# The class is frozen (in " +
                     class_dict["mother"] + " init), for now it's impossible "
                     "to\n" + TAB2 + "# add new "
                     "properties\n")
    else:
        init_str += ("\n" + TAB2 + "# The class is frozen, for now it's " +
                     "impossible to add new properties\n")
        init_str += TAB2 + "self._freeze()\n"

    return init_str
Beispiel #6
0
def generate_as_dict(gen_dict, class_dict):
    """Generate the code for the as_dict method of the class

    Parameters
    ----------
    gen_dict : dict
        Dict with key = class name and value = class dict (name, package, properties, methods...)

    class_dict : dict
        Dictionnary of the class to generate (keys are name, package, properties, methods...)

    Returns
    -------
    dict_str : str
        String containing the code for the as_dict method of the class
    """

    class_name = class_dict["name"]
    dict_str = ""  # This string is for the generated code

    var_str = ""  # For the creation of the return dict (in as_dict)

    for prop in class_dict["properties"]:
        if prop["type"] in PYTHON_TYPE:
            # Add => "class_name ["var_name"] = self.var_name" to var_str
            var_str += (
                TAB2
                + class_name
                + '_dict["'
                + prop["name"]
                + '"] = self.'
                + prop["name"]
                + "\n"
            )
        elif prop["type"] == "ndarray":
            # Add => "class_name ["var_name"] = self.var_name.tolist()" to
            # var_str
            var_str += TAB2 + "if self." + prop["name"] + " is None:\n"
            var_str += TAB3 + class_name + '_dict["' + prop["name"] + '"] = None\n'
            var_str += TAB2 + "else:\n"
            var_str += (
                TAB3
                + class_name
                + '_dict["'
                + prop["name"]
                + '"] = self.'
                + prop["name"]
                + ".tolist()\n"
            )
        elif prop["type"] == "function":
            # Add => "class_name ["var_name"] = self._var_name" to
            # var_str
            var_str += TAB2 + "if self." + prop["name"] + " is None:\n"
            var_str += TAB3 + class_name + '_dict["' + prop["name"] + '"] = None\n'
            var_str += TAB2 + "else:\n"
            var_str += (
                TAB3
                + class_name
                + '_dict["'
                + prop["name"]
                + '"] = [dumps(self._'
                + prop["name"]
                + "[0]).decode('ISO-8859-2'), self._"
                + prop["name"]
                + "[1]]\n"
            )
        elif "." in prop["type"]:  # Type from external package
            var_str += TAB2 + "if self." + prop["name"] + " is None:\n"
            var_str += TAB3 + class_name + '_dict["' + prop["name"] + '"] = None\n'
            var_str += (
                TAB2
                + "else: # Store serialized data (using cloudpickle) and str to read it in json save files\n"
            )
            var_str += (
                TAB3
                + class_name
                + "_dict['"
                + prop["name"]
                + '\'] ={"__class__" : str(type(self._'
                + prop["name"]
                + ")),"
                + '"__repr__":str(self._'
                + prop["name"]
                + ".__repr__()),"
                + '"serialized":dumps(self._'
                + prop["name"]
                + ").decode('ISO-8859-2')}\n"
            )

        elif is_list_pyleecan_type(prop["type"]):
            var_str += TAB2 + class_name + '_dict["' + prop["name"] + '"] = list()\n'
            var_str += TAB2 + "for obj in self." + prop["name"] + ":\n"
            var_str += (
                TAB3
                + class_name
                + '_dict["'
                + prop["name"]
                + '"].append(obj.as_dict())\n'
            )
        elif prop["type"] == "{ndarray}":
            var_str += TAB2 + class_name + '_dict["' + prop["name"] + '"] = dict()\n'
            var_str += TAB2 + "for key, obj in self." + prop["name"] + ".items():\n"
            var_str += (
                TAB3
                + class_name
                + '_dict["'
                + prop["name"]
                + '"][key] = obj.tolist()\n'
            )
        elif is_dict_pyleecan_type(prop["type"]):
            var_str += TAB2 + class_name + '_dict["' + prop["name"] + '"] = dict()\n'
            var_str += TAB2 + "for key, obj in self." + prop["name"] + ".items():\n"
            var_str += (
                TAB3
                + class_name
                + '_dict["'
                + prop["name"]
                + '"][key] = obj.as_dict()\n'
            )
        else:
            # Add => "class_name ["var_name"] = self.var_name.as_dict()" to
            # var_str
            var_str += TAB2 + "if self." + prop["name"] + " is None:\n"
            var_str += TAB3 + class_name + '_dict["' + prop["name"] + '"] = None\n'
            var_str += TAB2 + "else:\n"
            var_str += (
                TAB3
                + class_name
                + '_dict["'
                + prop["name"]
                + '"] = self.'
                + prop["name"]
                + ".as_dict()\n"
            )

    # Code generation
    dict_str += TAB + "def as_dict(self):\n"
    dict_str += (
        TAB2 + '"""Convert this objet in a json seriable dict (can '
        "be use in __init__)\n" + TAB2 + '"""\n\n'
    )
    if class_dict["mother"] != "":
        # Get the properties of the mother class (if needed)
        dict_str += (
            TAB2 + "# Get the properties inherited from " + class_dict["mother"] + "\n"
        )
        dict_str += (
            TAB2 + class_name + "_dict = super(" + class_name + ", self).as_dict()\n"
        )
    else:
        dict_str += TAB2 + class_name + "_dict = dict()\n"

    dict_str += var_str
    dict_str += (
        TAB2 + "# The class name is added to the dict for" + "deserialisation purpose\n"
    )
    if class_dict["mother"] != "":
        dict_str += TAB2 + "# Overwrite the mother class name\n"
    dict_str += TAB2 + class_name + '_dict["__class__"] = "' + class_name + '"\n'
    dict_str += TAB2 + "return " + class_name + "_dict\n"

    return dict_str
Beispiel #7
0
def generate_properties(gen_dict, class_dict):
    """Generate the code for the getter and setter of the properties of the class

    Parameters
    ----------
    gen_dict : dict
        Dict with key = class name and value = class dict (name, package, properties, methods...)

    class_dict : dict
        Dictionnary of the class to generate (keys are name, package, properties, methods...)

    Returns
    -------
    prop_str : str
        String containing the code for the getter and setter of the properties of the class
    """

    prop_str = ""  # This string is for the generated code

    for prop in class_dict["properties"]:
        # Getter
        prop_str += TAB + "def _get_" + prop["name"] + "(self):\n"
        prop_str += TAB2 + '"""getter of ' + prop["name"] + '"""\n'
        if is_list_pyleecan_type(prop["type"]):
            # TODO: Update the parent should be done only in the setter but
            # their is an issue with .append for list of pyleecan type
            prop_str += TAB2 + "for obj in self._" + prop["name"] + ":\n"
            prop_str += TAB3 + "if obj is not None:\n"
            prop_str += TAB4 + "obj.parent = self\n"
            prop_str += TAB2 + "return self._" + prop["name"] + "\n\n"

        elif is_dict_pyleecan_type(
                prop["type"]) and prop["type"] != "{ndarray}":
            # TODO: Update the parent should be done only in the setter but
            # their is an issue with .append for list of pyleecan type
            prop_str += TAB2 + "for key, obj in self._" + prop[
                "name"] + ".items():\n"
            prop_str += TAB3 + "if obj is not None:\n"
            prop_str += TAB4 + "obj.parent = self\n"
            prop_str += TAB2 + "return self._" + prop["name"] + "\n\n"
        elif prop["type"] == "function":
            prop_str += TAB2 + "return self._" + prop["name"] + "[0]\n\n"
        else:
            prop_str += TAB2 + "return self._" + prop["name"] + "\n\n"

        # Setter
        prop_str += TAB + "def _set_" + prop["name"] + "(self, value):\n"
        prop_str += TAB2 + '"""setter of ' + prop["name"] + '"""\n'
        # Convert ndarray if needed
        if prop["type"] == "ndarray":
            prop_str += TAB2 + "if type(value) is list:\n"
            prop_str += TAB3 + "try:\n"
            prop_str += TAB4 + "value = array(value)\n"
            prop_str += TAB3 + "except:\n"
            prop_str += TAB4 + "pass\n"
        elif prop["type"] == "{ndarray}":
            prop_str += TAB2 + "if type(value) is dict:\n"
            prop_str += TAB3 + "for key, obj in value.items():\n"
            prop_str += TAB4 + "if type(obj) is list:\n"
            prop_str += TAB5 + "try:\n"
            prop_str += TAB6 + "obj = array(obj)\n"
            prop_str += TAB5 + "except:\n"
            prop_str += TAB6 + "pass\n"

        # Add check_var("var_name",value, "var_type", min=var_min, max=var_max)
        if prop["type"] == "function":
            # A function can be defined by a callable or a list containing the serialized callable and its sourcecode
            prop_str += TAB2 + "try:\n"
            prop_str += TAB3 + 'check_var("' + prop[
                "name"] + '", value, "list")\n'
            prop_str += TAB2 + "except CheckTypeError:\n"
            prop_str += (TAB3 + 'check_var("' + prop["name"] + '", value, "' +
                         prop["type"] + '")\n')
            prop_str += (
                TAB2 +
                "if isinstance(value,list): # Load function from saved dict\n")
            prop_str += (
                TAB3 + "self._" + prop["name"] +
                " = [loads(value[0].encode('ISO-8859-2')),value[1]]\n")
            prop_str += TAB2 + "elif value is None:\n"
            prop_str += TAB3 + "self._" + prop["name"] + " = [None,None]\n"
            prop_str += TAB2 + "elif callable(value):\n"
            prop_str += TAB3 + "self._" + prop[
                "name"] + " = [value,getsource(value)]\n"
            prop_str += TAB2 + "else:\n"
            prop_str += (
                TAB3 +
                "raise TypeError('Expected function or list from a saved file, got: '+str(type(value))) \n"
            )

        elif "." in prop["type"]:  # Import from another package
            prop_str += TAB2 + "try: # Check the type \n"
            prop_str += TAB3 + 'check_var("' + prop[
                "name"] + '", value, "dict")\n'
            prop_str += TAB2 + "except CheckTypeError:\n"
            prop_str += (TAB3 + 'check_var("' + prop["name"] + '", value, "' +
                         prop["type"] + '")\n')
            prop_str += TAB3 + "# property can be set from a list to handle loads\n"
            prop_str += (
                TAB2 +
                'if type(value) == dict: # Load type from saved dict {"type":type(value),"str": str(value),"serialized": serialized(value)]\n'
            )
            prop_str += (
                TAB3 + "self._" + prop["name"] +
                " = loads(value[\"serialized\"].encode('ISO-8859-2'))\n")
            prop_str += TAB2 + "else: \n"
            prop_str += TAB3 + "self._" + prop["name"] + "= value \n"

        else:
            prop_str += (TAB2 + 'check_var("' + prop["name"] + '", value, "' +
                         prop["type"] + '"')
            # Min and max are added only if needed
            if prop["type"] in ["float", "int", "ndarray"]:
                if str(prop["min"]) is not "":
                    prop_str += ", Vmin=" + str(prop["min"])
                if str(prop["max"]) is not "":
                    prop_str += ", Vmax=" + str(prop["max"])
            prop_str += ")\n"
            prop_str += TAB2 + "self._" + prop["name"] + " = value\n\n"

        if is_list_pyleecan_type(prop["type"]):
            # List of pyleecan type
            prop_str += TAB2 + "for obj in self._" + prop["name"] + ":\n"
            prop_str += TAB3 + "if obj is not None:\n"
            prop_str += TAB4 + "obj.parent = self\n\n"
        elif (prop["type"] not in PYTHON_TYPE
              and prop["type"] not in ["ndarray", "function", "{ndarray}"]
              and not is_dict_pyleecan_type(prop["type"])
              and "." not in prop["type"]):
            # pyleecan type
            prop_str += TAB2 + "if self._" + prop["name"] + " is not None:\n"
            prop_str += TAB3 + "self._" + prop["name"] + ".parent = self\n"

        # Property declaration
        # For doxygen : TODO: still needed for sphinx ?
        prop_str += TAB + "# " + prop["desc"] + "\n"
        prop_str += TAB + "# Type : " + prop["type"]
        if str(prop["min"]) is not "":
            prop_str += ", min = " + str(prop["min"])
        if str(prop["max"]) is not "":
            prop_str += ", max = " + str(prop["max"])
        prop_str += "\n"
        # Add "var_name = property(fget=_get_var_name, fset=_set_var_name,
        # doc = "this is doc")"
        if len(prop["desc"]) > 40:  # PEP8
            # Three lines definition
            prop_str += TAB + prop["name"] + " = property(\n"
            prop_str += TAB2 + "fget=_get_" + prop["name"] + ",\n"
            prop_str += TAB2 + "fset=_set_" + prop["name"] + ",\n"
            prop_str += TAB2 + 'doc=u"""' + prop["desc"] + '""",\n'
            prop_str += TAB + ")\n\n"
        elif len(prop["desc"]) + 2 * len(prop["name"]) > 25:
            prop_str += TAB + prop["name"] + " = property(\n"
            prop_str += TAB2 + "fget=_get_" + prop["name"]
            prop_str += ", fset=_set_" + prop["name"]
            prop_str += ', doc=u"""' + prop["desc"] + '"""\n'
            prop_str += TAB + ")\n\n"
        else:
            # All on one line
            prop_str += TAB + prop["name"] + " = property("
            prop_str += "fget=_get_" + prop["name"]
            prop_str += ", fset=_set_" + prop["name"]
            prop_str += ', doc=u"""' + prop["desc"] + '""")\n\n'

    return prop_str[:-2]  # Remove last \n\n