Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
2526c94e
Commit
2526c94e
authored
Jan 07, 2016
by
Marius Wachtler
1
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1029 from Daetalus/pyerr_warnex
Implement PyErr_WarnEx
parents
b3bacb8f
d4e924b0
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
1073 additions
and
22 deletions
+1073
-22
from_cpython/CMakeLists.txt
from_cpython/CMakeLists.txt
+1
-0
from_cpython/Include/Python.h
from_cpython/Include/Python.h
+1
-0
from_cpython/Include/frameobject.h
from_cpython/Include/frameobject.h
+98
-0
from_cpython/Include/sysmodule.h
from_cpython/Include/sysmodule.h
+3
-0
from_cpython/Python/_warnings.c
from_cpython/Python/_warnings.c
+926
-0
src/runtime/builtin_modules/sys.cpp
src/runtime/builtin_modules/sys.cpp
+5
-0
src/runtime/capi.cpp
src/runtime/capi.cpp
+5
-19
src/runtime/frame.cpp
src/runtime/frame.cpp
+16
-0
src/runtime/traceback.cpp
src/runtime/traceback.cpp
+4
-0
src/runtime/types.cpp
src/runtime/types.cpp
+2
-0
test/tests/warnings_test.py
test/tests/warnings_test.py
+12
-3
No files found.
from_cpython/CMakeLists.txt
View file @
2526c94e
...
...
@@ -114,6 +114,7 @@ file(GLOB_RECURSE STDPYTHON_SRCS Python
Python-ast.c
random.c
structmember.c
_warnings.c
)
# compile specified files in from_cpython/Python
...
...
from_cpython/Include/Python.h
View file @
2526c94e
...
...
@@ -74,6 +74,7 @@
#include "classobject.h"
#include "cobject.h"
#include "fileobject.h"
#include "frameobject.h"
#include "pycapsule.h"
#include "traceback.h"
#include "sliceobject.h"
...
...
from_cpython/Include/frameobject.h
0 → 100644
View file @
2526c94e
/* Frame object interface */
#ifndef Py_FRAMEOBJECT_H
#define Py_FRAMEOBJECT_H
#ifdef __cplusplus
extern
"C"
{
#endif
// Pyston changes: we don't use it for now.
#if 0
typedef struct {
int b_type; /* what kind of block this is */
int b_handler; /* where to jump to find handler */
int b_level; /* value stack level to pop to */
} PyTryBlock;
typedef struct _frame {
PyObject_VAR_HEAD
struct _frame *f_back; /* previous frame, or NULL */
PyCodeObject *f_code; /* code segment */
PyObject *f_builtins; /* builtin symbol table (PyDictObject) */
PyObject *f_globals; /* global symbol table (PyDictObject) */
PyObject *f_locals; /* local symbol table (any mapping) */
PyObject **f_valuestack; /* points after the last local */
/* Next free slot in f_valuestack. Frame creation sets to f_valuestack.
Frame evaluation usually NULLs it, but a frame that yields sets it
to the current stack top. */
PyObject **f_stacktop;
PyObject *f_trace; /* Trace function */
/* If an exception is raised in this frame, the next three are used to
* record the exception info (if any) originally in the thread state. See
* comments before set_exc_info() -- it's not obvious.
* Invariant: if _type is NULL, then so are _value and _traceback.
* Desired invariant: all three are NULL, or all three are non-NULL. That
* one isn't currently true, but "should be".
*/
PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;
PyThreadState *f_tstate;
int f_lasti; /* Last instruction if called */
/* Call PyFrame_GetLineNumber() instead of reading this field
directly. As of 2.3 f_lineno is only valid when tracing is
active (i.e. when f_trace is set). At other times we use
PyCode_Addr2Line to calculate the line from the current
bytecode index. */
int f_lineno; /* Current line number */
int f_iblock; /* index in f_blockstack */
PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */
PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */
} PyFrameObject;
/* Standard object interface */
PyAPI_DATA(PyTypeObject) PyFrame_Type;
#define PyFrame_Check(op) ((op)->ob_type == &PyFrame_Type)
#define PyFrame_IsRestricted(f) \
((f)->f_builtins != (f)->f_tstate->interp->builtins)
PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *,
PyObject *, PyObject *);
/* The rest of the interface is specific for frame objects */
/* Block management functions */
PyAPI_FUNC(void) PyFrame_BlockSetup(PyFrameObject *, int, int, int);
PyAPI_FUNC(PyTryBlock *) PyFrame_BlockPop(PyFrameObject *);
/* Extend the value stack */
PyAPI_FUNC(PyObject **) PyFrame_ExtendStack(PyFrameObject *, int, int);
/* Conversions between "fast locals" and locals in dictionary */
PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int);
PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
PyAPI_FUNC(int) PyFrame_ClearFreeList(void);
#endif
typedef
struct
_PyFrameObject
PyFrameObject
;
/* Return the line of code the frame is currently executing. */
PyAPI_FUNC
(
int
)
PyFrame_GetLineNumber
(
PyFrameObject
*
)
PYSTON_NOEXCEPT
;
// Pyston changes: add a function to get globals
PyAPI_FUNC
(
PyObject
*
)
PyFrame_GetGlobals
(
PyFrameObject
*
)
PYSTON_NOEXCEPT
;
// Pyston changes: add a function to get frame object by level
PyAPI_FUNC
(
PyFrameObject
*
)
PyFrame_ForStackLevel
(
int
stack_level
)
PYSTON_NOEXCEPT
;
#ifdef __cplusplus
}
#endif
#endif
/* !Py_FRAMEOBJECT_H */
from_cpython/Include/sysmodule.h
View file @
2526c94e
...
...
@@ -25,6 +25,9 @@ PyAPI_FUNC(void) PySys_ResetWarnOptions(void) PYSTON_NOEXCEPT;
PyAPI_FUNC
(
void
)
PySys_AddWarnOption
(
char
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
PySys_HasWarnOptions
(
void
)
PYSTON_NOEXCEPT
;
// Pyston change: add this API to get sys modules dict
PyAPI_FUNC
(
PyObject
*
)
PySys_GetModulesDict
(
void
)
PYSTON_NOEXCEPT
;
#ifdef __cplusplus
}
#endif
...
...
from_cpython/Python/_warnings.c
0 → 100644
View file @
2526c94e
#include "Python.h"
#include "frameobject.h"
#define MODULE_NAME "_warnings"
PyDoc_STRVAR
(
warnings__doc__
,
MODULE_NAME
" provides basic warning filtering support.
\n
"
"It is a helper module to speed up interpreter start-up."
);
/* Both 'filters' and 'onceregistry' can be set in warnings.py;
get_warnings_attr() will reset these variables accordingly. */
static
PyObject
*
_filters
;
/* List */
static
PyObject
*
_once_registry
;
/* Dict */
static
PyObject
*
_default_action
;
/* String */
static
int
check_matched
(
PyObject
*
obj
,
PyObject
*
arg
)
{
PyObject
*
result
;
int
rc
;
if
(
obj
==
Py_None
)
return
1
;
result
=
PyObject_CallMethod
(
obj
,
"match"
,
"O"
,
arg
);
if
(
result
==
NULL
)
return
-
1
;
rc
=
PyObject_IsTrue
(
result
);
Py_DECREF
(
result
);
return
rc
;
}
/*
Returns a new reference.
A NULL return value can mean false or an error.
*/
static
PyObject
*
get_warnings_attr
(
const
char
*
attr
)
{
static
PyObject
*
warnings_str
=
NULL
;
PyObject
*
all_modules
;
PyObject
*
warnings_module
;
int
result
;
if
(
warnings_str
==
NULL
)
{
warnings_str
=
PyString_InternFromString
(
"warnings"
);
if
(
warnings_str
==
NULL
)
return
NULL
;
}
all_modules
=
PyImport_GetModuleDict
();
result
=
PyDict_Contains
(
all_modules
,
warnings_str
);
if
(
result
==
-
1
||
result
==
0
)
return
NULL
;
warnings_module
=
PyDict_GetItem
(
all_modules
,
warnings_str
);
if
(
!
PyObject_HasAttrString
(
warnings_module
,
attr
))
return
NULL
;
return
PyObject_GetAttrString
(
warnings_module
,
attr
);
}
static
PyObject
*
get_once_registry
(
void
)
{
PyObject
*
registry
;
registry
=
get_warnings_attr
(
"onceregistry"
);
if
(
registry
==
NULL
)
{
if
(
PyErr_Occurred
())
return
NULL
;
return
_once_registry
;
}
Py_DECREF
(
_once_registry
);
_once_registry
=
registry
;
return
registry
;
}
static
PyObject
*
get_default_action
(
void
)
{
PyObject
*
default_action
;
default_action
=
get_warnings_attr
(
"defaultaction"
);
if
(
default_action
==
NULL
)
{
if
(
PyErr_Occurred
())
{
return
NULL
;
}
return
_default_action
;
}
Py_DECREF
(
_default_action
);
_default_action
=
default_action
;
return
default_action
;
}
/* The item is a borrowed reference. */
static
const
char
*
get_filter
(
PyObject
*
category
,
PyObject
*
text
,
Py_ssize_t
lineno
,
PyObject
*
module
,
PyObject
**
item
)
{
PyObject
*
action
;
Py_ssize_t
i
;
PyObject
*
warnings_filters
;
warnings_filters
=
get_warnings_attr
(
"filters"
);
if
(
warnings_filters
==
NULL
)
{
if
(
PyErr_Occurred
())
return
NULL
;
}
else
{
Py_DECREF
(
_filters
);
_filters
=
warnings_filters
;
}
if
(
!
PyList_Check
(
_filters
))
{
PyErr_SetString
(
PyExc_ValueError
,
MODULE_NAME
".filters must be a list"
);
return
NULL
;
}
/* _filters could change while we are iterating over it. */
for
(
i
=
0
;
i
<
PyList_GET_SIZE
(
_filters
);
i
++
)
{
PyObject
*
tmp_item
,
*
action
,
*
msg
,
*
cat
,
*
mod
,
*
ln_obj
;
Py_ssize_t
ln
;
int
is_subclass
,
good_msg
,
good_mod
;
tmp_item
=
*
item
=
PyList_GET_ITEM
(
_filters
,
i
);
if
(
PyTuple_Size
(
tmp_item
)
!=
5
)
{
PyErr_Format
(
PyExc_ValueError
,
MODULE_NAME
".filters item %zd isn't a 5-tuple"
,
i
);
return
NULL
;
}
/* Python code: action, msg, cat, mod, ln = item */
action
=
PyTuple_GET_ITEM
(
tmp_item
,
0
);
msg
=
PyTuple_GET_ITEM
(
tmp_item
,
1
);
cat
=
PyTuple_GET_ITEM
(
tmp_item
,
2
);
mod
=
PyTuple_GET_ITEM
(
tmp_item
,
3
);
ln_obj
=
PyTuple_GET_ITEM
(
tmp_item
,
4
);
good_msg
=
check_matched
(
msg
,
text
);
good_mod
=
check_matched
(
mod
,
module
);
is_subclass
=
PyObject_IsSubclass
(
category
,
cat
);
ln
=
PyInt_AsSsize_t
(
ln_obj
);
if
(
good_msg
==
-
1
||
good_mod
==
-
1
||
is_subclass
==
-
1
||
(
ln
==
-
1
&&
PyErr_Occurred
()))
return
NULL
;
if
(
good_msg
&&
is_subclass
&&
good_mod
&&
(
ln
==
0
||
lineno
==
ln
))
return
PyString_AsString
(
action
);
}
action
=
get_default_action
();
if
(
action
!=
NULL
)
{
return
PyString_AsString
(
action
);
}
PyErr_SetString
(
PyExc_ValueError
,
MODULE_NAME
".defaultaction not found"
);
return
NULL
;
}
static
int
already_warned
(
PyObject
*
registry
,
PyObject
*
key
,
int
should_set
)
{
PyObject
*
already_warned
;
if
(
key
==
NULL
)
return
-
1
;
already_warned
=
PyDict_GetItem
(
registry
,
key
);
if
(
already_warned
!=
NULL
)
{
int
rc
=
PyObject_IsTrue
(
already_warned
);
if
(
rc
!=
0
)
return
rc
;
}
/* This warning wasn't found in the registry, set it. */
if
(
should_set
)
return
PyDict_SetItem
(
registry
,
key
,
Py_True
);
return
0
;
}
/* New reference. */
static
PyObject
*
normalize_module
(
PyObject
*
filename
)
{
PyObject
*
module
;
const
char
*
mod_str
;
Py_ssize_t
len
;
int
rc
=
PyObject_IsTrue
(
filename
);
if
(
rc
==
-
1
)
return
NULL
;
else
if
(
rc
==
0
)
return
PyString_FromString
(
"<unknown>"
);
mod_str
=
PyString_AsString
(
filename
);
if
(
mod_str
==
NULL
)
return
NULL
;
len
=
PyString_Size
(
filename
);
if
(
len
<
0
)
return
NULL
;
if
(
len
>=
3
&&
strncmp
(
mod_str
+
(
len
-
3
),
".py"
,
3
)
==
0
)
{
module
=
PyString_FromStringAndSize
(
mod_str
,
len
-
3
);
}
else
{
module
=
filename
;
Py_INCREF
(
module
);
}
return
module
;
}
static
int
update_registry
(
PyObject
*
registry
,
PyObject
*
text
,
PyObject
*
category
,
int
add_zero
)
{
PyObject
*
altkey
,
*
zero
=
NULL
;
int
rc
;
if
(
add_zero
)
{
zero
=
PyInt_FromLong
(
0
);
if
(
zero
==
NULL
)
return
-
1
;
altkey
=
PyTuple_Pack
(
3
,
text
,
category
,
zero
);
}
else
altkey
=
PyTuple_Pack
(
2
,
text
,
category
);
rc
=
already_warned
(
registry
,
altkey
,
1
);
Py_XDECREF
(
zero
);
Py_XDECREF
(
altkey
);
return
rc
;
}
static
void
show_warning
(
PyObject
*
filename
,
int
lineno
,
PyObject
*
text
,
PyObject
*
category
,
PyObject
*
sourceline
)
{
PyObject
*
f_stderr
;
PyObject
*
name
;
char
lineno_str
[
128
];
PyOS_snprintf
(
lineno_str
,
sizeof
(
lineno_str
),
":%d: "
,
lineno
);
name
=
PyObject_GetAttrString
(
category
,
"__name__"
);
if
(
name
==
NULL
)
/* XXX Can an object lack a '__name__' attribute? */
return
;
f_stderr
=
PySys_GetObject
(
"stderr"
);
if
(
f_stderr
==
NULL
)
{
fprintf
(
stderr
,
"lost sys.stderr
\n
"
);
Py_DECREF
(
name
);
return
;
}
/* Print "filename:lineno: category: text\n" */
PyFile_WriteObject
(
filename
,
f_stderr
,
Py_PRINT_RAW
);
PyFile_WriteString
(
lineno_str
,
f_stderr
);
PyFile_WriteObject
(
name
,
f_stderr
,
Py_PRINT_RAW
);
PyFile_WriteString
(
": "
,
f_stderr
);
PyFile_WriteObject
(
text
,
f_stderr
,
Py_PRINT_RAW
);
PyFile_WriteString
(
"
\n
"
,
f_stderr
);
Py_XDECREF
(
name
);
/* Print " source_line\n" */
if
(
sourceline
)
{
char
*
source_line_str
=
PyString_AS_STRING
(
sourceline
);
while
(
*
source_line_str
==
' '
||
*
source_line_str
==
'\t'
||
*
source_line_str
==
'\014'
)
source_line_str
++
;
PyFile_WriteString
(
source_line_str
,
f_stderr
);
PyFile_WriteString
(
"
\n
"
,
f_stderr
);
}
else
_Py_DisplaySourceLine
(
f_stderr
,
PyString_AS_STRING
(
filename
),
lineno
,
2
);
PyErr_Clear
();
}
static
PyObject
*
warn_explicit
(
PyObject
*
category
,
PyObject
*
message
,
PyObject
*
filename
,
int
lineno
,
PyObject
*
module
,
PyObject
*
registry
,
PyObject
*
sourceline
)
{
PyObject
*
key
=
NULL
,
*
text
=
NULL
,
*
result
=
NULL
,
*
lineno_obj
=
NULL
;
PyObject
*
item
=
Py_None
;
const
char
*
action
;
int
rc
;
if
(
registry
&&
!
PyDict_Check
(
registry
)
&&
(
registry
!=
Py_None
))
{
PyErr_SetString
(
PyExc_TypeError
,
"'registry' must be a dict"
);
return
NULL
;
}
/* Normalize module. */
if
(
module
==
NULL
)
{
module
=
normalize_module
(
filename
);
if
(
module
==
NULL
)
return
NULL
;
}
else
Py_INCREF
(
module
);
/* Normalize message. */
Py_INCREF
(
message
);
/* DECREF'ed in cleanup. */
rc
=
PyObject_IsInstance
(
message
,
PyExc_Warning
);
if
(
rc
==
-
1
)
{
goto
cleanup
;
}
if
(
rc
==
1
)
{
text
=
PyObject_Str
(
message
);
if
(
text
==
NULL
)
goto
cleanup
;
category
=
(
PyObject
*
)
message
->
ob_type
;
}
else
{
text
=
message
;
message
=
PyObject_CallFunction
(
category
,
"O"
,
message
);
if
(
message
==
NULL
)
goto
cleanup
;
}
lineno_obj
=
PyInt_FromLong
(
lineno
);
if
(
lineno_obj
==
NULL
)
goto
cleanup
;
/* Create key. */
key
=
PyTuple_Pack
(
3
,
text
,
category
,
lineno_obj
);
if
(
key
==
NULL
)
goto
cleanup
;
if
((
registry
!=
NULL
)
&&
(
registry
!=
Py_None
))
{
rc
=
already_warned
(
registry
,
key
,
0
);
if
(
rc
==
-
1
)
goto
cleanup
;
else
if
(
rc
==
1
)
goto
return_none
;
/* Else this warning hasn't been generated before. */
}
action
=
get_filter
(
category
,
text
,
lineno
,
module
,
&
item
);
if
(
action
==
NULL
)
goto
cleanup
;
if
(
strcmp
(
action
,
"error"
)
==
0
)
{
PyErr_SetObject
(
category
,
message
);
goto
cleanup
;
}
/* Store in the registry that we've been here, *except* when the action
is "always". */
rc
=
0
;
if
(
strcmp
(
action
,
"always"
)
!=
0
)
{
if
(
registry
!=
NULL
&&
registry
!=
Py_None
&&
PyDict_SetItem
(
registry
,
key
,
Py_True
)
<
0
)
goto
cleanup
;
else
if
(
strcmp
(
action
,
"ignore"
)
==
0
)
goto
return_none
;
else
if
(
strcmp
(
action
,
"once"
)
==
0
)
{
if
(
registry
==
NULL
||
registry
==
Py_None
)
{
registry
=
get_once_registry
();
if
(
registry
==
NULL
)
goto
cleanup
;
}
/* _once_registry[(text, category)] = 1 */
rc
=
update_registry
(
registry
,
text
,
category
,
0
);
}
else
if
(
strcmp
(
action
,
"module"
)
==
0
)
{
/* registry[(text, category, 0)] = 1 */
if
(
registry
!=
NULL
&&
registry
!=
Py_None
)
rc
=
update_registry
(
registry
,
text
,
category
,
0
);
}
else
if
(
strcmp
(
action
,
"default"
)
!=
0
)
{
PyObject
*
to_str
=
PyObject_Str
(
item
);
const
char
*
err_str
=
"???"
;
if
(
to_str
!=
NULL
)
err_str
=
PyString_AS_STRING
(
to_str
);
PyErr_Format
(
PyExc_RuntimeError
,
"Unrecognized action (%s) in warnings.filters:
\n
%s"
,
action
,
err_str
);
Py_XDECREF
(
to_str
);
goto
cleanup
;
}
}
if
(
rc
==
1
)
/* Already warned for this module. */
goto
return_none
;
if
(
rc
==
0
)
{
PyObject
*
show_fxn
=
get_warnings_attr
(
"showwarning"
);
if
(
show_fxn
==
NULL
)
{
if
(
PyErr_Occurred
())
goto
cleanup
;
show_warning
(
filename
,
lineno
,
text
,
category
,
sourceline
);
}
else
{
PyObject
*
res
;
if
(
!
PyMethod_Check
(
show_fxn
)
&&
!
PyFunction_Check
(
show_fxn
))
{
PyErr_SetString
(
PyExc_TypeError
,
"warnings.showwarning() must be set to a "
"function or method"
);
Py_DECREF
(
show_fxn
);
goto
cleanup
;
}
res
=
PyObject_CallFunctionObjArgs
(
show_fxn
,
message
,
category
,
filename
,
lineno_obj
,
NULL
);
Py_DECREF
(
show_fxn
);
Py_XDECREF
(
res
);
if
(
res
==
NULL
)
goto
cleanup
;
}
}
else
/* if (rc == -1) */
goto
cleanup
;
return_none:
result
=
Py_None
;
Py_INCREF
(
result
);
cleanup:
Py_XDECREF
(
key
);
Py_XDECREF
(
text
);
Py_XDECREF
(
lineno_obj
);
Py_DECREF
(
module
);
Py_XDECREF
(
message
);
return
result
;
/* Py_None or NULL. */
}
/* filename, module, and registry are new refs, globals is borrowed */
/* Returns 0 on error (no new refs), 1 on success */
static
int
setup_context
(
Py_ssize_t
stack_level
,
PyObject
**
filename
,
int
*
lineno
,
PyObject
**
module
,
PyObject
**
registry
)
{
PyObject
*
globals
;
/* Setup globals and lineno. */
// Pyston changes: use Pyston's BoxedFrame instead PyFrameObject
// to get globals and lineno.
/* PyFrameObject *f = PyThreadState_GET()->frame; */
/* while (--stack_level > 0 && f != NULL) */
/* f = f->f_back; */
/* */
/* if (f == NULL) { */
/* globals = PyThreadState_Get()->interp->sysdict; */
/* } */
/* else { */
/* globals = f->f_globals; */
/* *lineno = PyFrame_GetLineNumber(f); */
/* } */
PyFrameObject
*
frame
=
PyFrame_ForStackLevel
(
stack_level
-
1
);
if
(
!
frame
)
{
globals
=
PySys_GetModulesDict
();
*
lineno
=
1
;
}
else
{
globals
=
PyFrame_GetGlobals
(
frame
);
*
lineno
=
PyFrame_GetLineNumber
(
frame
);
}
*
module
=
NULL
;
/* Setup registry. */
assert
(
globals
!=
NULL
);
assert
(
PyDict_Check
(
globals
));
*
registry
=
PyDict_GetItemString
(
globals
,
"__warningregistry__"
);
if
(
*
registry
==
NULL
)
{
int
rc
;
*
registry
=
PyDict_New
();
if
(
*
registry
==
NULL
)
return
0
;
rc
=
PyDict_SetItemString
(
globals
,
"__warningregistry__"
,
*
registry
);
if
(
rc
<
0
)
goto
handle_error
;
}
else
Py_INCREF
(
*
registry
);
/* Setup module. */
*
module
=
PyDict_GetItemString
(
globals
,
"__name__"
);
if
(
*
module
==
NULL
)
{
*
module
=
PyString_FromString
(
"<string>"
);
if
(
*
module
==
NULL
)
goto
handle_error
;
}
else
Py_INCREF
(
*
module
);
/* Setup filename. */
*
filename
=
PyDict_GetItemString
(
globals
,
"__file__"
);
if
(
*
filename
!=
NULL
&&
PyString_Check
(
*
filename
))
{
Py_ssize_t
len
=
PyString_Size
(
*
filename
);
const
char
*
file_str
=
PyString_AsString
(
*
filename
);
if
(
file_str
==
NULL
||
(
len
<
0
&&
PyErr_Occurred
()))
goto
handle_error
;
/* if filename.lower().endswith((".pyc", ".pyo")): */
if
(
len
>=
4
&&
file_str
[
len
-
4
]
==
'.'
&&
tolower
(
file_str
[
len
-
3
])
==
'p'
&&
tolower
(
file_str
[
len
-
2
])
==
'y'
&&
(
tolower
(
file_str
[
len
-
1
])
==
'c'
||
tolower
(
file_str
[
len
-
1
])
==
'o'
))
{
*
filename
=
PyString_FromStringAndSize
(
file_str
,
len
-
1
);
if
(
*
filename
==
NULL
)
goto
handle_error
;
}
else
Py_INCREF
(
*
filename
);
}
else
{
const
char
*
module_str
=
PyString_AsString
(
*
module
);
*
filename
=
NULL
;
if
(
module_str
&&
strcmp
(
module_str
,
"__main__"
)
==
0
)
{
PyObject
*
argv
=
PySys_GetObject
(
"argv"
);
if
(
argv
!=
NULL
&&
PyList_Size
(
argv
)
>
0
)
{
int
is_true
;
*
filename
=
PyList_GetItem
(
argv
,
0
);
Py_INCREF
(
*
filename
);
/* If sys.argv[0] is false, then use '__main__'. */
is_true
=
PyObject_IsTrue
(
*
filename
);
if
(
is_true
<
0
)
{
Py_DECREF
(
*
filename
);
goto
handle_error
;
}
else
if
(
!
is_true
)
{
Py_DECREF
(
*
filename
);
*
filename
=
PyString_FromString
(
"__main__"
);
if
(
*
filename
==
NULL
)
goto
handle_error
;
}
}
else
{
/* embedded interpreters don't have sys.argv, see bug #839151 */
*
filename
=
PyString_FromString
(
"__main__"
);
if
(
*
filename
==
NULL
)
goto
handle_error
;
}
}
if
(
*
filename
==
NULL
)
{
*
filename
=
*
module
;
Py_INCREF
(
*
filename
);
}
}
return
1
;
handle_error:
/* filename not XDECREF'ed here as there is no way to jump here with a
dangling reference. */
Py_XDECREF
(
*
registry
);
Py_XDECREF
(
*
module
);
return
0
;
}
static
PyObject
*
get_category
(
PyObject
*
message
,
PyObject
*
category
)
{
int
rc
;
/* Get category. */
rc
=
PyObject_IsInstance
(
message
,
PyExc_Warning
);
if
(
rc
==
-
1
)
return
NULL
;
if
(
rc
==
1
)
category
=
(
PyObject
*
)
message
->
ob_type
;
else
if
(
category
==
NULL
)
category
=
PyExc_UserWarning
;
/* Validate category. */
rc
=
PyObject_IsSubclass
(
category
,
PyExc_Warning
);
if
(
rc
==
-
1
)
return
NULL
;
if
(
rc
==
0
)
{
PyErr_SetString
(
PyExc_ValueError
,
"category is not a subclass of Warning"
);
return
NULL
;
}
return
category
;
}
static
PyObject
*
do_warn
(
PyObject
*
message
,
PyObject
*
category
,
Py_ssize_t
stack_level
)
{
PyObject
*
filename
,
*
module
,
*
registry
,
*
res
;
int
lineno
;
if
(
!
setup_context
(
stack_level
,
&
filename
,
&
lineno
,
&
module
,
&
registry
))
return
NULL
;
res
=
warn_explicit
(
category
,
message
,
filename
,
lineno
,
module
,
registry
,
NULL
);
Py_DECREF
(
filename
);
Py_DECREF
(
registry
);
Py_DECREF
(
module
);
return
res
;
}
static
PyObject
*
warnings_warn
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kwds
)
{
static
char
*
kw_list
[]
=
{
"message"
,
"category"
,
"stacklevel"
,
0
};
PyObject
*
message
,
*
category
=
NULL
;
Py_ssize_t
stack_level
=
1
;
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwds
,
"O|On:warn"
,
kw_list
,
&
message
,
&
category
,
&
stack_level
))
return
NULL
;
category
=
get_category
(
message
,
category
);
if
(
category
==
NULL
)
return
NULL
;
return
do_warn
(
message
,
category
,
stack_level
);
}
static
PyObject
*
warnings_warn_explicit
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kwds
)
{
static
char
*
kwd_list
[]
=
{
"message"
,
"category"
,
"filename"
,
"lineno"
,
"module"
,
"registry"
,
"module_globals"
,
0
};
PyObject
*
message
;
PyObject
*
category
;
PyObject
*
filename
;
int
lineno
;
PyObject
*
module
=
NULL
;
PyObject
*
registry
=
NULL
;
PyObject
*
module_globals
=
NULL
;
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwds
,
"OOOi|OOO:warn_explicit"
,
kwd_list
,
&
message
,
&
category
,
&
filename
,
&
lineno
,
&
module
,
&
registry
,
&
module_globals
))
return
NULL
;
if
(
module_globals
)
{
static
PyObject
*
get_source_name
=
NULL
;
static
PyObject
*
splitlines_name
=
NULL
;
PyObject
*
loader
;
PyObject
*
module_name
;
PyObject
*
source
;
PyObject
*
source_list
;
PyObject
*
source_line
;
PyObject
*
returned
;
if
(
get_source_name
==
NULL
)
{
get_source_name
=
PyString_InternFromString
(
"get_source"
);
if
(
!
get_source_name
)
return
NULL
;
}
if
(
splitlines_name
==
NULL
)
{
splitlines_name
=
PyString_InternFromString
(
"splitlines"
);
if
(
!
splitlines_name
)
return
NULL
;
}
/* Check/get the requisite pieces needed for the loader. */
loader
=
PyDict_GetItemString
(
module_globals
,
"__loader__"
);
module_name
=
PyDict_GetItemString
(
module_globals
,
"__name__"
);
if
(
loader
==
NULL
||
module_name
==
NULL
)
goto
standard_call
;
/* Make sure the loader implements the optional get_source() method. */
if
(
!
PyObject_HasAttrString
(
loader
,
"get_source"
))
goto
standard_call
;
/* Call get_source() to get the source code. */
source
=
PyObject_CallMethodObjArgs
(
loader
,
get_source_name
,
module_name
,
NULL
);
if
(
!
source
)
return
NULL
;
else
if
(
source
==
Py_None
)
{
Py_DECREF
(
Py_None
);
goto
standard_call
;
}
/* Split the source into lines. */
source_list
=
PyObject_CallMethodObjArgs
(
source
,
splitlines_name
,
NULL
);
Py_DECREF
(
source
);
if
(
!
source_list
)
return
NULL
;
/* Get the source line. */
source_line
=
PyList_GetItem
(
source_list
,
lineno
-
1
);
if
(
!
source_line
)
{
Py_DECREF
(
source_list
);
return
NULL
;
}
/* Handle the warning. */
returned
=
warn_explicit
(
category
,
message
,
filename
,
lineno
,
module
,
registry
,
source_line
);
Py_DECREF
(
source_list
);
return
returned
;
}
standard_call:
return
warn_explicit
(
category
,
message
,
filename
,
lineno
,
module
,
registry
,
NULL
);
}
/* Function to issue a warning message; may raise an exception. */
int
PyErr_WarnEx
(
PyObject
*
category
,
const
char
*
text
,
Py_ssize_t
stack_level
)
{
PyObject
*
res
;
PyObject
*
message
=
PyString_FromString
(
text
);
if
(
message
==
NULL
)
return
-
1
;
if
(
category
==
NULL
)
category
=
PyExc_RuntimeWarning
;
res
=
do_warn
(
message
,
category
,
stack_level
);
Py_DECREF
(
message
);
if
(
res
==
NULL
)
return
-
1
;
Py_DECREF
(
res
);
return
0
;
}
/* PyErr_Warn is only for backwards compatibility and will be removed.
Use PyErr_WarnEx instead. */
#undef PyErr_Warn
PyAPI_FUNC
(
int
)
PyErr_Warn
(
PyObject
*
category
,
char
*
text
)
{
return
PyErr_WarnEx
(
category
,
text
,
1
);
}
/* Warning with explicit origin */
int
PyErr_WarnExplicit
(
PyObject
*
category
,
const
char
*
text
,
const
char
*
filename_str
,
int
lineno
,
const
char
*
module_str
,
PyObject
*
registry
)
{
PyObject
*
res
;
PyObject
*
message
=
PyString_FromString
(
text
);
PyObject
*
filename
=
PyString_FromString
(
filename_str
);
PyObject
*
module
=
NULL
;
int
ret
=
-
1
;
if
(
message
==
NULL
||
filename
==
NULL
)
goto
exit
;
if
(
module_str
!=
NULL
)
{
module
=
PyString_FromString
(
module_str
);
if
(
module
==
NULL
)
goto
exit
;
}
if
(
category
==
NULL
)
category
=
PyExc_RuntimeWarning
;
res
=
warn_explicit
(
category
,
message
,
filename
,
lineno
,
module
,
registry
,
NULL
);
if
(
res
==
NULL
)
goto
exit
;
Py_DECREF
(
res
);
ret
=
0
;
exit:
Py_XDECREF
(
message
);
Py_XDECREF
(
module
);
Py_XDECREF
(
filename
);
return
ret
;
}
PyDoc_STRVAR
(
warn_doc
,
"Issue a warning, or maybe ignore it or raise an exception."
);
PyDoc_STRVAR
(
warn_explicit_doc
,
"Low-level inferface to warnings functionality."
);
static
PyMethodDef
warnings_functions
[]
=
{
{
"warn"
,
(
PyCFunction
)
warnings_warn
,
METH_VARARGS
|
METH_KEYWORDS
,
warn_doc
},
{
"warn_explicit"
,
(
PyCFunction
)
warnings_warn_explicit
,
METH_VARARGS
|
METH_KEYWORDS
,
warn_explicit_doc
},
/* XXX(brett.cannon): add showwarning? */
/* XXX(brett.cannon): Reasonable to add formatwarning? */
{
NULL
,
NULL
}
/* sentinel */
};
static
PyObject
*
create_filter
(
PyObject
*
category
,
const
char
*
action
)
{
static
PyObject
*
ignore_str
=
NULL
;
static
PyObject
*
error_str
=
NULL
;
static
PyObject
*
default_str
=
NULL
;
PyObject
*
action_obj
=
NULL
;
PyObject
*
lineno
,
*
result
;
if
(
!
strcmp
(
action
,
"ignore"
))
{
if
(
ignore_str
==
NULL
)
{
ignore_str
=
PyString_InternFromString
(
"ignore"
);
if
(
ignore_str
==
NULL
)
return
NULL
;
}
action_obj
=
ignore_str
;
}
else
if
(
!
strcmp
(
action
,
"error"
))
{
if
(
error_str
==
NULL
)
{
error_str
=
PyString_InternFromString
(
"error"
);
if
(
error_str
==
NULL
)
return
NULL
;
}
action_obj
=
error_str
;
}
else
if
(
!
strcmp
(
action
,
"default"
))
{
if
(
default_str
==
NULL
)
{
default_str
=
PyString_InternFromString
(
"default"
);
if
(
default_str
==
NULL
)
return
NULL
;
}
action_obj
=
default_str
;
}
else
{
Py_FatalError
(
"unknown action"
);
}
/* This assumes the line number is zero for now. */
lineno
=
PyInt_FromLong
(
0
);
if
(
lineno
==
NULL
)
return
NULL
;
result
=
PyTuple_Pack
(
5
,
action_obj
,
Py_None
,
category
,
Py_None
,
lineno
);
Py_DECREF
(
lineno
);
return
result
;
}
static
PyObject
*
init_filters
(
void
)
{
/* Don't silence DeprecationWarning if -3 or -Q were used. */
PyObject
*
filters
=
PyList_New
(
Py_Py3kWarningFlag
||
Py_DivisionWarningFlag
?
3
:
4
);
unsigned
int
pos
=
0
;
/* Post-incremented in each use. */
unsigned
int
x
;
const
char
*
bytes_action
;
if
(
filters
==
NULL
)
return
NULL
;
/* If guard changes, make sure to update 'filters' initialization above. */
if
(
!
Py_Py3kWarningFlag
&&
!
Py_DivisionWarningFlag
)
{
PyList_SET_ITEM
(
filters
,
pos
++
,
create_filter
(
PyExc_DeprecationWarning
,
"ignore"
));
}
PyList_SET_ITEM
(
filters
,
pos
++
,
create_filter
(
PyExc_PendingDeprecationWarning
,
"ignore"
));
PyList_SET_ITEM
(
filters
,
pos
++
,
create_filter
(
PyExc_ImportWarning
,
"ignore"
));
if
(
Py_BytesWarningFlag
>
1
)
bytes_action
=
"error"
;
else
if
(
Py_BytesWarningFlag
)
bytes_action
=
"default"
;
else
bytes_action
=
"ignore"
;
PyList_SET_ITEM
(
filters
,
pos
++
,
create_filter
(
PyExc_BytesWarning
,
bytes_action
));
for
(
x
=
0
;
x
<
pos
;
x
+=
1
)
{
if
(
PyList_GET_ITEM
(
filters
,
x
)
==
NULL
)
{
Py_DECREF
(
filters
);
return
NULL
;
}
}
return
filters
;
}
PyMODINIT_FUNC
_PyWarnings_Init
(
void
)
{
PyObject
*
m
;
m
=
Py_InitModule3
(
MODULE_NAME
,
warnings_functions
,
warnings__doc__
);
if
(
m
==
NULL
)
return
;
_filters
=
init_filters
();
if
(
_filters
==
NULL
)
return
;
// Pyston change: let the GC scan the filters
PyGC_AddPotentialRoot
(
&
_filters
,
sizeof
(
_filters
));
Py_INCREF
(
_filters
);
if
(
PyModule_AddObject
(
m
,
"filters"
,
_filters
)
<
0
)
return
;
_once_registry
=
PyDict_New
();
if
(
_once_registry
==
NULL
)
return
;
// Pyston change: let the GC scan the registry
PyGC_AddPotentialRoot
(
&
_once_registry
,
sizeof
(
_once_registry
));
Py_INCREF
(
_once_registry
);
if
(
PyModule_AddObject
(
m
,
"once_registry"
,
_once_registry
)
<
0
)
return
;
_default_action
=
PyString_FromString
(
"default"
);
if
(
_default_action
==
NULL
)
return
;
// Pyston change: let the GC scan the action
PyGC_AddPotentialRoot
(
&
_default_action
,
sizeof
(
_default_action
));
Py_INCREF
(
_default_action
);
if
(
PyModule_AddObject
(
m
,
"default_action"
,
_default_action
)
<
0
)
return
;
}
src/runtime/builtin_modules/sys.cpp
View file @
2526c94e
...
...
@@ -41,6 +41,7 @@ BoxedDict* sys_modules_dict;
extern
"C"
{
// supposed to be exposed through sys.flags
int
Py_BytesWarningFlag
=
0
;
int
Py_DivisionWarningFlag
=
0
;
int
Py_HashRandomizationFlag
=
0
;
}
...
...
@@ -400,6 +401,10 @@ extern "C" const char* Py_GetPlatform() noexcept {
#endif
}
extern
"C"
PyObject
*
PySys_GetModulesDict
()
noexcept
{
return
getSysModulesDict
();
}
static
PyObject
*
sys_excepthook
(
PyObject
*
self
,
PyObject
*
args
)
noexcept
{
PyObject
*
exc
,
*
value
,
*
tb
;
if
(
!
PyArg_UnpackTuple
(
args
,
"excepthook"
,
3
,
3
,
&
exc
,
&
value
,
&
tb
))
...
...
src/runtime/capi.cpp
View file @
2526c94e
...
...
@@ -585,8 +585,11 @@ extern "C" int PyObject_IsTrue(PyObject* o) noexcept {
extern
"C"
int
PyObject_Not
(
PyObject
*
o
)
noexcept
{
fatalOrError
(
PyExc_NotImplementedError
,
"unimplemented"
);
return
-
1
;
int
res
;
res
=
PyObject_IsTrue
(
o
);
if
(
res
<
0
)
return
res
;
return
res
==
0
;
}
extern
"C"
PyObject
*
PyObject_Call
(
PyObject
*
callable_object
,
PyObject
*
args
,
PyObject
*
kw
)
noexcept
{
...
...
@@ -1034,16 +1037,6 @@ extern "C" PyObject* PyErr_Occurred() noexcept {
return
cur_thread_state
.
curexc_type
;
}
extern
"C"
int
PyErr_WarnEx
(
PyObject
*
category
,
const
char
*
text
,
Py_ssize_t
stacklevel
)
noexcept
{
// These warnings are silenced by default:
// We should copy the real CPython code in here
if
(
category
==
PyExc_DeprecationWarning
)
return
0
;
fatalOrError
(
PyExc_NotImplementedError
,
"unimplemented"
);
return
-
1
;
}
extern
"C"
void
*
PyObject_Malloc
(
size_t
sz
)
noexcept
{
return
gc_compat_malloc
(
sz
);
}
...
...
@@ -1924,13 +1917,6 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
return
rtn
;
}
/* Warning with explicit origin */
extern
"C"
int
PyErr_WarnExplicit
(
PyObject
*
category
,
const
char
*
text
,
const
char
*
filename_str
,
int
lineno
,
const
char
*
module_str
,
PyObject
*
registry
)
noexcept
{
Py_FatalError
(
"unimplemented"
);
}
/* extension modules might be compiled with GC support so these
functions must always be available */
...
...
src/runtime/frame.cpp
View file @
2526c94e
...
...
@@ -149,6 +149,22 @@ Box* getFrame(int depth) {
return
BoxedFrame
::
boxFrame
(
std
::
move
(
it
));
}
extern
"C"
int
PyFrame_GetLineNumber
(
PyFrameObject
*
f
)
noexcept
{
BoxedInt
*
lineno
=
(
BoxedInt
*
)
BoxedFrame
::
lineno
((
Box
*
)
f
,
NULL
);
return
lineno
->
n
;
}
extern
"C"
PyObject
*
PyFrame_GetGlobals
(
PyFrameObject
*
f
)
noexcept
{
Box
*
globals
=
BoxedFrame
::
globals
((
Box
*
)
f
,
NULL
);
if
(
globals
->
cls
==
attrwrapper_cls
)
return
attrwrapperToDict
(
globals
);
return
globals
;
}
extern
"C"
PyFrameObject
*
PyFrame_ForStackLevel
(
int
stack_level
)
noexcept
{
return
(
PyFrameObject
*
)
getFrame
(
stack_level
);
}
void
setupFrame
()
{
frame_cls
=
BoxedClass
::
create
(
type_cls
,
object_cls
,
&
BoxedFrame
::
gchandler
,
0
,
0
,
sizeof
(
BoxedFrame
),
false
,
"frame"
);
...
...
src/runtime/traceback.cpp
View file @
2526c94e
...
...
@@ -126,6 +126,10 @@ static Box* traceback_tb_next(Box* self, void*) {
return
traceback
->
tb_next
;
}
extern
"C"
int
_Py_DisplaySourceLine
(
PyObject
*
f
,
const
char
*
filename
,
int
lineno
,
int
indent
)
noexcept
{
RELEASE_ASSERT
(
0
,
"Not implemented."
);
}
void
setupTraceback
()
{
traceback_cls
=
BoxedClass
::
create
(
type_cls
,
object_cls
,
BoxedTraceback
::
gcHandler
,
0
,
0
,
sizeof
(
BoxedTraceback
),
false
,
"traceback"
);
...
...
src/runtime/types.cpp
View file @
2526c94e
...
...
@@ -77,6 +77,7 @@ extern "C" void initzlib();
extern
"C"
void
init_codecs
();
extern
"C"
void
init_socket
();
extern
"C"
void
_PyUnicode_Init
();
extern
"C"
void
_PyWarnings_Init
()
noexcept
;
extern
"C"
void
_string_init
();
extern
"C"
void
initunicodedata
();
extern
"C"
void
init_weakref
();
...
...
@@ -3937,6 +3938,7 @@ void setupRuntime() {
setupClassobj
();
setupSuper
();
_PyUnicode_Init
();
_PyWarnings_Init
();
_string_init
();
setupDescr
();
setupTraceback
();
...
...
test/tests/warnings_test.py
View file @
2526c94e
import
warnings
import
_warnings
# Specifying this as a DeprecationWarning is a hacky way of supressing the warning,
# since we don't output the exact same error message as CPython right now:
warnings
.
warn
(
"hello world"
,
DeprecationWarning
)
warnings
.
filterwarnings
(
'error'
)
try
:
warnings
.
warn
(
"hello world"
,
Warning
)
except
Warning
as
w
:
print
(
w
.
args
[
0
])
try
:
_warnings
.
warn
(
"deperecated"
,
Warning
)
except
Warning
as
w
:
print
(
w
.
args
[
0
])
Boxiang Sun
@Daetalus
mentioned in commit
87637579
·
Sep 08, 2016
mentioned in commit
87637579
mentioned in commit 876375792f99ce224bcea32dd36b4fdce1e0f6c6
Toggle commit list
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment