def visit_ClassDef(self, node):  # pylint: disable=invalid-name
        """Visit top-level classes."""
        # Resolve everything as root scope contains everything from the process module.
        for base in node.bases:
            # Cover `from resolwe.process import ...`.
            if isinstance(base, ast.Name) and isinstance(base.ctx, ast.Load):
                base = getattr(runtime, base.id, None)
            # Cover `from resolwe import process`.
            elif isinstance(base, ast.Attribute) and isinstance(base.ctx, ast.Load):
                base = getattr(runtime, base.attr, None)
            else:
                continue

            if issubclass(base, runtime.Process):
                break
        else:
            return

        descriptor = ProcessDescriptor(source=self.source)

        # Available embedded classes.
        embedded_class_fields = {
            runtime.PROCESS_INPUTS_NAME: descriptor.inputs,
            runtime.PROCESS_OUTPUTS_NAME: descriptor.outputs,
        }

        # Parse metadata in class body.
        for item in node.body:
            if isinstance(item, ast.Assign):
                # Possible metadata.
                if (len(item.targets) == 1 and isinstance(item.targets[0], ast.Name)
                        and isinstance(item.targets[0].ctx, ast.Store)
                        and item.targets[0].id in PROCESS_METADATA):
                    # Try to get the metadata value.
                    value = PROCESS_METADATA[item.targets[0].id].get_value(item.value)
                    setattr(descriptor.metadata, item.targets[0].id, value)
            elif (isinstance(item, ast.Expr) and isinstance(item.value, ast.Str)
                  and descriptor.metadata.description is None):
                # Possible description string.
                descriptor.metadata.description = item.value.s
            elif isinstance(item, ast.ClassDef) and item.name in embedded_class_fields.keys():
                # Possible input/output declaration.
                self.visit_field_class(item, descriptor, embedded_class_fields[item.name])

        descriptor.validate()
        self.processes.append(descriptor)
def visit_ClassDef ( self , node ) : for base in node . bases : if isinstance ( base , ast . Name ) and isinstance ( base . ctx , ast . Load ) : base = getattr ( runtime , base . id , None ) elif isinstance ( base , ast . Attribute ) and isinstance ( base . ctx , ast . Load ) : base = getattr ( runtime , base . attr , None ) else : continue if issubclass ( base , runtime . Process ) : break else : return descriptor = ProcessDescriptor ( source = self . source ) embedded_class_fields = { runtime . PROCESS_INPUTS_NAME : descriptor . inputs , runtime . PROCESS_OUTPUTS_NAME : descriptor . outputs , } for item in node . body : if isinstance ( item , ast . Assign ) : if ( len ( item . targets ) == 1 and isinstance ( item . targets [ 0 ] , ast . Name ) and isinstance ( item . targets [ 0 ] . ctx , ast . Store ) and item . targets [ 0 ] . id in PROCESS_METADATA ) : value = PROCESS_METADATA [ item . targets [ 0 ] . id ] . get_value ( item . value ) setattr ( descriptor . metadata , item . targets [ 0 ] . id , value ) elif ( isinstance ( item , ast . Expr ) and isinstance ( item . value , ast . Str ) and descriptor . metadata . description is None ) : descriptor . metadata . description = item . value . s elif isinstance ( item , ast . ClassDef ) and item . name in embedded_class_fields . keys ( ) : self . visit_field_class ( item , descriptor , embedded_class_fields [ item . name ] ) descriptor . validate ( ) self . processes . append ( descriptor )
Visit top-level classes.