def entry_for_one_class(nom, klas): """ Generate a BUILD dictionary entry for a class. nom: name like 'python_binary' klas: class like pants.python_binary""" try: args, varargs, varkw, defaults = inspect.getargspec(klas.__init__) argspec = inspect.formatargspec(args[1:], varargs, varkw, defaults) funcdoc = klas.__init__.__doc__ methods = [] for attrname in dir(klas): attr = getattr(klas, attrname) attr_bdi = get_builddict_info(attr) if not attr_bdi: continue if inspect.ismethod(attr): methods.append(entry_for_one_method(attrname, attr)) continue raise TaskError( '@manual.builddict on non-method %s within class %s ' 'but I only know what to do with methods' % (attrname, nom)) except TypeError: # __init__ might not be a Python function argspec = None funcdoc = None methods = None return entry(nom, classdoc=klas.__doc__, argspec=argspec, funcdoc=funcdoc, methods=methods)
def entry_for_one_class(nom, cls): """ Generate a BUILD dictionary entry for a class. nom: name like 'python_binary' cls: class like pants.python_binary""" try: args, varargs, varkw, defaults = inspect.getargspec(cls.__init__) argspec = inspect.formatargspec(args[1:], varargs, varkw, defaults) funcdoc = cls.__init__.__doc__ methods = [] for attrname in dir(cls): attr = getattr(cls, attrname) attr_bdi = get_builddict_info(attr) if attr_bdi is None: continue if inspect.ismethod(attr): methods.append(entry_for_one_method(attrname, attr)) continue raise TaskError('@manual.builddict on non-method %s within class %s ' 'but I only know what to do with methods' % (attrname, nom)) except TypeError: # __init__ might not be a Python function argspec = None funcdoc = None methods = None return entry(nom, classdoc=cls.__doc__, argspec=argspec, funcdoc=funcdoc, methods=methods, impl="{0}.{1}".format(cls.__module__, cls.__name__))
def entry_for_one(nom, sym): if inspect.isclass(sym): return entry_for_one_class(nom, sym) info = get_builddict_info(sym) if info and info.get('factory'): # instead of getting factory info, get info about associated class: return entry_for_one_class(nom, sym.im_self) if inspect.ismethod(sym) or inspect.isfunction(sym): return entry_for_one_func(nom, sym) return msg_entry(nom, "TODO! no doc gen for %s %s" % (str(type(sym)), str(sym)), "TODO! no doc gen for %s %s" % (str(type(sym)), str(sym)))
def entry_for_one(nom, sym): if inspect.isclass(sym): return entry_for_one_class(nom, sym) info = get_builddict_info(sym) if info and info.get('factory'): # instead of getting factory info, get info about associated class: return entry_for_one_class(nom, sym.im_self) if inspect.ismethod(sym) or inspect.isfunction(sym): return entry_for_one_func(nom, sym) return msg_entry( nom, "TODO! no doc gen for {} {}".format(str(type(sym)), str(sym)), "TODO! no doc gen for {} {}".format(str(type(sym)), str(sym)))
def assemble(predefs=PREDEFS, symbol_hash=None): """Assemble big hash of entries suitable for smushing into a template. predefs: Hash of "hard-wired" predefined entries. symbol_hash: Python syms from which to generate more entries. Default: get from BUILD context""" d = {} for k in PREDEFS: v = PREDEFS[k] if "suppress" in v and v["suppress"]: continue d[k] = v if symbol_hash is None: symbol_hash = get_syms() for k in symbol_hash: bdi = get_builddict_info(symbol_hash[k]) if bdi is None: continue d[k] = bdi.copy() if not "defn" in d[k]: d[k]["defn"] = entry_for_one(k, symbol_hash[k]) return d
def assemble(predefs=PREDEFS, symbol_hash=None): """Assemble big hash of entries suitable for smushing into a template. predefs: Hash of "hard-wired" predefined entries. symbol_hash: Python syms from which to generate more entries. Default: get from BUILD context""" d = {} for k in PREDEFS: v = PREDEFS[k] if "suppress" in v and v["suppress"]: continue d[k] = v if symbol_hash is None: symbol_hash = get_syms() for k in symbol_hash: bdi = get_builddict_info(symbol_hash[k]) if bdi is None: continue d[k] = bdi.copy() if not "defn" in d[k]: d[k]["defn"] = entry_for_one(k, symbol_hash[k]) return d
def assemble(predefs=PREDEFS, build_file_parser=None): """Assemble big hash of entries suitable for smushing into a template. predefs: Hash of "hard-wired" predefined entries. build_file_parser: BuildFileParser which knows the BUILD-file symbols defined for this run of Pants; hopefully knows ~the same symbols defined for a "typical" run of Pants. """ retval = {} for nom in PREDEFS: val = PREDEFS[nom] if "suppress" in val and val["suppress"]: continue retval[nom] = val if build_file_parser: symbol_hash = get_syms(build_file_parser) for nom in symbol_hash: bdi = get_builddict_info(symbol_hash[nom]) if bdi is None: continue retval[nom] = bdi.copy() if not "defn" in retval[nom]: retval[nom]["defn"] = entry_for_one(nom, symbol_hash[nom]) return retval
def assemble_buildsyms(predefs=PREDEFS, build_file_parser=None): """Assemble big hash of entries suitable for smushing into a template. predefs: Hash of "hard-wired" predefined entries. build_file_parser: BuildFileParser which knows the BUILD-file symbols defined for this run of Pants; hopefully knows ~the same symbols defined for a "typical" run of Pants. """ retval = {} for nom in predefs: val = predefs[nom] if 'suppress' in val and val['suppress']: continue retval[nom] = val if build_file_parser: symbol_hash = get_syms(build_file_parser) for nom in symbol_hash: v = symbol_hash[nom] bdi = get_builddict_info(v) if bdi and 'suppress' in bdi and bdi['suppress']: continue retval[nom] = {'defn': entry_for_one(nom, v)} return retval
def assemble_buildsyms(predefs=PREDEFS, build_file_parser=None): """Assemble big hash of entries suitable for smushing into a template. predefs: Hash of "hard-wired" predefined entries. build_file_parser: BuildFileParser which knows the BUILD-file symbols defined for this run of Pants; hopefully knows ~the same symbols defined for a "typical" run of Pants. """ retval = {} for nom in predefs: val = predefs[nom] if 'suppress' in val and val['suppress']: continue retval[nom] = val if build_file_parser: symbol_hash = get_syms(build_file_parser) for nom in symbol_hash: v = symbol_hash[nom] bdi = get_builddict_info(v) if bdi and 'suppress' in bdi and bdi['suppress']: continue retval[nom] = {'defn': entry_for_one(nom, v)} return retval
def entry_for_one_class(nom, cls): """ Generate a BUILD dictionary entry for a class. nom: name like 'python_binary' cls: class like pants.python_binary""" if issubclass(cls, Target): # special case for Target classes: "inherit" information up the class tree. (argspec, funcdoc_rst, paramdocs) = info_for_target_class(cls) else: args, varargs, varkw, defaults = inspect.getargspec(cls.__init__) argspec = inspect.formatargspec(args[1:], varargs, varkw, defaults) funcdoc_shards = shard_param_docstring( dedent_docstring(cls.__init__.__doc__)) paramdocs = param_docshards_to_template_datas(funcdoc_shards) funcdoc_rst = cls.__init__.__doc__ methods = [] for attrname in dir(cls): attr = getattr(cls, attrname) info = get_builddict_info(attr) # we want methods tagged @manual.builddict--except factory functions if info and not info.get('factory', False): if inspect.ismethod(attr): methods.append(entry_for_one_method(attrname, attr)) else: raise TaskError('@manual.builddict() on non-method {0}' ' within class {1}'.format(attrname, nom)) return entry(nom, classdoc_rst=cls.__doc__, classdoc_html=rst_to_html(dedent_docstring(cls.__doc__)), argspec=argspec, funcdoc_rst=funcdoc_rst, methods=methods, paramdocs=paramdocs, impl='{0}.{1}'.format(cls.__module__, cls.__name__))
def entry_for_one_class(nom, cls): """ Generate a BUILD dictionary entry for a class. nom: name like 'python_binary' cls: class like pants.python_binary""" if issubclass(cls, Target): # special case for Target classes: "inherit" information up the class tree. (argspec, funcdoc_rst, paramdocs) = info_for_target_class(cls) else: args, varargs, varkw, defaults = inspect.getargspec(cls.__init__) argspec = inspect.formatargspec(args[1:], varargs, varkw, defaults) funcdoc_shards = shard_param_docstring(dedent_docstring(cls.__init__.__doc__)) paramdocs = param_docshards_to_template_datas(funcdoc_shards) funcdoc_rst = cls.__init__.__doc__ methods = [] for attrname in dir(cls): attr = getattr(cls, attrname) info = get_builddict_info(attr) # we want methods tagged @manual.builddict--except factory functions if info and not info.get("factory", False): if inspect.ismethod(attr): methods.append(entry_for_one_method(attrname, attr)) else: raise TaskError("@manual.builddict() on non-method {0}" " within class {1}".format(attrname, nom)) return entry( nom, classdoc_rst=cls.__doc__, classdoc_html=rst_to_html(dedent_docstring(cls.__doc__)), argspec=argspec, funcdoc_rst=funcdoc_rst, methods=methods, paramdocs=paramdocs, impl="{0}.{1}".format(cls.__module__, cls.__name__), )
def entry_for_one_class(nom, cls): """ Generate a BUILD dictionary entry for a class. nom: name like 'python_binary' cls: class like pants.python_binary""" if issubclass(cls, Target): # special case for Target classes: "inherit" information up the class tree. args_accumulator = [] defaults_accumulator = () docs_accumulator = [] for c in inspect.getmro(cls): if not issubclass(c, Target): continue if not inspect.ismethod(c.__init__): continue args, _, _, defaults = inspect.getargspec(c.__init__) args_accumulator = args[1:] + args_accumulator defaults_accumulator = (defaults or ()) + defaults_accumulator dedented_doc = dedent_docstring(c.__init__.__doc__) docs_accumulator.append(shard_param_docstring(dedented_doc)) # Suppress these from BUILD dictionary: they're legit args to the # Target implementation, but they're not for BUILD files: assert(args_accumulator[1] == 'address') assert(args_accumulator[2] == 'build_graph') args_accumulator = [args_accumulator[0]] + args_accumulator[3:] defaults_accumulator = (defaults_accumulator[0],) + defaults_accumulator[3:] argspec = inspect.formatargspec(args_accumulator, None, None, defaults_accumulator) # Suppress these from BUILD dictionary: they're legit args to the # Target implementation, but they're not for BUILD files: suppress = set(['address', 'build_graph', 'payload']) funcdoc_rst = '' funcdoc_shards = OrderedDict() for shard in docs_accumulator: for param, parts in shard.items(): if param in suppress: continue suppress.add(param) # only show things once funcdoc_shards[param] = parts # Don't interpret param names like "type_" as links. if 'type' in parts: funcdoc_rst += '\n:type {0}: {1}'.format(param, parts['type']) if 'param' in parts: funcdoc_rst += '\n:param {0}: {1}'.format(param, parts['param']) paramdocs = param_docshards_to_template_datas(funcdoc_shards) else: args, varargs, varkw, defaults = inspect.getargspec(cls.__init__) argspec = inspect.formatargspec(args[1:], varargs, varkw, defaults) funcdoc_shards = shard_param_docstring(dedent_docstring(cls.__init__.__doc__)) paramdocs = param_docshards_to_template_datas(funcdoc_shards) funcdoc_rst = cls.__init__.__doc__ methods = [] for attrname in dir(cls): attr = getattr(cls, attrname) info = get_builddict_info(attr) # we want methods tagged @manual.builddict--except factory functions if info and not info.get('factory', False): if inspect.ismethod(attr): methods.append(entry_for_one_method(attrname, attr)) else: raise TaskError('@manual.builddict() on non-method {0}' ' within class {1}'.format(attrname, nom)) return entry(nom, classdoc_rst=cls.__doc__, classdoc_html=rst_to_html(dedent_docstring(cls.__doc__)), argspec=argspec, funcdoc_rst=funcdoc_rst, methods=methods, paramdocs=paramdocs, impl='{0}.{1}'.format(cls.__module__, cls.__name__))
def entry_for_one_class(nom, cls): """ Generate a BUILD dictionary entry for a class. nom: name like 'python_binary' cls: class like pants.python_binary""" if issubclass(cls, Target): # special case for Target classes: "inherit" information up the class tree. args_accumulator = [] defaults_accumulator = () docs_accumulator = [] for c in inspect.getmro(cls): if not issubclass(c, Target): continue if not inspect.ismethod(c.__init__): continue args, _, _, defaults = inspect.getargspec(c.__init__) args_accumulator = args[1:] + args_accumulator defaults_accumulator = (defaults or ()) + defaults_accumulator dedented_doc = indent_docstring_by_n(c.__init__.__doc__, 0) docs_accumulator.append(shard_param_docstring(dedented_doc)) # Suppress these from BUILD dictionary: they're legit args to the # Target implementation, but they're not for BUILD files: assert(args_accumulator[1] == 'address') assert(args_accumulator[2] == 'build_graph') assert(args_accumulator[3] == 'payload') args_accumulator = [args_accumulator[0]] + args_accumulator[4:] defaults_accumulator = (defaults_accumulator[0],) + defaults_accumulator[4:] argspec = inspect.formatargspec(args_accumulator, None, None, defaults_accumulator) # Suppress these from BUILD dictionary: they're legit args to the # Target implementation, but they're not for BUILD files: suppress = set(['address', 'build_graph', 'payload']) funcdoc = '' for shard in docs_accumulator: for param, parts in shard.items(): if param in suppress: continue suppress.add(param) # only show things once if 'param' in parts: funcdoc += '\n:param {0}: {1}'.format(param, parts['param']) if 'type' in parts: funcdoc += '\n:type {0}: {1}'.format(param, parts['type']) else: args, varargs, varkw, defaults = inspect.getargspec(cls.__init__) argspec = inspect.formatargspec(args[1:], varargs, varkw, defaults) funcdoc = cls.__init__.__doc__ methods = [] for attrname in dir(cls): attr = getattr(cls, attrname) attr_bdi = get_builddict_info(attr) if attr_bdi is None: continue if inspect.ismethod(attr): methods.append(entry_for_one_method(attrname, attr)) continue raise TaskError('@manual.builddict on non-method %s within class %s ' 'but I only know what to do with methods' % (attrname, nom)) return entry(nom, classdoc=cls.__doc__, argspec=argspec, funcdoc=funcdoc, methods=methods, impl='{0}.{1}'.format(cls.__module__, cls.__name__))
def entry_for_one_class(nom, cls): """ Generate a BUILD dictionary entry for a class. nom: name like 'python_binary' cls: class like pants.python_binary""" if issubclass(cls, Target): # special case for Target classes: "inherit" information up the class tree. args_accumulator = [] defaults_accumulator = () docs_accumulator = [] for c in inspect.getmro(cls): if not issubclass(c, Target): continue if not inspect.ismethod(c.__init__): continue args, _, _, defaults = inspect.getargspec(c.__init__) args_accumulator = args[1:] + args_accumulator defaults_accumulator = (defaults or ()) + defaults_accumulator dedented_doc = indent_docstring_by_n(c.__init__.__doc__, 0) docs_accumulator.append(shard_param_docstring(dedented_doc)) # Suppress these from BUILD dictionary: they're legit args to the # Target implementation, but they're not for BUILD files: assert args_accumulator[1] == "address" assert args_accumulator[2] == "build_graph" assert args_accumulator[3] == "payload" args_accumulator = [args_accumulator[0]] + args_accumulator[4:] defaults_accumulator = (defaults_accumulator[0],) + defaults_accumulator[4:] argspec = inspect.formatargspec(args_accumulator, None, None, defaults_accumulator) # Suppress these from BUILD dictionary: they're legit args to the # Target implementation, but they're not for BUILD files: suppress = set(["address", "build_graph", "payload"]) funcdoc = "" for shard in docs_accumulator: for param, parts in shard.items(): if param in suppress: continue suppress.add(param) # only show things once if "param" in parts: funcdoc += "\n:param {0}: {1}".format(param, parts["param"]) if "type" in parts: funcdoc += "\n:type {0}: {1}".format(param, parts["type"]) else: args, varargs, varkw, defaults = inspect.getargspec(cls.__init__) argspec = inspect.formatargspec(args[1:], varargs, varkw, defaults) funcdoc = cls.__init__.__doc__ methods = [] for attrname in dir(cls): attr = getattr(cls, attrname) attr_bdi = get_builddict_info(attr) if attr_bdi is None: continue if inspect.ismethod(attr): methods.append(entry_for_one_method(attrname, attr)) continue raise TaskError( "@manual.builddict on non-method %s within class %s " "but I only know what to do with methods" % (attrname, nom) ) return entry( nom, classdoc=cls.__doc__, argspec=argspec, funcdoc=funcdoc, methods=methods, impl="{0}.{1}".format(cls.__module__, cls.__name__), )