Пример #1
0
def generate_class(gen_dict, class_name, path_to_gen):
    """generate the corresponding class file (erase the previous code)

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

    class_name : str
        name of the class to generate

    path_to_gen : str
        path to the file to save the class code


    Returns
    -------
    None

    """

    class_dict = gen_dict[class_name]
    class_pack = class_dict["package"]

    # Start of file generation
    # Create or Erase the file by opening it
    class_file = open_co(join(path_to_gen, class_name + ".py"), "w", "utf-8")

    # List of non python type to import
    import_type_list = list(find_import_type(gen_dict, class_dict, []))

    # Encoding
    class_file.write("# -*- coding: utf-8 -*-\n")

    # Warning
    class_file.write('"""Warning : this file has been generated, '
                     'you shouldn\'t edit it"""\n\n')

    # Import
    class_file.write("from os import linesep\n")
    if "ndarray" in import_type_list:
        class_file.write("from pyleecan.Classes.check import set_array, " +
                         "check_init_dict, check_var\n")
    else:
        class_file.write(
            "from pyleecan.Classes.check import check_init_dict, " +
            "check_var\n")
    # Save function
    class_file.write("from pyleecan.Functions.save import save\n")

    # Import of the mother_class (FrozenClass by default)
    # All the classes file are in the Classes folder (regardless of their main package)
    if class_dict["mother"] != "":
        class_file.write("from pyleecan.Classes." + class_dict["mother"] +
                         " import " + class_dict["mother"] + "\n\n")
    else:
        class_file.write("from pyleecan.Classes.frozen import FrozenClass\n\n")

    # Import all the methods of the class
    # The methods are in Methods.<Main package>.<class name>, one file per method
    for meth in class_dict["methods"]:
        class_file.write("from pyleecan.Methods." + class_pack + "." +
                         class_name + "." + meth + " import " +
                         meth.split(".")[-1] + "\n")
    if len(class_dict["methods"]) > 0:
        class_file.write("\n")

    # For Matrix and Vector (numpy) property
    if "ndarray" in import_type_list:
        class_file.write("from numpy import array, array_equal\n")
        import_type_list.remove("ndarray")

    # Import of all needed pyleecan type for property polymorphism
    class_file.write(
        "from pyleecan.Classes.check import InitUnKnowClassError\n")
    for pyleecan_type in import_type_list:
        type_dict = gen_dict[pyleecan_type]
        class_file.write("from pyleecan.Classes." + pyleecan_type +
                         " import " + pyleecan_type + "\n")
        for daughter_name in type_dict["daughters"]:
            # Import of the inherited class (for init)
            class_file.write("from pyleecan.Classes." + daughter_name +
                             " import " + daughter_name + "\n")
    if len(import_type_list) > 0:
        class_file.write("\n")

    # Class declaration
    if class_dict["mother"] != "":
        class_file.write("\n\nclass " + class_name + "(" +
                         class_dict["mother"] + "):\n")
    else:
        class_file.write("\n\nclass " + class_name + "(FrozenClass):\n")

    # Class Docstring
    if class_dict["desc"] != "":
        class_file.write(TAB + '"""' + class_dict["desc"] + '"""\n')
    class_file.write("\n")

    # Declare all class Constante (VERSION should be a constante for every classes)
    for cst in class_dict["constants"]:
        class_file.write(TAB + cst["name"] + " = " + str(cst["value"]) + "\n")
    class_file.write("\n")

    # Asign all the Methods of the class
    for meth in class_dict["methods"]:
        class_file.write(TAB + "# cf Methods." + class_pack + "." +
                         class_name + "." + meth + "\n")
        class_file.write(TAB + meth.split(".")[-1] + " = " +
                         meth.split(".")[-1] + "\n")
    class_file.write(TAB + "# save method is available in all object\n")
    class_file.write(TAB + "save = save\n\n")

    # Add the __init__ method
    if len(class_dict["properties"]) == 0 and class_dict["mother"] == "":
        class_file.write(generate_init_void() + "\n")
    else:
        class_file.write(generate_init(gen_dict, class_dict) + "\n")

    # Add the __str__ method
    class_file.write(generate_str(gen_dict, class_dict) + "\n")

    # Add the __eq__ method
    class_file.write(generate_eq(gen_dict, class_dict) + "\n")

    # Add the as_dict method
    class_file.write(generate_as_dict(gen_dict, class_dict) + "\n")

    # Add the _set_None method
    class_file.write(generate_set_None(gen_dict, class_dict) + "\n")

    # Add all the properties getter and setter
    class_file.write(generate_properties(gen_dict, class_dict) + "\n")

    # End of class generation
    class_file.close()
