1import py, sys
2
3class DeprecationWarning(DeprecationWarning):
4    def __init__(self, msg, path, lineno):
5        self.msg = msg
6        self.path = path
7        self.lineno = lineno
8    def __repr__(self):
9        return "%s:%d: %s" %(self.path, self.lineno+1, self.msg)
10    def __str__(self):
11        return self.msg
12
13def _apiwarn(startversion, msg, stacklevel=2, function=None):
14    # below is mostly COPIED from python2.4/warnings.py's def warn()
15    # Get context information
16    if isinstance(stacklevel, str):
17        frame = sys._getframe(1)
18        level = 1
19        found = frame.f_code.co_filename.find(stacklevel) != -1
20        while frame:
21            co = frame.f_code
22            if co.co_filename.find(stacklevel) == -1:
23                if found:
24                    stacklevel = level
25                    break
26            else:
27                found = True
28            level += 1
29            frame = frame.f_back
30        else:
31            stacklevel = 1
32    msg = "%s (since version %s)" %(msg, startversion)
33    warn(msg, stacklevel=stacklevel+1, function=function)
34
35
36def warn(msg, stacklevel=1, function=None):
37    if function is not None:
38        import inspect
39        filename = inspect.getfile(function)
40        lineno = py.code.getrawcode(function).co_firstlineno
41    else:
42        try:
43            caller = sys._getframe(stacklevel)
44        except ValueError:
45            globals = sys.__dict__
46            lineno = 1
47        else:
48            globals = caller.f_globals
49            lineno = caller.f_lineno
50        if '__name__' in globals:
51            module = globals['__name__']
52        else:
53            module = "<string>"
54        filename = globals.get('__file__')
55    if filename:
56        fnl = filename.lower()
57        if fnl.endswith(".pyc") or fnl.endswith(".pyo"):
58            filename = filename[:-1]
59        elif fnl.endswith("$py.class"):
60            filename = filename.replace('$py.class', '.py')
61    else:
62        if module == "__main__":
63            try:
64                filename = sys.argv[0]
65            except AttributeError:
66                # embedded interpreters don't have sys.argv, see bug #839151
67                filename = '__main__'
68        if not filename:
69            filename = module
70    path = py.path.local(filename)
71    warning = DeprecationWarning(msg, path, lineno)
72    import warnings
73    warnings.warn_explicit(warning, category=Warning,
74        filename=str(warning.path),
75        lineno=warning.lineno,
76        registry=warnings.__dict__.setdefault(
77            "__warningsregistry__", {})
78    )
79
80