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
35def warn(msg, stacklevel=1, function=None):
36    if function is not None:
37        filename = py.std.inspect.getfile(function)
38        lineno = py.code.getrawcode(function).co_firstlineno
39    else:
40        try:
41            caller = sys._getframe(stacklevel)
42        except ValueError:
43            globals = sys.__dict__
44            lineno = 1
45        else:
46            globals = caller.f_globals
47            lineno = caller.f_lineno
48        if '__name__' in globals:
49            module = globals['__name__']
50        else:
51            module = "<string>"
52        filename = globals.get('__file__')
53    if filename:
54        fnl = filename.lower()
55        if fnl.endswith(".pyc") or fnl.endswith(".pyo"):
56            filename = filename[:-1]
57        elif fnl.endswith("$py.class"):
58            filename = filename.replace('$py.class', '.py')
59    else:
60        if module == "__main__":
61            try:
62                filename = sys.argv[0]
63            except AttributeError:
64                # embedded interpreters don't have sys.argv, see bug #839151
65                filename = '__main__'
66        if not filename:
67            filename = module
68    path = py.path.local(filename)
69    warning = DeprecationWarning(msg, path, lineno)
70    py.std.warnings.warn_explicit(warning, category=Warning,
71        filename=str(warning.path),
72        lineno=warning.lineno,
73        registry=py.std.warnings.__dict__.setdefault(
74            "__warningsregistry__", {})
75    )
76
77