Пример #2
0
def gen_gui_class_file(path, class_name, gen_dict, gen_list):
    """Generate the Main class file according to the gen_list (should be run
    only once)

    Parameters
    ----------
    path : str
        Path to the class folder

    class_name : str
        Name of the class to generate

    gen_dict : dict
        Dict with key = class name and value = class_dict

    gen_list : list
        List of widget to edit

    Returns
    -------

    """
    gen_str = "# -*- coding: utf-8 -*-\n\n"

    # Generate the import path
    # from "C:\\Users...\\GUI\\Dialog..." to ["C:", "Users",..., "GUI",
    # "Dialog",...]
    split_path = path.split("\\")  # Split the path arount the \\
    # The import path start at "GUI", we remove everything before GUI in
    # split_path list
    # from ["C:", "Users",..., "GUI", "Dialog",...] to ["GUI", "Dialog"...]
    split_path.reverse()
    split_path = split_path[:split_path.index("pyleecan") + 1]
    split_path.reverse()
    # from ["GUI", "Dialog", ...] to GUI.Dialog...
    import_path = ".".join(split_path)

    gen_str += "from PyQt5.QtGui import QDialog\n"
    gen_str += "from PyQt5.QtCore import SIGNAL, Qt\n\n"
    gen_str += ("from " + import_path + ".Gen_" + class_name + " import Gen_" +
                class_name + "\n\n")
    gen_str += "class " + class_name + " (Gen_" + class_name + ", QDialog):\n"
    gen_str += TAB + "def __init__ (self,in_obj):\n"
    gen_str += TAB2 + "#Build the interface according to the .ui file\n"
    gen_str += TAB2 + "QDialog.__init__(self)\n"
    gen_str += TAB2 + "self.setupUi(self)\n\n"
    gen_str += TAB2 + "#Copy to set the modification only if validated\n"
    gen_str += TAB2 + "#self.fault = Fault(init_dict=fault.as_dict())\n\n"

    init_str = ""  # For loading the value from input
    connect_str = ""  # Connect slot and signal
    slot_str = ""  # Slot

    for edit in gen_list:
        data = find_prop(gen_dict[edit["xls"]][edit["cls"]]["properties"],
                         edit["name"])
        if data["type"] == "int" and "type" in edit["name"]:
            init_str += (TAB2 + "self.c_" + edit["name"] +
                         ".setCurrentIndex(in_obj." + edit["name"] + ")\n")
            connect_str += (TAB2 + "self.connect(self.c_" + edit["name"] +
                            ', SIGNAL("currentIndexChanged(int)"),self.set_' +
                            edit["name"] + ")\n")
            slot_str += TAB + "def set_" + edit["name"] + " (self,index):\n"
            slot_str += (TAB2 + '"""Signal to update the value of ' +
                         edit["name"] + " according to the combobox\n")
            slot_str += TAB2 + "@param[in] self A " + class_name + " object\n"
            slot_str += (TAB2 +
                         "@param[in] index Current index of the combobox\n" +
                         TAB2 + '"""\n')
            slot_str += TAB2 + "self.obj." + edit["name"] + " = index\n\n"
        elif data["type"] == "int":
            init_str += (TAB2 + "self.si_" + edit["name"] +
                         ".setValue(in_obj." + edit["name"] + ")\n")
            connect_str += (TAB2 + "self.connect(self.si_" + edit["name"] +
                            ', SIGNAL("editingFinished()"),self.set_' +
                            edit["name"] + ")\n")
            slot_str += TAB + "def set_" + edit["name"] + " (self):\n"
            slot_str += (TAB2 + '"""Signal to update the value of ' +
                         edit["name"] + " according to the line edit\n")
            slot_str += (TAB2 + "@param[in] self A " + class_name +
                         " object\n" + TAB2 + '"""\n')
            slot_str += (TAB2 + "self.obj." + edit["name"] + " = self.si_" +
                         edit["name"] + ".value()\n\n")
        elif data["type"] == "float":
            init_str += (TAB2 + "self.lf_" + edit["name"] +
                         ".setValue(in_obj." + edit["name"] + ")\n")
            connect_str += (TAB2 + "self.connect(self.lf_" + edit["name"] +
                            ', SIGNAL("editingFinished()"),self.set_' +
                            edit["name"] + ")\n")
            slot_str += TAB + "def set_" + edit["name"] + " (self):\n"
            slot_str += (TAB2 + '"""Signal to update the value of ' +
                         edit["name"] + " according to the line edit\n")
            slot_str += (TAB2 + "@param[in] self A " + class_name +
                         " object\n" + TAB2 + '"""\n')
            slot_str += (TAB2 + "self.obj." + edit["name"] + " = self.lf_" +
                         edit["name"] + ".value()\n\n")
        elif data["type"] == "bool":
            init_str += TAB2 + "if in_obj." + edit["name"] + " :\n"
            init_str += TAB3 + "self." + edit[
                "name"] + ".setCheckState(Qt.Checked)\n"
            init_str += TAB2 + "else :\n"
            init_str += TAB3 + "self." + edit[
                "name"] + ".setCheckState(Qt.Unchecked)\n"
            connect_str += (TAB2 + "self.connect(self." + edit["name"] +
                            ', SIGNAL("toggled(bool)"),self.set_' +
                            edit["name"] + ")\n")
            slot_str += TAB + "def set_" + edit[
                "name"] + " (self, is_checked):\n"
            slot_str += (TAB2 + '"""Signal to update the value of ' +
                         edit["name"] + " according to the checkbox\n")
            slot_str += TAB2 + "@param[in] self A " + class_name + " object\n"
            slot_str += (TAB2 +
                         "@param[in] is_checked State of the checkbox\n" +
                         TAB2 + '"""\n')
            slot_str += TAB2 + "self.obj." + edit["name"] + " = is_checked\n\n"
        elif data["type"] == "str":
            init_str += (TAB2 + "self.le_" + edit["name"] +
                         ".setText(in_obj." + edit["name"] + ")\n")
            connect_str += (TAB2 + "self.connect(self.le_" + edit["name"] +
                            ', SIGNAL("editingFinished()"),self.set_' +
                            edit["name"] + ")\n")
            slot_str += TAB + "def set_" + edit["name"] + " (self):\n"
            slot_str += (TAB2 + '"""Signal to update the value of ' +
                         edit["name"] + " according to the line edit\n")
            slot_str += (TAB2 + "@param[in] self A " + class_name +
                         " object\n" + TAB2 + '"""\n')
            slot_str += (TAB2 + "self.obj." + edit["name"] +
                         " = str(self.le_" + edit["name"] + ".text())\n\n")

    # Concatenate all (and remove last \n)
    gen_str += init_str + "\n" + connect_str + "\n" + slot_str[:-1]
    # Write the file with the generated code lines
    gen_file = open_co(join(path, class_name + ".py"), "w", "utf-8")
    gen_file.write(gen_str)
    gen_file.close()
