From 8ea136a76b49c25869311e9257f506461ba9d2bb Mon Sep 17 00:00:00 2001 From: caremoli Date: Mon, 11 Oct 2010 16:25:25 +0000 Subject: [PATCH] CCAR: add docstring to main classes to be able to use autodoc feature in YACS sphinx documentation --- Examples/pygui1/components.py | 2 +- Examples/pygui1/using.rst | 3 + module_generator/__init__.py | 6 +- module_generator/astcompo.py | 24 ++++++++ module_generator/cppcompo.py | 24 ++++++++ module_generator/fcompo.py | 21 +++++++ module_generator/gener.py | 110 ++++++++++++++++++++++++++++++++-- module_generator/pycompo.py | 22 +++++++ 8 files changed, 202 insertions(+), 10 deletions(-) diff --git a/Examples/pygui1/components.py b/Examples/pygui1/components.py index f10274b..89171e8 100644 --- a/Examples/pygui1/components.py +++ b/Examples/pygui1/components.py @@ -40,7 +40,7 @@ c1=PYComponent("compo2",services=[ ) modul=Module("pycompos",components=[c1],prefix="./install", - doc=["*.rst",], + doc=["*.rst","*.png"], gui=["pycomposGUI.py","demo.ui","*.png"], ) diff --git a/Examples/pygui1/using.rst b/Examples/pygui1/using.rst index f28347d..8321bf3 100644 --- a/Examples/pygui1/using.rst +++ b/Examples/pygui1/using.rst @@ -15,3 +15,6 @@ The Object Browser is in a tab, with tree_view Other ---------- +.. image:: exec.png + :align: center + diff --git a/module_generator/__init__.py b/module_generator/__init__.py index 585afa1..650d35a 100644 --- a/module_generator/__init__.py +++ b/module_generator/__init__.py @@ -18,9 +18,9 @@ # """ - Package to generate SALOME modules with components - implemented in C++, Fortran or Python - that can use datastream ports +The python module module_generator defines classes which can be used to define a SALOME module, its components and +generates a SALOME source module, its installation and a SALOME application including this module and +other preexisting SALOME modules like GEOM, SMESH or others. """ from gener import Module, Service, Generator from fcompo import F77Component diff --git a/module_generator/astcompo.py b/module_generator/astcompo.py index 879501b..cb99fcf 100644 --- a/module_generator/astcompo.py +++ b/module_generator/astcompo.py @@ -36,6 +36,30 @@ from aster_tmpl import comm, make_etude, cexe, exeaster from aster_tmpl import container, component class ASTERComponent(Component): + """ + A :class:`ASTERComponent` instance represents an ASTER SALOME component (special component for Code_Aster that is a mix of + Fortran and Python code) with services given as a list of :class:`Service` instances with the parameter *services*. + + :param name: gives the name of the component. + :type name: str + :param services: the list of services (:class:`Service`) of the component. + :param kind: If it is given and has the value "exe", the component will be built as a standalone + component (executable or shell script). The default is to build the component as a dynamic library. + :param libs: gives all the libraries options to add when linking the generated component (-L...). + :param rlibs: gives all the runtime libraries options to add when linking the generated component (-R...). + :param exe_path: is only used when kind is "exe" and gives the path to the standalone component. + :param aster_dir: gives the Code_Aster installation directory. + :param python_path: If it is given (as a list of paths), all the paths are added to the python path (sys.path). + :param argv: is a list of strings that gives the command line parameters for Code_Aster. This parameter is only useful when + kind is "lib". + + For example, the following call defines a Code_Aster component named "mycompo" with one service s1 (it must have been defined before). + This standalone component takes some command line arguments:: + + >>> c1 = module_generator.ASTERComponent('mycompo', services=[s1,], kind="exe", + exe_path="launch.sh", + argv=["-memjeveux","4"]) + """ def __init__(self, name, services=None, libs="", rlibs="", aster_dir="", python_path=None, argv=None, kind="lib", exe_path=None): """initialise component attributes""" diff --git a/module_generator/cppcompo.py b/module_generator/cppcompo.py index eb6edea..f6561f8 100644 --- a/module_generator/cppcompo.py +++ b/module_generator/cppcompo.py @@ -27,6 +27,30 @@ from cpp_tmpl import initService, cxxService, hxxCompo, cxxCompo from cpp_tmpl import exeCPP, compoEXEMakefile, compoMakefile class CPPComponent(Component): + """ + A :class:`CPPComponent` instance represents a C++ SALOME component with services given as a list of :class:`Service` + instances with the parameter *services*. + + :param name: gives the name of the component. + :type name: str + :param services: the list of services (:class:`Service`) of the component. + :param kind: If it is given and has the value "exe", the component will be built as a standalone + component (executable or shell script). The default is to build the component as a dynamic library. + :param libs: gives all the libraries options to add when linking the generated component (-L...). + :param rlibs: gives all the runtime libraries options to add when linking the generated component (-R...). + :param includes: gives all the include options to add when compiling the generated component (-I...). + :param sources: gives all the external source files to add in the compilation step (list of paths). + :param exe_path: is only used when kind is "exe" and gives the path to the standalone component. + :param compodefs: can be used to add extra definition code in the component for example when using a base class + to define the component class by deriving it (see *inheritedclass* parameter) + :param inheritedclass: can be used to define a base class for the component. The base class can be defined in external + source or with the *compodefs* parameter. The value of the *inheritedclass* parameter is the name of the base class. + + For example, the following call defines a standalone component named "mycompo" with one service s1 (it must have been defined before):: + + >>> c1 = module_generator.CPPComponent('mycompo', services=[s1,], kind="exe", + exe_path="./launch.sh") + """ def __init__(self, name, services=None, libs="", rlibs="", includes="", kind="lib", exe_path=None, sources=None, inheritedclass="", compodefs=""): diff --git a/module_generator/fcompo.py b/module_generator/fcompo.py index 55d2baf..c466fe3 100644 --- a/module_generator/fcompo.py +++ b/module_generator/fcompo.py @@ -29,6 +29,27 @@ else: f77Types = {"double":"double *", "long":"long *", "string":"const char *"} class F77Component(CPPComponent): + """ + A :class:`F77Component` instance represents a Fortran SALOME component with services given as a list of :class:`Service` + instances with the parameter *services*. + + :param name: gives the name of the component. + :type name: str + :param services: the list of services (:class:`Service`) of the component. + :param kind: If it is given and has the value "exe", the component will be built as a standalone + component (executable or shell script). The default is to build the component as a dynamic library. + :param libs: gives all the libraries options to add when linking the generated component (-L...). + :param rlibs: gives all the runtime libraries options to add when linking the generated component (-R...). + :param sources: gives all the external source files to add in the compilation step (list of paths). + :param exe_path: is only used when kind is "exe" and gives the path to the standalone component. + + For example, the following call defines a Fortran component named "mycompo" with one service s1 (it must have been defined before). + This component is implemented as a dynamic library linked with a user's library "mylib":: + + >>> c1 = module_generator.F77Component('mycompo', services=[s1,], + libs="-lmylib -Lmydir") + + """ def __init__(self, name, services=None, libs="", rlibs="", kind="lib", exe_path=None, sources=None): CPPComponent.__init__(self, name, services, libs=libs, rlibs=rlibs, diff --git a/module_generator/gener.py b/module_generator/gener.py index 131a181..60bf73b 100644 --- a/module_generator/gener.py +++ b/module_generator/gener.py @@ -61,6 +61,35 @@ def makedirs(namedir): os.makedirs(namedir) class Module(object): + """ + A :class:`Module` instance represents a SALOME module that contains components given as a list of + component instances (:class:`CPPComponent` or :class:`PYComponent` or :class:`F77Component` or :class:`ASTERComponent`) + with the parameter *components*. + + :param name: gives the name of the module. The SALOME source module + will be located in the directory. + :type name: str + :param components: gives the list of components of the module. + :param prefix: is the path of the installation directory. + :param layout: If given and has the value "monodir", all components + will be generated in a single directory. The default is to generate each component in its + own directory. + :param doc: can be used to add an online documentation to the module. It must be a list of file names (sources, images, ...) that will be + used to build a sphinx documentation (see http://sphinx.pocoo.org, for more information). If not given, the Makefile.am + and the conf.py (sphinx configuration) files are generated. In this case, the file name extension of source files must be .rst. + See small examples in Examples/pygui1 and Examples/cppgui1. + :param gui: can be used to add a GUI to the module. It must be a list of file names (sources, images, qt designer files, ...). + If not given, the Makefile.am and SalomeApp.xml are generated. All image files are put in the resources directory of the module. + The GUI can be implemented in C++ (file name extension '.cxx') or in Python (file name extension '.py'). + See small examples in Examples/pygui1 and Examples/cppgui1. + + For example, the following call defines a module named "mymodule" with 2 components c1 and c2 (they must have been + defined before) that will be installed in the "install" directory:: + + >>> m = module_generator.Module('mymodule', components=[c1,c2], + prefix="./install") + + """ def __init__(self, name, components=None, prefix="",layout="multidir", doc=None, gui=None): self.name = name self.components = components or [] @@ -129,6 +158,37 @@ class Component(object): return {} class Service(object): + """ + A :class:`Service` instance represents a component service with dataflow and datastream ports. + + :param name: gives the name of the service. + :type name: str + :param inport: gives the list of input dataflow ports. + :param outport: gives the list of output dataflow ports. An input or output dataflow port is defined + by a 2-tuple (port name, data type name). The list of supported basic data types is: "double", "long", "string", + "dblevec", "stringvec", "intvec", "file" and "pyobj" only for Python services. Depending on the implementation + language, it is also possible to use some types from SALOME modules (see :ref:`yacstypes`). + :param instream: gives the list of input datastream ports. + :param outstream: gives the list of output datastream ports. An input or output datastream port is defined + by a 3-tuple (port name, data type name, mode name). The list of possible data types is: "CALCIUM_double", "CALCIUM_integer", + "CALCIUM_real", "CALCIUM_string", "CALCIUM_complex", "CALCIUM_logical", "CALCIUM_long". The mode can be "I" (iterative mode) + or "T" (temporal mode). + :param defs: gives the source code to insert in the definition section of the component. It can be C++ includes + or Python imports + :type defs: str + :param body: gives the source code to insert in the service call. It can be any C++ + or Python code that fits well in the body of the service method. + :type body: str + + For example, the following call defines a minimal Python service with one input dataflow port (name "a", type double) + and one input datastream port:: + + >>> s1 = module_generator.Service('myservice', inport=[("a","double"),], + instream=[("aa","CALCIUM_double","I")], + body="print a") + + + """ def __init__(self, name, inport=None, outport=None, instream=None, outstream=None, parallel_instream=None, parallel_outstream=None, body="", defs="", impl_type="sequential"): self.name = name @@ -224,6 +284,19 @@ class Service(object): return name, typ class Generator(object): + """ + A :class:`Generator` instance take a :class:`Module` instance as its first parameter and can be used to generate the + SALOME source module, builds it, installs it and includes it in a SALOME application. + + :param module: gives the :class:`Module` instance that will be used for the generation. + :param context: If given , its content is used to specify the prerequisites + environment file (key *"prerequisites"*) and the SALOME KERNEL installation directory (key *"kernel"*). + :type context: dict + + For example, the following call creates a generator for the module m:: + + >>> g = module_generator.Generator(m,context) + """ def __init__(self, module, context=None): self.module = module self.context = context or {} @@ -235,7 +308,7 @@ class Generator(object): raise Invalid("To generate a module with GUI, you need to set the 'gui' parameter in the context dictionnary") def generate(self): - """generate SALOME module as described by module attribute""" + """Generate a SALOME source module""" module = self.module namedir = module.name+"_SRC" force = self.context.get("force") @@ -676,13 +749,13 @@ echo " Qt ..................... : $qt_ok" self.makeFiles(content, filename) def bootstrap(self): - """execute module autogen.sh script: execution of libtool, autoconf, automake""" + """Execute the first build step (bootstrap autotools with autogen.sh script) : execution of libtool, autoconf, automake""" ier = os.system("cd %s_SRC;sh autogen.sh" % self.module.name) if ier != 0: raise Invalid("bootstrap has ended in error") def configure(self): - """execute module configure script with installation prefix (prefix attribute of module)""" + """Execute the second build step (configure) with installation prefix as given by the prefix attribute of module""" prefix = self.module.prefix paco = self.context.get("paco") mpi = self.context.get("mpi") @@ -703,7 +776,7 @@ echo " Qt ..................... : $qt_ok" raise Invalid("configure has ended in error") def make(self): - """execute module Makefile : make""" + """Execute the third build step (compile and link) : make""" make_command = "make " if self.makeflags: make_command += self.makeflags @@ -712,14 +785,39 @@ echo " Qt ..................... : $qt_ok" raise Invalid("make has ended in error") def install(self): - """install module: make install """ + """Execute the installation step : make install """ makedirs(self.module.prefix) ier = os.system("cd %s_SRC;make install" % self.module.name) if ier != 0: raise Invalid("install has ended in error") def make_appli(self, appliname, restrict=None, altmodules=None, resources=""): - """generate SALOME application""" + """ + Create a SALOME application containing the module and preexisting SALOME modules. + + :param appliname: is a string that gives the name of the application (directory path where the application + will be installed). + :type appliname: str + :param restrict: If given (a list of module names), only those SALOME modules will be included in the + application. The default is to include all modules that are located in the same directory as the KERNEL module and have + the same suffix (for example, if KERNEL directory is KERNEL_V5 and GEOM directory is GEOM_V5, GEOM module is automatically + included, except if restrict is used). + :param altmodules: can be used to add SALOME modules that cannot be managed with the precedent rule. This parameter + is a dict with a module name as the key and the installation path as the value. + :param resources: can be used to define an alternative resources catalog (path of the file). + + For example, the following calls create a SALOME application with external modules and resources catalog in "appli" directory:: + + >>> g=Generator(m,context) + >>> g.generate() + >>> g.bootstrap() + >>> g.configure() + >>> g.make() + >>> g.install() + >>> g.make_appli("appli", restrict=["KERNEL"], altmodules={"GUI":GUI_ROOT_DIR, "YACS":YACS_ROOT_DIR}, + resources="myresources.xml") + + """ makedirs(appliname) rootdir, kerdir = os.path.split(self.kernel) diff --git a/module_generator/pycompo.py b/module_generator/pycompo.py index 411c936..27f4c0b 100644 --- a/module_generator/pycompo.py +++ b/module_generator/pycompo.py @@ -35,6 +35,28 @@ def indent(text, prefix=' '): return join(lines, '\n') class PYComponent(Component): + """ + A :class:`PYComponent` instance represents a Python SALOME component with services given as a list of :class:`Service` + instances with the parameter *services*. + + :param name: gives the name of the component. + :type name: str + :param services: the list of services (:class:`Service`) of the component. + :param kind: If it is given and has the value "exe", the component will be built as a standalone + component (python executable). The default is to build the component as a python module. + :param sources: gives all the external Python source files to add in the component directory (list of paths). + :param python_path: If it is given (as a list of paths), all the paths are added to the python path (sys.path). + :param compodefs: can be used to add extra definition code in the component for example when using a base class + to define the component class by deriving it (see *inheritedclass* parameter) + :param inheritedclass: can be used to define a base class for the component. The base class can be defined in external + source or with the *compodefs* parameter. The value of the *inheritedclass* parameter is the name of the base class. + + For example, the following call defines a Python component named "mycompo" with one service s1 (it must have been defined before):: + + >>> c1 = module_generator.PYComponent('mycompo', services=[s1,], + python_path="apath") + + """ def __init__(self, name, services=None, python_path=None, kind="lib", sources=None, inheritedclass="", compodefs=""): """initialise component attributes""" -- 2.39.2