def caseFactory(): from inspect import findsource g = globals().copy() cases = [g[obj] for obj in g if obj.startswith("Test") and issubclass(g[obj], unittest.TestCase)] ordered_cases = sorted(cases, key=lambda f: findsource(f)[1]) return ordered_cases
def getsourcelines(object): """Return a list of source lines and starting line number for an object. Parameters ---------- object : a python object The argument may be a module, class, method, function, traceback, frame, or code object. The source code is returned as a string with the lines corresponding to the object and the line number indicates where in the original source file the first line of code was found. An IOError is raised if the source code cannot be retrieved.""" lines, lnum = inspect.findsource(object) if inspect.ismodule(object): lnum = 0 ss = '' for x in lines: ss += x else: lines = inspect.getblock(lines[lnum:]) lnum = lnum + 1 ss = '' for x in lines: ss += x return ss, 0
def get_source(frame): """ get source lines for this frame Params --- frame : frame object Returns --- lines : list of str startline : int location of lines[0] in the original source file """ # TODO find out what's faster: Allowing inspect's getsourcelines # to tokenize the whole file to find the surrounding code block, # or getting the whole file quickly via linecache & feeding all # of it to our own instance of tokenize, then clipping to # desired context afterwards. if frame.f_code.co_name in NON_FUNCTION_SCOPES: lines, _ = inspect.findsource(frame) startline = 1 else: lines, startline = inspect.getsourcelines(frame) return lines, startline
def linkcode_resolve(domain, info): """ Determine the URL corresponding to Python object """ if domain != 'py': return None modname = info['module'] fullname = info['fullname'] submod = sys.modules.get(modname) if submod is None: return None obj = submod for part in fullname.split('.'): try: obj = getattr(obj, part) except: return None try: fn = inspect.getsourcefile(obj) except: fn = None if not fn: return None try: source, lineno = inspect.findsource(obj) except: lineno = None if lineno: linespec = "#L%d" % (lineno + 1) else: linespec = "" fn = relpath(fn, start='../') return '{}/blob/{}/{}{}'.format(GITHUB_URL, code_branch, fn, linespec)
def from_module(cls, module): """Get new context from module object and parse source for linenos""" sourcepath = inspect.getsourcefile(module) # TODO: fix this to do the right thing rather than rely on cwd relpath = os.path.relpath(sourcepath) return cls(relpath, _source_info=_parse_source("".join(inspect.findsource(module)[0]), module.__file__))
def reached(t, v=None): """ Execute if a tainted value reaches a sensitive sink for the vulnerability v. If the module-level variable ENDS is set to True, then the sink is not executed and the reached function is executed instead. If ENDS is set to False, the reached function is executed but the program continues its flow. The provided de facto implementation alerts that the violation happened and information to find the error. """ frame = sys._getframe(3) filename = inspect.getfile(frame) lno = frame.f_lineno print "=" * 79 print "Violation in line %d from file %s" % (lno, filename) # Localize this message print "Tainted value: %s" % t print "-" * 79 lineas = inspect.findsource(frame)[0] lineas = [" %s" % l for l in lineas] lno = lno - 1 lineas[lno] = "--> " + lineas[lno][4:] lineas = lineas[lno - 3 : lno + 3] print "".join(lineas) print "=" * 79
def _printlonglist(self, linerange=None): try: if self.curframe.f_code.co_name == '<module>': # inspect.getsourcelines is buggy in this case: if we just # pass the frame, it returns the source for the first function # defined in the module. Instead, we want the full source # code of the module lines, _ = inspect.findsource(self.curframe) lineno = 1 else: try: lines, lineno = inspect.getsourcelines(self.curframe) except Exception as e: print('** Error in inspect.getsourcelines: %s **' % e, file=self.stdout) return except IOError as e: print('** Error: %s **' % e, file=self.stdout) return if linerange: start, end = linerange start = max(start, lineno) end = min(end, lineno + len(lines)) lines = lines[start - lineno:end - lineno] lineno = start self._print_lines_pdbpp(lines, lineno)
def _GetFileAndLine(component): """Returns the filename and line number of component. Args: component: A component to find the source information for, usually a class or routine. Returns: filename: The name of the file where component is defined. lineno: The line number where component is defined. """ if inspect.isbuiltin(component): return None, None try: filename = inspect.getsourcefile(component) except TypeError: return None, None try: unused_code, lineindex = inspect.findsource(component) lineno = lineindex + 1 except IOError: lineno = None return filename, lineno
def get_encoding(obj): """Try to obtain encoding information of the source of an object.""" for line in inspect.findsource(obj)[0][:2]: m = get_encoding_line_re.search(line) if m: return m.group(1) return "ascii"
def getsourcelines(obj): (lines, lineno) = inspect.findsource(obj) if inspect.isframe(obj) and obj.f_globals is obj.f_locals: return (lines, 1) if inspect.ismodule(obj): return (lines, 1) return (inspect.getblock(lines[lineno:]), lineno + 1)
def get_source(obj): """Get object's source code. Returns None when source can't be found. """ from inspect import findsource try: lines, lnum = findsource(obj) except (IOError, TypeError): return None return lines, lnum
def function_ast(f): """ Returns ast for the given function. Gives a tuple of (ast_module, function_body, function_file :param f: The function to parse :type f: Callable :return: The relevant AST code: A module including only the function definition; the func body; the func file :rtype: tuple(Module, list(AST), str) """ try: f_file = sys.modules[f.__module__].__file__ except (KeyError, AttributeError): # pragma: nocover f_file = '' try: found = inspect.findsource(f) except IndexError as err: # pragma: nocover raise IOError( ('Discrepancy in number of decorator @magics expected by ' 'inspect vs. __code__.co_firstlineno\n' '{} in {}.\n' 'Try using the decorators after declaring the function' 'instead of @-magic').format(f, f_file)) from err root = ast.parse(textwrap.dedent(inspect.getsource(f)), f_file) return root, root.body[0].body, f_file
def test_getfslineno() -> None: def f(x) -> None: raise NotImplementedError() fspath, lineno = getfslineno(f) assert isinstance(fspath, py.path.local) assert fspath.basename == "test_source.py" assert lineno == f.__code__.co_firstlineno - 1 # see findsource class A: pass fspath, lineno = getfslineno(A) _, A_lineno = inspect.findsource(A) assert isinstance(fspath, py.path.local) assert fspath.basename == "test_source.py" assert lineno == A_lineno assert getfslineno(3) == ("", -1) class B: pass B.__name__ = B.__qualname__ = "B2" assert getfslineno(B)[1] == -1 co = compile("...", "", "eval") assert co.co_filename == "" if hasattr(sys, "pypy_version_info"): assert getfslineno(co) == ("", -1) else: assert getfslineno(co) == ("", 0)
def blender_findsource(object): lines, text_name = blender_findsourcetext(object) try: filename = blender_findsource._si_cache[lines] except KeyError: fd, filename = tempfile.mkstemp(prefix='SI_Blender_', suffix=f'_{text_name}.py') os.close(fd) with open(filename, 'w') as f: f.write(lines) blender_findsource._si_cache[lines] = filename def hooked_getfile(o): if id(o) == id(object): return filename return inspect._si_old_getfile(o) inspect._si_old_getfile = inspect.getfile inspect.getfile = hooked_getfile ret = inspect.findsource(object) inspect.getfile = inspect._si_old_getfile del inspect._si_old_getfile return ret
def linkcode_resolve(domain, info): """ Determine the URL corresponding to Python object """ if domain != 'py': return None modname = info['module'] fullname = info['fullname'] submod = sys.modules.get(modname) if submod is None: return None obj = submod for part in fullname.split('.'): try: obj = getattr(obj, part) except: return None try: fn = inspect.getsourcefile(obj) except: fn = None if not fn: return None try: source, lineno = inspect.findsource(obj) except: lineno = None if lineno: linespec = "#L%d" % (lineno + 1) else: linespec = "" fn = relpath(fn, start='..') return "https://github.com/mithrandi/txacme/blob/%s/%s%s" % ( txacme_version_info['full-revisionid'], fn, linespec)
def get_encoding(obj): """Try to obtain encoding information of the source of an object.""" for line in inspect.findsource(obj)[0][:2]: m = get_encoding_re.search(line) if m: return m.group(1) return 'ascii'
def collectMetaData(obj): data = {} data["name"] = obj.__name__ if inspect.isclass(obj): if issubclass(obj, Sofa.Core.Controller): data["type"] = "Controller" elif issubclass(obj, Sofa.Core.DataEngine): data["type"] = "DataEngine" elif issubclass(obj, Sofa.Core.ForceField): data["type"] = "ForceField" elif issubclass(obj, Sofa.Core.RawPrefab): data["type"] = "SofaPrefab" else: data["type"] = "Class" elif obj.__name__ is "createScene": data["type"] = "SofaScene" elif obj.__name__ is "SofaPrefabF" or type(obj) == Sofa.PrefabBuilder: data["type"] = "SofaPrefab" else: data["type"] = "Function" ## Class and Function are not callabled from the GUI. Unless having the callable decorator if data["type"] == "Class" or data["type"] == "Function": return None data["params"] = inspect.getfullargspec( obj.__original__ if "__original__" in dir(obj) else obj) data["sourcecode"] = inspect.getsource( obj.__original__ if "__original__" in dir(obj) else obj) data["docstring"] = obj.__original__.__doc__ if "__original__" in dir( obj) else obj.__doc__ if obj.__doc__ != None else "" data["lineno"] = str( inspect.findsource(obj.__original__ if "__original__" in dir(obj) else obj)[1]) return data
def _get_class_methods(cls): """Get a class as an argument and return a list of it's methods that the method name start with the word 'test'. The list is sorted by its line position in the module file :type cls: (class) :return: (list) of 2 dimension elements: first element is the method name, second element is line position of the element """ # Initialize a array to store methods methods = [] # Get all the methods of 'cls' (class) cls_methods = dir(cls) # start a loop to check if a method is a 'test_method' for method in cls_methods: # check if the method name starts with 'test' if method[0:4] == "test": # get a reference to the method func = getattr(cls, method) # get the line position of the method in it's module file position = inspect.findsource(func)[1] # add the method and its line position to the list 'methods methods.append([method, position]) # sort the methods by the line position methods.sort(key=lambda x: x[1]) return methods
def _get_full_source(program: Any, source: str) -> str: """Get full source code of the program Parameters ---------- program : Any The python function or class. source : str The source code of the program without other codes in the same file. Returns ------- str The full source code """ try: # It will cause a problem when running in Jupyter Notebook. # `mod` will be <module '__main__'>, which is a built-in module # and `getsource` will throw a TypeError mod = inspect.getmodule(program) if mod is not None: return inspect.getsource(mod) else: return source except TypeError: # It's a work around for Jupyter problem. # Since `findsource` is an internal API of inspect, we just use it # as a fallback method. full_source, _ = inspect.findsource(program) return "".join(full_source)
def from_module(cls, module): """Get new context from module object and parse source for linenos""" sourcepath = inspect.getsourcefile(module) # TODO: fix this to do the right thing rather than rely on cwd relpath = os.path.relpath(sourcepath) return cls(relpath, _source_info=_parse_source("".join(inspect.findsource(module)[0])))
def _ghostwrite_condition_code(condition: Callable[..., Any]) -> str: """Ghostwrite the code representing the condition in an assumption.""" if not icontract._represent.is_lambda(a_function=condition): sign = inspect.signature(condition) args = ", ".join(param for param in sign.parameters.keys()) return "{}({})".format(condition.__name__, args) # We need to extract the source code corresponding to the decorator since # inspect.getsource() is broken with lambdas. # Find the line corresponding to the condition lambda lines, condition_lineno = inspect.findsource(condition) filename = inspect.getsourcefile(condition) assert filename is not None decorator_inspection = icontract._represent.inspect_decorator( lines=lines, lineno=condition_lineno, filename=filename) lambda_inspection = icontract._represent.find_lambda_condition( decorator_inspection=decorator_inspection) assert ( lambda_inspection is not None ), "Expected lambda_inspection to be non-None if is_lambda is True on: {}".format( condition) return lambda_inspection.text
def introspect_docstring_lineno(api_doc): """ Try to determine the line number on which the given item's docstring begins. Return the line number, or C{None} if the line number can't be determined. The line number of the first line in the file is 1. """ if api_doc.docstring_lineno is not UNKNOWN: return api_doc.docstring_lineno if isinstance(api_doc, ValueDoc) and api_doc.pyval is not UNKNOWN: try: lines, lineno = inspect.findsource(api_doc.pyval) if not isinstance(api_doc, ModuleDoc): lineno += 1 for lineno in range(lineno, len(lines)): if lines[lineno].split('#', 1)[0].strip(): api_doc.docstring_lineno = lineno + 1 return lineno + 1 except IOError: pass except TypeError: pass except IndexError: log.warning('inspect.findsource(%s) raised IndexError' % api_doc.canonical_name) return None
def getErrorTraceKIS(self, tb=None): out = [] nr = 1 filename0 = "unknown" linenr0 = 0 func0 = "unknown" frs = self.getFrames(tb=tb) frs.reverse() for f, linenr in frs: try: code, linenr2 = inspect.findsource(f) except IOError: continue start = max(linenr - 10, 0) stop = min(linenr + 4, len(code)) code2 = "".join(code[start:stop]) finfo = inspect.getframeinfo(f) linenr3 = linenr - start - 1 out.append( (finfo.filename, finfo.function, linenr3, code2, linenr)) if nr == 1: filename0 = finfo.filename linenr0 = linenr func0 = finfo.function return out, filename0, linenr0, func0
def function_to_ast(f): """ Obtain the source code of a Python function and create an AST. :param f: Python function. :return: A 4-tuple of (AST, function filename, function line-number, source code as string). """ try: src = inspect.getsource(f) src_file = inspect.getfile(f) _, src_line = inspect.findsource(f) # TypeError: X is not a module, class, method, function, traceback, frame, # or code object; OR OSError: could not get source code except (TypeError, OSError): # Try to import dill to obtain code from compiled functions try: import dill src = dill.source.getsource(f) src_file = '<interpreter>' src_line = 0 except (ImportError, ModuleNotFoundError, TypeError, OSError): raise TypeError( 'Cannot obtain source code for dace program. This may ' 'happen if you are using the "python" default ' 'interpreter. Please either use the "ipython" ' 'interpreter, a Jupyter or Colab notebook, or place ' 'the source code in a file and import it.') src_ast = ast.parse(_remove_outer_indentation(src)) ast.increment_lineno(src_ast, src_line) return src_ast, src_file, src_line, src
def Info(component): """Returns a dict with information about the given component. The dict will have at least some of the following fields. type_name: The type of `component`. string_form: A string representation of `component`. file: The file in which `component` is defined. line: The line number at which `component` is defined. docstring: The docstring of `component`. init_docstring: The init docstring of `component`. class_docstring: The class docstring of `component`. call_docstring: The call docstring of `component`. length: The length of `component`. Args: component: The component to analyze. Returns: A dict with information about the component. """ import IPython # pylint: disable=g-import-not-at-top inspector = IPython.core.oinspect.Inspector() info = inspector.info(component) try: unused_code, lineindex = inspect.findsource(component) info['line'] = lineindex + 1 except (TypeError, IOError): info['line'] = None return info
def reached(t, v=None): ''' Execute if a tainted value reaches a sensitive sink for the vulnerability v. If the module-level variable ENDS is set to True, then the sink is not executed and the reached function is executed instead. If ENDS is set to False, the reached function is executed but the program continues its flow. The provided de facto implementation alerts that the violation happened and information to find the error. ''' frame = sys._getframe(3) filename = inspect.getfile(frame) lno = frame.f_lineno print("=" * 79) print("Violation in line %d from file %s" % (lno, filename)) # Localize this message print("Tainted value: %s" % t) print('-' * 79) lineas = inspect.findsource(frame)[0] lineas = [' %s' % l for l in lineas] lno = lno - 1 lineas[lno] = '--> ' + lineas[lno][4:] lineas = lineas[lno - 3: lno + 3] print("".join(lineas)) print("=" * 79)
def test_getfslineno(): from _pytest._code import getfslineno def f(x): pass fspath, lineno = getfslineno(f) assert fspath.basename == "test_source.py" assert lineno == _pytest._code.getrawcode(f).co_firstlineno - 1 # see findsource class A(object): pass fspath, lineno = getfslineno(A) _, A_lineno = inspect.findsource(A) assert fspath.basename == "test_source.py" assert lineno == A_lineno assert getfslineno(3) == ("", -1) class B(object): pass B.__name__ = "B2" assert getfslineno(B)[1] == -1
def _printlonglist(self, linerange=None): try: if self.curframe.f_code.co_name == '<module>': # inspect.getsourcelines is buggy in this case: if we just # pass the frame, it returns the source for the first function # defined in the module. Instead, we want the full source # code of the module lines, _ = inspect.findsource(self.curframe) lineno = 1 else: try: lines, lineno = inspect.getsourcelines(self.curframe) except Exception as e: print('** Error in inspect.getsourcelines: %s **' % e, file=self.stdout) return except IOError as e: print('** Error: %s **' % e, file=self.stdout) return if linerange: start, end = linerange start = max(start, lineno) end = min(end, lineno+len(lines)) lines = lines[start-lineno:end-lineno] lineno = start self._print_lines_pdbpp(lines, lineno)
def test_getfslineno() -> None: from _pytest._code import getfslineno def f(x) -> None: pass fspath, lineno = getfslineno(f) assert fspath.basename == "test_source.py" assert lineno == f.__code__.co_firstlineno - 1 # see findsource class A: pass fspath, lineno = getfslineno(A) _, A_lineno = inspect.findsource(A) assert fspath.basename == "test_source.py" assert lineno == A_lineno assert getfslineno(3) == ("", -1) class B: pass B.__name__ = "B2" assert getfslineno(B)[1] == -1
def get_comment_doc(obj): """Get lines of comments immediately preceding an object's source code. Returns None when source can't be found. """ from inspect import findsource, ismodule try: lines, lnum = findsource(obj) except (IOError, TypeError): return None if ismodule(obj): lnum = 0 # Look for a comment block at the top of the file. start = lnum if lnum == 0: if lines and lines[0][:2] == '#!': start = 1 else: start += 1 if lines[start].lstrip()[:3] == 'def': start += 1 while start < len(lines) and lines[start].strip() in ('', '#'): start = start + 1 if start < len(lines) and lines[start].lstrip()[:1] == '#': comments = [] end = start while end < len(lines) and lines[end].lstrip()[:1] == '#': comments.append(lines[end].strip()[2:]) end = end + 1 return '\n'.join(comments)
def getErrorTraceKIS(self,tb=None): out=[] nr=1 filename0="unknown" linenr0=0 func0="unknown" frs=self.getFrames(tb=tb) frs.reverse() for f,linenr in frs: try: code,linenr2=inspect.findsource(f) except IOError: continue start=max(linenr-10,0) stop=min(linenr+4,len(code)) code2="".join(code[start:stop]) finfo=inspect.getframeinfo(f) linenr3=linenr-start-1 out.append((finfo.filename,finfo.function,linenr3,code2,linenr)) if nr==1: filename0=finfo.filename linenr0=linenr func0=finfo.function return out,filename0,linenr0,func0
def log_type(args_kw, ret, func, slf=False, prop_getter=False, clss=None, argspecs=None, args_kw_type=None, ret_type=None): """Stores information of a function or method call into a cache, so pytypes can create a PEP 484 stubfile from this information later on (see dump_cache). """ if args_kw_type is None: args_kw_type = deep_type(args_kw) if ret_type is None: ret_type = deep_type(ret) if argspecs is None: argspecs = getargspecs(func) node = _register_logged_func(func, slf, prop_getter, clss, argspecs) node.add_observation(args_kw_type, ret_type) md = util.getmodule_for_member(func, prop_getter) if not md.__name__ in _module_file_map: _module_file_map[md.__name__] = md.__file__ if clss is None: try: clss = util.get_class_that_defined_method(func) except ValueError: pass if not clss is None and not clss in _member_line_map: _member_line_map[clss] = findsource(clss)[1]
def get_comment_doc(obj, lines=None, lnum=None): """Get lines of comments immediately preceding an object's source code. Returns None when source can't be found. """ from inspect import ismodule if lines is None: try: from inspect import findsource lines, lnum = findsource(obj) except (IOError, TypeError): return None if ismodule(obj): lnum = 0 # Look for a comment block at the top of the file. start = lnum if lnum == 0: if lines and lines[0][:2] == '#!': start = 1 else: start += 1 if lines[start].lstrip()[:3] == 'def': start += 1 while start < len(lines) and lines[start].strip() in ('', '#'): start = start + 1 if start < len(lines) and lines[start].lstrip()[:1] == '#': comments = [] end = start while end < len(lines) and lines[end].lstrip()[:1] == '#': comments.append(lines[end].strip()[2:]) end = end + 1 return '\n'.join(comments)
def test_getfslineno() -> None: def f(x) -> None: raise NotImplementedError() fspath, lineno = getfslineno(f) assert isinstance(fspath, Path) assert fspath.name == "test_source.py" assert lineno == f.__code__.co_firstlineno - 1 # see findsource class A: pass fspath, lineno = getfslineno(A) _, A_lineno = inspect.findsource(A) assert isinstance(fspath, Path) assert fspath.name == "test_source.py" assert lineno == A_lineno assert getfslineno(3) == ("", -1) class B: pass B.__name__ = B.__qualname__ = "B2" assert getfslineno(B)[1] == -1
def obj_signature(obj): try: filename = inspect.getsourcefile(obj) lines, lineno = inspect.findsource(obj) except TypeError: filename, lineno = '__builtin__', None return (obj.__name__, filename, lineno)
def findsource(obj): try: sourcelines, lineno = inspect.findsource(obj) except Exception: return None, -1 source = Source() source.lines = [line.rstrip() for line in sourcelines] return source, lineno
def warn_class(klass: type, message): """Issue a warning directed at a class, not the line of code issuing the warning.""" modname = klass.__module__ module = sys.modules[modname] filename = module.__file__ lineno = inspect.findsource(klass)[1] + 1 print('%s:%d: Warning: %s: %s' % (filename, lineno, klass.__qualname__, message))
def findsource(obj) -> Tuple[Optional[Source], int]: try: sourcelines, lineno = inspect.findsource(obj) except Exception: return None, -1 source = Source() source.lines = [line.rstrip() for line in sourcelines] return source, lineno
def getsourcelines(self, obj): lines, lineno = inspect.findsource(obj) if inspect.isframe(obj) and obj.f_globals is obj.f_locals: # must be a module frame: do not try to cut a block out of it return lines, 1 elif inspect.ismodule(obj): return lines, 1 return inspect.getblock(lines[lineno:]), lineno + 1
def test_findsource_code_in_linecache(self): lines = ["x=1"] co = compile(lines[0], "_dynamically_created_file", "exec") self.assertRaises(IOError, inspect.findsource, co) self.assertRaises(IOError, inspect.getsource, co) linecache.cache[co.co_filename] = (1, None, lines, co.co_filename) self.assertEqual(inspect.findsource(co), (lines,0)) self.assertEqual(inspect.getsource(co), lines[0])
def cacherun(fun, *args, **kwargs): """ This function runs the given function with the passed arguments. However, when the same function (function source is checked) has been run with the same arguments before, its result is loaded from a cache file. If this function was run before with the same arguments, return cached results instead. :args: fun (function): the function to be run. Must be a python function (no build-in function). Its source code is hashed. *args : sequence of positional arguments **kwargs : sequence of keyword arguments :returns: result of fun(*args, **kwargs) """ try: os.mkdir('.cache') except OSError: pass # open persistent dict index = shelve.open(os.sep.join(['.cache','shelf_pickle'])) hf = hashlib.sha256() # update hashfunction with function hf.update(cPickle.dumps(inspect.findsource(fun))) for arg in args: hf.update(cPickle.dumps(arg)) for key in sorted(kwargs.keys()): hf.update(cPickle.dumps(key)) hf.update(cPickle.dumps(kwargs[key])) hash_ = hf.hexdigest() if hash_ in index.keys(): ffname = os.sep.join(['.cache', index[hash_]]) with open( ffname , 'rb') as f: res = cPickle.load(f) else: # compute res = fun(*args, **kwargs) # store # get new file name fh, fn = tempfile.mkstemp(suffix='.pickle', prefix='cache', dir='.cache', text=False) os.close(fh) fname = fn.split(os.sep)[-1] ffname = os.sep.join(['.cache', fname]) with open( ffname, 'wb') as f: cPickle.dump(res, f) index[hash_] = fname index.sync() index.close() return res
def _get_test_funcs(cls): testcase_methods = dir(unittest.TestCase) for m in inspect.classify_class_attrs(cls): if m.kind == 'method' and \ m.defining_class == cls and \ not m.name.startswith('_') and \ m.name not in testcase_methods: yield (inspect.findsource(getattr(cls, m.name))[1], m.name)
def github_linkcode_resolve(domain, info): """Return a link to the source on GitHub for the given autodoc info.""" if (domain != 'py' or not info['module'] or not info['module'].startswith('reviewboard')): # These aren't the modules you're looking for. return None # Grab the module referenced in the docs. submod = sys.modules.get(info['module']) if submod is None: return None # Split that, trying to find the module at the very tail of the module # path. obj = submod for part in info['fullname'].split('.'): try: obj = getattr(obj, part) except: return None # Grab the name of the source file. try: filename = inspect.getsourcefile(obj) except: filename = None if not filename: return None filename = os.path.relpath(filename, start=os.path.dirname(reviewboard.__file__)) # Find the line number of the thing being documented. try: linenum = inspect.findsource(obj)[1] except: linenum = None # Build a reference for the line number in GitHub. if linenum: linespec = '#L%d' % (linenum + 1) else: linespec = '' # Get the branch/tag/commit to link to. ref = get_git_doc_ref() if not ref: ref = _get_branch_for_version() return ('https://github.com/reviewboard/reviewboard/blob/%s/reviewboard/' '%s%s' % (ref, filename, linespec))
def linkcode_resolve(domain, info): """Determine the URL corresponding to Python object This code is stolen with thanks from the scipy team. """ if domain != 'py': return None modname = info['module'] fullname = info['fullname'] submod = sys.modules.get(modname) if submod is None: return None obj = submod for part in fullname.split('.'): try: obj = getattr(obj, part) except: return None # try and sneak past a decorator try: obj = obj.im_func.func_closure[0].cell_contents except (AttributeError, TypeError): pass try: fn = inspect.getsourcefile(obj) except: fn = None if not fn: try: fn = inspect.getsourcefile(sys.modules[obj.__module__]) except: fn = None if not fn: return None try: source, lineno = inspect.findsource(obj) except: lineno = None if lineno: linespec = "#L%d" % (lineno + 1) else: linespec = "" fn = os.path.relpath(fn, start=os.path.dirname(gwpy.__file__)) if fn.startswith(os.path.pardir): return None tag = gwpy_version.git_tag or gwpy_version.git_branch return ("http://github.com/gwpy/gwpy/tree/%s/gwpy/%s%s" % (tag, fn, linespec))
def findsource(obj): try: sourcelines, lineno = inspect.findsource(obj) except py.builtin._sysex: raise except: # noqa return None, -1 source = Source() source.lines = [line.rstrip() for line in sourcelines] return source, lineno
def import_path_to_file_path(path): try: obj = get_object(path) except (AttributeError, ImportError) as e: error('error opening %r: %s' % (path, str(e))) try: _source, lineno = inspect.findsource(obj) except TypeError: try: _source, lineno = inspect.findsource(obj.__class__) except TypeError as e: error('error opening %r: %s' % (path, str(e))) except IOError as e: # allow opening an empty module (e.g. __init__.py) if inspect.ismodule(obj): sourcefile = inspect.getsourcefile(obj) if sourcefile: lineno = 0 e = None if e: error('error opening %r: %s' % (path, str(e))) try: path = inspect.getsourcefile(obj) except TypeError: try: path = inspect.getsourcefile(obj.__class__) except TypeError as e: error('error opening %r: %s' % (path, str(e))) except IOError: path = obj.__file__ if lineno: additional_args = ['+%d' % (lineno+1)] else: additional_args = [] dirname, basename = os.path.split(path) return dirname, basename, additional_args
def findsource(obj): """Return the entire source file and starting line number for an object. The argument may be a module, class, method, function, traceback, frame, or code object. The source code is returned as a list of all the lines in the file and the line number indexes a line in that list. An IOError is raised if the source code cannot be retrieved.""" filename = inspect.getsourcefile(obj) if filename: linecache.checkcache(filename) return inspect.findsource(obj)
def caseFactory(scope,caseSorter=None,regex_test=None, caseSuperCls=unittest.TestCase): """Get test objects by occurence in the incoming scope.""" if not scope: scope = globals().copy() if not caseSorter: caseSorter = lambda f: inspect.findsource(f)[1] if not regex_test: regex_test = "^Test" caseMatches = re.compile(regex_test) return sorted([scope[obj] for obj in scope if inspect.isclass(scope[obj]) and issubclass(scope[obj],caseSuperCls) and re.match(caseMatches,obj) ],key=caseSorter)
def getframeinfo(frame, context=1): """ Get information about a frame or traceback object. A tuple of five things is returned: the filename, the line number of the current line, the function name, a list of lines of context from the source code, and the index of the current line within that list. The optional second argument specifies the number of lines of context to return, which are centered around the current line. This originally comes from ``inspect`` but is modified to handle issues with ``findsource()``. """ if inspect.istraceback(frame): lineno = frame.tb_lineno frame = frame.tb_frame else: lineno = frame.f_lineno if not inspect.isframe(frame): raise TypeError('arg is not a frame or traceback object') filename = inspect.getsourcefile(frame) or inspect.getfile(frame) if context > 0: start = lineno - 1 - context // 2 try: lines, lnum = inspect.findsource(frame) except Exception: # findsource raises platform-dependant exceptions first_lines = lines = index = None else: start = max(start, 1) start = max(0, min(start, len(lines) - context)) first_lines = lines[:2] lines = lines[start:(start + context)] index = lineno - 1 - start else: first_lines = lines = index = None # Code taken from Django's ExceptionReporter._get_lines_from_file if first_lines and isinstance(first_lines[0], bytes): encoding = 'ascii' for line in first_lines[:2]: # File coding may be specified. Match pattern from PEP-263 # (http://www.python.org/dev/peps/pep-0263/) match = re.search(br'coding[:=]\s*([-\w.]+)', line) if match: encoding = match.group(1).decode('ascii') break lines = [line.decode(encoding, 'replace') for line in lines] if hasattr(inspect, 'Traceback'): return inspect.Traceback(filename, lineno, frame.f_code.co_name, lines, index) else: return (filename, lineno, frame.f_code.co_name, lines, index)
def source(obj): """Displays the source code of an object. Applies syntax highlighting if Pygments is available. """ import sys from inspect import findsource, getmodule, getsource, getsourcefile try: # Check to see if the object is defined in a shared library, which # findsource() doesn't do properly (see issue4050) if not getsourcefile(obj): raise TypeError() s = getsource(obj) except TypeError: __trash__ = sys.stderr.write("Source code unavailable (maybe it's " "part of a C extension?\n") return import re enc = 'ascii' for line in findsource(getmodule(obj))[0][:2]: m = re.search(r'coding[:=]\s*([-\w.]+)', line) if m: enc = m.group(1) try: s = s.decode(enc, 'replace') except LookupError: s = s.decode('ascii', 'replace') try: if sys.platform == 'win32': raise ImportError() from pygments import highlight from pygments.lexers import PythonLexer from pygments.formatters import TerminalFormatter s = highlight(s, PythonLexer(), TerminalFormatter()) except (ImportError, UnicodeError): pass import os from pydoc import pager has_lessopts = 'LESS' in os.environ lessopts = os.environ.get('LESS', '') try: os.environ['LESS'] = lessopts + ' -R' pager(s.encode(sys.stdout.encoding, 'replace')) finally: if has_lessopts: os.environ['LESS'] = lessopts else: os.environ.pop('LESS', None)
def linkcode_resolve(domain, info): """ Determine the URL corresponding to Python object Code from scipy: http://nullege.com/codes/show/src@s@c@scipy-HEAD@doc@[email protected] """ if domain != 'py': return None modname = info['module'] fullname = info['fullname'] submod = sys.modules.get(modname) if submod is None: return None obj = submod for part in fullname.split('.'): try: obj = getattr(obj, part) except: return None try: fn = inspect.getsourcefile(obj) except: fn = None if not fn: try: fn = inspect.getsourcefile(sys.modules[obj.__module__]) except: fn = None if not fn: return None try: source, lineno = inspect.findsource(obj) except: lineno = None if lineno: linespec = "#L%d" % (lineno + 1) else: linespec = "" fn = relpath(fn, start=dirname(FlowCytometryTools.__file__)) uri_to_doc = r'//github.com/eyurtsev/FlowCytometryTools/blob/{hexsha}/FlowCytometryTools/{file_name}{line_number}' return uri_to_doc.format(hexsha=commit_hash, file_name=fn, line_number=linespec)
def get_func_source(obj): """Get object's source code. Returns None when source can't be found. """ from inspect import findsource from dis import findlinestarts try: lines, lnum = findsource(obj) ls = list(findlinestarts(obj.func_code)) lstart = ls[0][1] lend = ls[-1][1] except (IOError, TypeError): return None return ''.join(lines[lstart-1:lend])
def linkcode_resolve(domain, info): """ Determine the URL corresponding to Python object """ if domain != 'py': return None modname = info['module'] fullname = info['fullname'] submod = sys.modules.get(modname) if submod is None: return None obj = submod for part in fullname.split('.'): try: obj = getattr(obj, part) except: return None try: fn = inspect.getsourcefile(obj) except: fn = None if not fn: try: fn = inspect.getsourcefile(sys.modules[obj.__module__]) except: fn = None if not fn: return None try: source, lineno = inspect.findsource(obj) except: lineno = None if lineno: linespec = "#L%d" % (lineno + 1) else: linespec = "" fn = relpath(fn, start=dirname(skbio.__file__)) if 'dev' in skbio.__version__: return "http://github.com/biocore/scikit-bio/blob/master/skbio/%s%s" % ( fn, linespec) else: return "http://github.com/biocore/scikit-bio/blob/%s/skbio/%s%s" % ( skbio.__version__, fn, linespec)
def linkcode_resolve(domain, info): """ Determine the URL corresponding to Python object """ import inspect from os.path import relpath, dirname import pipeline import subprocess if domain != 'py': return None modname = info['module'] fullname = info['fullname'] submod = sys.modules.get(modname) if submod is None: return None obj = submod for part in fullname.split('.'): try: obj = getattr(obj, part) except: return None try: fn = inspect.getsourcefile(obj) except: fn = None if not fn: return None try: source, lineno = inspect.findsource(obj) except: lineno = None if lineno: linespec = "#L%d" % (lineno + 1) else: linespec = "" fn = relpath(fn, start=dirname(pipeline.__file__)) p = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE) git_rev, err = p.communicate() git_rev = git_rev.decode('utf-8').rstrip('\n') print(git_rev) print(fn) return "https://github.com/BioroboticsLab/bb_pipeline/blob/{}/pipeline/{}{}".format( git_rev, fn, linespec)