Пример #3
0
def gen_gui_edit_file(path, class_name, gen_dict, gen_list):
    """Generate the "Gen_" class for editing the gui according to gen_list

    Parameters
    ----------
    path : str
        Path to the class folder

    class_name : str
        Name of the class to generate

    gen_dict : dict
        Dict with key = class name and value = class_dict

    gen_list : list
        List of widget to edit

    Returns
    -------

    """

    # gen_str contains the code that will be written in the generated file
    gen_str = "# -*- coding: utf-8 -*-\n"
    gen_str += '"""File generated according to ' + class_name + "/gen_list.json\n"
    gen_str += 'WARNING! All changes made in this file will be lost!\n"""\n\n'

    # Generate the import path
    # from "C:\\Users...\\GUI\\Dialog..." to ["C:", "Users",..., "GUI",
    # "Dialog",...]
    split_path = path.split("\\")  # Split the path arount the \\
    # The import path start at "GUI", we remove everything before GUI in
    # split_path list
    # from ["C:", "Users",..., "GUI", "Dialog",...] to ["GUI", "Dialog"...]
    split_path.reverse()
    split_path = split_path[:split_path.index("pyleecan") + 1]
    split_path.reverse()
    # from ["GUI", "Dialog", ...] to GUI.Dialog...
    import_path = ".".join(split_path)

    gen_str += ("from " + import_path + ".Ui_" + class_name + " import Ui_" +
                class_name + "\n\n\n")
    gen_str += "class Gen_" + class_name + "(Ui_" + class_name + "):\n"

    # We use polymorphism to add some code lines to setupUi
    gen_str += TAB + "def setupUi(self, " + class_name + "):\n"
    gen_str += (
        TAB2 +
        '"""Abstract class to update the widget according to the csv doc\n')
    gen_str += TAB2 + '"""\n'
    gen_str += TAB2 + "Ui_" + class_name + ".setupUi(self, " + class_name + ")\n"

    # We generate the corresponding lines for every needed widget
    for edit in gen_list:
        # data contains description, min, max of the variable according to Doc
        # excel files
        data = find_prop(gen_dict[edit["cls"]]["properties"], edit["name"])

        # widget can contain either a list or a string
        if isinstance(edit["widget"], list):
            # generate the code lines for every widget in the list (label and
            # corresponding input most of the time)
            for widget in edit["widget"]:
                gen_str += gen_edit_widget_code(widget, data)
        else:
            # generate the code lines for the widget
            gen_str += gen_edit_widget_code(edit["widget"], data)

    # Write the file with the generated code lines
    gen_file = open_co(join(path, "Gen_" + class_name + ".py"), "w", "utf-8")
    gen_file.write(gen_str[:-1])
    gen_file.close()
