def createPyDocumentation(path, origin, language): isErrorPy = False # create commonServerPy json doc commonServerPython = readYmlFile(path) pyScript = commonServerPython.get("script", "") code = compile(pyScript, '<string>', 'exec') ns = {} exec code in ns x = [] for a in ns: if callable(ns.get(a)) and a not in pyPrivateFuncs: docstring = inspect.getdoc(ns.get(a)) if not docstring: print "docstring for function " + a + " is empty" isErrorPy = True else: y = parser.parse_docstring(docstring) y["name"] = a y["argList"] = list(inspect.getargspec(ns.get(a)))[0] if pyIrregularFuncs.get(a, None) is None \ else pyIrregularFuncs[a]["argList"] x.append(y) if isErrorPy: return None, isErrorPy return reformatPythonOutput(x, origin, language)
def test_parse_docstring(self): docstring = """ Return a Zone instance. Second line docsting. :type zone_id: ``str`` :param zone_id: Required zone id (required) :keyword auth: Initial authentication information for the node (optional) :type auth: :class:`NodeAuthSSHKey` or `NodeAuthPassword` :return: instance :rtype: :class:`Zone` or `Node` """ result = parser.parse_docstring(docstring) description = result['description'] args = result['arguments'] return_type = result['return']['type_name'] return_description = result['return']['description'] self.assertTrue(description.startswith('Return')) self.assertTrue('Second line' in description) self.assertEqual(args['zone_id']['type_name'], '``str``') self.assertEqual(args['zone_id']['required'], True) self.assertItemsEqual(args['auth']['type_name'], 'class:`NodeAuthSSHKey` or `NodeAuthPassword`') self.assertEqual(args['auth']['required'], False) self.assertEqual(return_type, 'class:`Zone` or `Node`') self.assertEqual(return_description, 'instance')
def construct_arguments(self, cls, positional_args={}): ''' Adds arguments to subparsers, returns populated dict of methods and their details. :param cls: the class to parse for methods to use :type cls: type :param positional_args: a dict of argument names per method name which should be used as positional argument. :type positional_args: dict :rtype: dict :return: a dict with metadata used for creating the cli arguments with argparse ''' arg_result = {} for method in inspect.getmembers(cls, is_api_method): name = method[1].__name__ docstring = parser.get_method_docstring(cls, name) result = parser.parse_docstring(docstring, cls) result['class'] = cls pretty_name = name[len(API_MARKER) + 1:] # adding argument to subparsers positional_arg = positional_args.get(pretty_name, None) result['positional_arg'] = positional_arg arg = self.create_arg_object(cls, pretty_name, result['arguments'], result['return'], result['description'], positional_arg) arg_result[pretty_name] = result return arg_result
def createPyDocumentation(path, origin, language): isErrorPy = False with open(path, 'r') as file: pyScript = clean_python_code(file.read(), remove_print_future=False) code = compile(pyScript, '<string>', 'exec') ns = {'demisto': demistomock} exec(code, ns) # guardrails-disable-line x = [] for a in ns: if a != 'demisto' and callable(ns.get(a)) and a not in pyPrivateFuncs: docstring = inspect.getdoc(ns.get(a)) if not docstring: print("docstring for function {} is empty".format(a)) isErrorPy = True else: y = parser.parse_docstring(docstring) y["name"] = a y["argList"] = list(inspect.getargspec(ns.get(a)))[0] if pyIrregularFuncs.get(a, None) is None \ else pyIrregularFuncs[a]["argList"] x.append(y) if isErrorPy: return None, isErrorPy return reformatPythonOutput(x, origin, language)
def __init__(self, driver_obj, method_name): if inspect.isclass(driver_obj): self.driver_cls = driver_obj else: self.driver_cls = driver_obj.__class__ self.driver_obj = driver_obj self.method_name = method_name self.method = getattr(self.driver_obj, method_name, None) if not inspect.ismethod(self.method): raise NoSuchOperationError() method_doc = get_method_docstring(self.driver_cls, method_name) if not method_doc: raise MethodParsingException('Empty docstring') argspec_arg = parse_args(self.method) docstring_parse_result = parse_docstring(method_doc, self.driver_cls) self.description = docstring_parse_result['description'] docstring_args = docstring_parse_result['arguments'] #check vargs self.vargs_entries = [] self.req_vargs_entries = [] for name, arg_info in docstring_args.items(): docstring_arg_tmp = docstring_args[name] #print docstring_arg_tmp entry_kwargs = { 'name': name, 'description': docstring_arg_tmp['description'], 'type_name': docstring_arg_tmp['type_name'], 'required': (docstring_arg_tmp['required'] or arg_info['required']), } if not entry_kwargs['required']: self.vargs_entries.append(entry_kwargs) else: self.req_vargs_entries.append(entry_kwargs) #update kwargs kwargs = set(docstring_args).difference(argspec_arg) self.kwargs_entries = [] for entry in kwargs: kwargs_entry = { 'name':entry, 'description':docstring_args[entry]['description'], 'type_name':docstring_args[entry]['type_name'], 'required':docstring_args[entry]['required'] } self.kwargs_entries.append(kwargs_entry) method_return = docstring_parse_result['return'] self.result_entry = method_return
def create_py_documentation(path, origin, language): is_error_py = False with open(path, 'r') as file: py_script = YmlUnifier.clean_python_code(file.read(), remove_print_future=False) logging.info("replacing DemistoClassApiModule: ") py_script = re.sub(r'from DemistoClassApiModule import \*[ \t]*(#.*)?', "", py_script) code = compile(py_script, '<string>', 'exec') ns = {'demisto': demistomock} exec(code, ns) # guardrails-disable-line # pylint: disable=W0122 x: list = [] for a in ns: a_object = ns.get(a) if a != 'demisto' and callable(a_object) and a not in PY_PRIVATE_FUNCS and ns \ and a_object.__module__ in (None, 'builtin', 'builtins'): docstring = inspect.getdoc(a_object) if not docstring: logging.error("docstring for function {} is empty".format(a)) is_error_py = True elif 'ignore docstring' in docstring: continue else: try: y = parser.parse_docstring(docstring) y["name"] = a logging.info('Processing {}'.format(a)) if inspect.isclass(a_object): y["argList"] = list(inspect.getfullargspec(a_object.__init__))[0] \ if PY_IRREGULAR_FUNCS.get(a, None) is None \ else PY_IRREGULAR_FUNCS[a]["argList"] # init will contains self, so remove the self from the arg list y["argList"].remove('self') else: y["argList"] = list(inspect.getfullargspec(a_object))[0] \ if PY_IRREGULAR_FUNCS.get(a, None) is None \ else PY_IRREGULAR_FUNCS[a]["argList"] x.append(y) except parser.MethodParsingException: logging.exception('Failed to parse {} class/function'.format(a)) is_error_py = True if is_error_py: return None, is_error_py return reformat_python_output(x, origin, language)
def test_foo_create_node(self): docstring = parser.get_method_docstring(self.Foo, 'create_node') result = parser.parse_docstring(docstring, self.Foo) description = result['description'] args = result['arguments'] return_type = result['return']['type_name'] return_description = result['return']['description'] self.assertTrue(description.startswith('Create a new node ')) self.assertEqual(len(args), 2) self.assertEqual('``str``', args['name']['type_name']) self.assertEqual('``dict``', args['size']['type_name']) self.assertEqual(return_type, 'class:`Node`') self.assertEqual(return_description, 'The newly created node.')
def from_pdoc(cls, element): is_class = isinstance(element, pdoc.Class) method = cls(element.refname, element.name, is_class) components = element.refname.split('.') mod = __import__(components[0]) for comp in components[1:]: mod = getattr(mod, comp) # Get method line number. method.add_source_line(get_source_line_number(mod)) # Get method Examples. examples = get_examples_from_docstring(element.docstring) if examples: method.add_example(examples) if element.docstring: if not isinstance(element, pdoc.Class) and element.cls: klass = element.cls.cls elif element.cls: klass = element.cls else: klass = None # Hack for old-style classes if not str(klass).startswith('<'): klass = '<class \'%s\'>' % (klass,) try: method_info = parse_docstring(element.docstring, klass) except (MethodParsingException, IndexError): return method for name, data in method_info['arguments'].items(): param = Param.from_docstring_section(name, data) method.add_param(param) if method_info.get('return'): if len(method_info['return']['type_name']) > 0: type_name = method_info.get('return').get('type_name') type_type = 'instance' if any(x.isupper() for x in type_name): type_type = 'constructor' type_markup = build_link_from_type(type_name, type_type) method.set_returns(type_markup) return method
def from_pdoc(cls, element): is_class = isinstance(element, pdoc.Class) method = cls(element.refname, element.name, is_class) components = element.refname.split('.') mod = __import__(components[0]) for comp in components[1:]: mod = getattr(mod, comp) # Get method line number. method.add_source_line(get_source_line_number(mod)) # Get method Examples. examples = get_examples_from_docstring(element.docstring) if examples: method.add_example(examples) if element.docstring: if not isinstance(element, pdoc.Class) and element.cls: klass = element.cls.cls elif element.cls: klass = element.cls else: klass = None # Hack for old-style classes if not str(klass).startswith('<'): klass = '<class \'%s\'>' % (klass, ) try: method_info = parse_docstring(element.docstring, klass) except (MethodParsingException, IndexError): return method for name, data in method_info['arguments'].items(): param = Param.from_docstring_section(name, data) method.add_param(param) if method_info.get('return'): if len(method_info['return']['type_name']) > 0: type_name = method_info.get('return').get('type_name') type_type = 'instance' if any(x.isupper() for x in type_name): type_type = 'constructor' type_markup = build_link_from_type(type_name, type_type) method.set_returns(type_markup) return method
def test_bar_deploy_node(self): docstring = parser.get_method_docstring(self.Bar, 'deploy_node') result = parser.parse_docstring(docstring, self.Bar) description = result['description'] args = result['arguments'] return_type = result['return']['type_name'] return_description = result['return']['description'] self.assertTrue(description.startswith('Deploy bar node')) self.assertEqual(len(args), 3) self.assertEqual('class:`NodeAuthSSHKey`', args['deploy']['type_name']) self.assertEqual('``str``', args['name']['type_name']) self.assertEqual('``dict``', args['size']['type_name']) self.assertEqual(return_type, 'class:`Node`') self.assertEqual(return_description, 'The newly created node.')
def test_bar_create_node(self): docstring = parser.get_method_docstring(self.Bar, 'create_node') result = parser.parse_docstring(docstring, self.Bar) description = result['description'] args = result['arguments'] return_type = result['return']['type_name'] return_description = result['return']['description'] self.assertTrue(description.startswith('Create a new bar node')) self.assertEqual(len(args), 3) self.assertEqual('``str``', args['name']['type_name']) self.assertEqual('``dict``', args['size']['type_name']) self.assertEqual('``str``', args['ex_fqdn']['type_name']) self.assertEqual(return_type, 'class:`Node`') self.assertEqual(return_description, 'New bar node')
def create_py_documentation(path, origin, language): is_error_py = False with open(path, 'r') as file: py_script = Unifier.clean_python_code(file.read(), remove_print_future=False) code = compile(py_script, '<string>', 'exec') ns = {'demisto': demistomock} exec(code, ns) # guardrails-disable-line x = [] for a in ns: if a != 'demisto' and callable( ns.get(a)) and a not in PY_PRIVATE_FUNCS: docstring = inspect.getdoc(ns.get(a)) if not docstring: print("docstring for function {} is empty".format(a)) is_error_py = True elif 'ignore docstring' in docstring: continue else: try: y = parser.parse_docstring(docstring) y["name"] = a print('Processing {}'.format(a)) if inspect.isclass(ns.get(a)): y["argList"] = list(inspect.getargspec(ns.get(a).__init__))[0] \ if PY_IRREGULAR_FUNCS.get(a, None) is None \ else PY_IRREGULAR_FUNCS[a]["argList"] # init will contains self, so remove the self from the arg list y["argList"].remove('self') else: y["argList"] = list(inspect.getargspec(ns.get(a)))[0] if PY_IRREGULAR_FUNCS.get(a, None) is None \ else PY_IRREGULAR_FUNCS[a]["argList"] x.append(y) except parser.MethodParsingException as ex: print( 'Failed to parse {} class/function.\nError: {}'.format( a, str(ex))) is_error_py = True if is_error_py: return None, is_error_py return reformat_python_output(x, origin, language)
def createPyDocumentation(path, origin, language): # create commonServerPy json doc commonServerPython = readYmlFile(path) pyScript = commonServerPython.get("script", "") code = compile(pyScript, '<string>', 'exec') ns = {} exec code in ns x = [] for a in ns: if callable(ns.get(a)) and a not in pyPrivateFuncs: y = parser.parse_docstring((inspect.getdoc(ns.get(a)))) y["name"] = a x.append(y) return reformatPythonOutput(x, origin, language)
for a in ns: <<<<<<< HEAD a_object = ns.get(a) if a != 'demisto' and callable(a_object) and a not in PY_PRIVATE_FUNCS and ns \ and a_object.__module__ in (None, 'builtin', 'builtins'): docstring = inspect.getdoc(a_object) if not docstring: logging.error("docstring for function {} is empty".format(a)) is_error_py = True elif 'ignore docstring' in docstring: continue else: try: y = parser.parse_docstring(docstring) y["name"] = a logging.info('Processing {}'.format(a)) if inspect.isclass(a_object): y["argList"] = list(inspect.getfullargspec(a_object.__init__))[0] \ if PY_IRREGULAR_FUNCS.get(a, None) is None \ else PY_IRREGULAR_FUNCS[a]["argList"] # init will contains self, so remove the self from the arg list y["argList"].remove('self') else: y["argList"] = list(inspect.getfullargspec(a_object))[0] \ if PY_IRREGULAR_FUNCS.get(a, None) is None \ else PY_IRREGULAR_FUNCS[a]["argList"]