Пример #4
0
def generate_class(gen_dict, class_name, path_to_gen):
    """generate the corresponding class file (erase the previous code)

    Parameters
    ----------
    gen_dict : dict
        Dict with key = class name and value = class dict (name, package, properties, methods...)
    class_name : str
        name of the class to generate
    path_to_gen : str
        path to the file to save the class code

    Returns
    -------
    None

    """

    class_dict = gen_dict[class_name]
    class_pack = class_dict["package"]

    # Start of file generation
    # Create or Erase the file by opening it
    class_file = open_co(join(path_to_gen, class_name + ".py"), "w", "utf-8")

    # List of non python type to import
    import_type_list = list(find_import_type(gen_dict, class_dict, []))
    if class_name in import_type_list:  # For recursive class
        import_type_list.remove(class_name)
    # Encoding
    class_file.write("# -*- coding: utf-8 -*-\n")

    # Warning
    class_file.write('"""File generated according to ' + class_dict["path"] +
                     "\n")
    if class_dict["is_internal"]:
        class_file.write(
            "WARNING! Internal version of the class: DO NOT SHARE ON GITHUB !\n"
        )
    class_file.write(
        'WARNING! All changes made in this file will be lost!\n"""\n\n')

    # Import
    class_file.write("from os import linesep\n")
    if "ndarray" in import_type_list:
        class_file.write("from pyleecan.Classes.check import set_array, " +
                         "check_init_dict, check_var, raise_\n")
    else:
        class_file.write(
            "from pyleecan.Classes.check import check_init_dict, check_var, raise_\n"
        )
    # Save function
    class_file.write("from pyleecan.Functions.save import save\n")

    # Import of the mother_class (FrozenClass by default)
    # All the classes file are in the Classes folder (regardless of their main package)
    if class_dict["mother"] != "":
        class_file.write("from pyleecan.Classes." + class_dict["mother"] +
                         " import " + class_dict["mother"] + "\n\n")
    else:
        class_file.write("from pyleecan.Classes.frozen import FrozenClass\n\n")

    # Import all the methods of the class
    # The methods are in Methods.<Main package>.<class name>, one file per method
    if len(class_dict["methods"]) > 0:
        class_file.write("# Import all class method\n")
        class_file.write(
            "# Try/catch to remove unnecessary dependencies in unused method\n"
        )
    for meth in class_dict["methods"]:
        class_file.write(import_method(class_pack, class_name, meth))
    if len(class_dict["methods"]) > 0:
        class_file.write("\n")

    # For Matrix and Vector (numpy) property
    if "ndarray" in import_type_list:
        class_file.write("from numpy import array, array_equal\n")
        import_type_list.remove("ndarray")

    # Import of all needed pyleecan type for empty init
    class_file.write(
        "from pyleecan.Classes.check import InitUnKnowClassError\n")
    for pyleecan_type in import_type_list:
        class_file.write("from pyleecan.Classes." + pyleecan_type +
                         " import " + pyleecan_type + "\n")

    # Class declaration
    if class_dict["mother"] != "":
        class_file.write("\n\nclass " + class_name + "(" +
                         class_dict["mother"] + "):\n")
    else:
        class_file.write("\n\nclass " + class_name + "(FrozenClass):\n")

    # Class Docstring
    if class_dict["desc"] != "":
        class_file.write(TAB + '"""' + class_dict["desc"] + '"""\n')
    class_file.write("\n")

    # Declare all class Constante (VERSION should be a constante for every classes)
    for cst in class_dict["constants"]:
        class_file.write(TAB + cst["name"] + " = " + str(cst["value"]) + "\n")
    class_file.write("\n")

    # Asign all the Methods of the class
    if len(class_dict["methods"]) > 1:
        class_file.write(
            TAB +
            "# Check ImportError to remove unnecessary dependencies in unused method\n"
        )
    for meth in class_dict["methods"]:
        meth_name = meth.split(".")[-1]
        class_file.write(TAB + "# cf Methods." + class_pack + "." +
                         class_name + "." + meth + "\n")
        class_file.write(TAB + "if isinstance(" + meth_name +
                         ", ImportError):\n")
        class_file.write(TAB2 + meth_name + " = property(\n")
        class_file.write(TAB3 + "fget=lambda x: raise_(\n")
        # PEP8 formating
        if len(class_name) + 2 * len(meth_name) > 39:
            # 2 lines Import text
            class_file.write(TAB4 + "ImportError(\n")
            class_file.write(TAB5 + """"Can't use """ + class_name +
                             " method " + meth_name + ': "\n')
            class_file.write(TAB5 + "+ str(" + meth_name + ")\n")
            class_file.write(TAB4 + ")\n")
        elif len(class_name) + 2 * len(meth_name) > 29:
            # Import text on line different line
            class_file.write(TAB4 + "ImportError(\n")
            class_file.write(TAB5 + """"Can't use """ + class_name +
                             " method " + meth_name + ': "')
            class_file.write(" + str(" + meth_name + ")\n")
            class_file.write(TAB4 + ")\n")
        else:  # On one line
            class_file.write(TAB4 + """ImportError("Can't use """ +
                             class_name + " method " + meth_name +
                             ': " + str(' + meth_name + "))\n")
        class_file.write(TAB3 + ")\n")
        class_file.write(TAB2 + ")\n")
        class_file.write(TAB + "else:\n")
        class_file.write(TAB2 + meth_name + " = " + meth_name + "\n")
    class_file.write(TAB + "# save method is available in all object\n")
    class_file.write(TAB + "save = save\n\n")

    # Add the __init__ method
    if len(class_dict["properties"]) == 0 and class_dict["mother"] == "":
        class_file.write(generate_init_void() + "\n")
    else:
        class_file.write(generate_init(gen_dict, class_dict) + "\n")

    # Add the __str__ method
    class_file.write(generate_str(gen_dict, class_dict) + "\n")

    # Add the __eq__ method
    class_file.write(generate_eq(gen_dict, class_dict) + "\n")

    # Add the as_dict method
    class_file.write(generate_as_dict(gen_dict, class_dict) + "\n")

    # Add the _set_None method
    class_file.write(generate_set_None(gen_dict, class_dict))

    # Add all the properties getter and setter
    if len(class_dict["properties"]) > 0:
        class_file.write("\n" + generate_properties(gen_dict, class_dict) +
                         "\n")

    # End of class generation
    class_file.close()