Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
39eab8de
Commit
39eab8de
authored
Jan 14, 2014
by
Damien George
Browse files
Merge pull request #161 from pfalcon/exc-more-pythonic
Move towards Python-compliant interface of exceptions
parents
66a5bf68
ddf2178d
Changes
2
Hide whitespace changes
Inline
Side-by-side
py/objexcept.c
View file @
39eab8de
...
...
@@ -8,105 +8,86 @@
#include
"misc.h"
#include
"mpconfig.h"
#include
"obj.h"
#include
"objtuple.h"
// This is unified class for C-level and Python-level exceptions
// Python-level exception have empty ->msg and all arguments are in
// args tuple. C-level excepttion likely have ->msg, and may as well
// have args tuple (or otherwise have it as NULL).
typedef
struct
mp_obj_exception_t
{
mp_obj_base_t
base
;
qstr
id
;
int
n_args
;
const
void
*
args
[]
;
qstr
msg
;
mp_obj_tuple_t
args
;
}
mp_obj_exception_t
;
void
exception_print
(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
o_in
)
{
mp_obj_exception_t
*
o
=
o_in
;
switch
(
o
->
n_args
)
{
case
0
:
print
(
env
,
"%s"
,
qstr_str
(
o
->
id
));
break
;
case
1
:
print
(
env
,
"%s: %s"
,
qstr_str
(
o
->
id
),
(
const
char
*
)
o
->
args
[
0
]);
break
;
case
2
:
print
(
env
,
"%s: "
,
qstr_str
(
o
->
id
));
print
(
env
,
(
const
char
*
)
o
->
args
[
0
],
o
->
args
[
1
]);
break
;
default:
// here we just assume at least 3 args, but only use first 3
print
(
env
,
"%s: "
,
qstr_str
(
o
->
id
));
print
(
env
,
(
const
char
*
)
o
->
args
[
0
],
o
->
args
[
1
],
o
->
args
[
2
]);
break
;
if
(
o
->
msg
!=
0
)
{
print
(
env
,
"%s: %s"
,
qstr_str
(
o
->
id
),
qstr_str
(
o
->
msg
));
}
else
{
print
(
env
,
"%s"
,
qstr_str
(
o
->
id
));
tuple_print
(
print
,
env
,
&
o
->
args
);
}
}
// args in reversed order
static
mp_obj_t
exception_call
(
mp_obj_t
self_in
,
int
n_args
,
const
mp_obj_t
*
args
)
{
mp_obj_exception_t
*
base
=
self_in
;
mp_obj_exception_t
*
o
=
m_new_obj_var
(
mp_obj_exception_t
,
mp_obj_t
*
,
n_args
);
o
->
base
.
type
=
&
exception_type
;
o
->
id
=
base
->
id
;
o
->
msg
=
0
;
o
->
args
.
len
=
n_args
;
// TODO: factor out as reusable copy_reversed()
int
j
=
0
;
for
(
int
i
=
n_args
-
1
;
i
>=
0
;
i
--
)
{
o
->
args
.
items
[
i
]
=
args
[
j
++
];
}
return
o
;
}
const
mp_obj_type_t
exception_type
=
{
{
&
mp_const_type
},
"exception"
,
.
print
=
exception_print
,
.
call_n
=
exception_call
,
};
mp_obj_t
mp_obj_new_exception
(
qstr
id
)
{
mp_obj_exception_t
*
o
=
m_new_obj
(
mp_obj_exception_t
);
o
->
base
.
type
=
&
exception_type
;
o
->
id
=
id
;
o
->
n_args
=
0
;
return
o
;
return
mp_obj_new_exception_msg_varg
(
id
,
NULL
);
}
mp_obj_t
mp_obj_new_exception_msg
(
qstr
id
,
const
char
*
msg
)
{
mp_obj_exception_t
*
o
=
m_new_obj_var
(
mp_obj_exception_t
,
void
*
,
1
);
o
->
base
.
type
=
&
exception_type
;
o
->
id
=
id
;
o
->
n_args
=
1
;
o
->
args
[
0
]
=
msg
;
return
o
;
return
mp_obj_new_exception_msg_varg
(
id
,
msg
);
}
mp_obj_t
mp_obj_new_exception_msg_1_arg
(
qstr
id
,
const
char
*
fmt
,
const
char
*
a1
)
{
mp_obj_exception_t
*
o
=
m_new_obj_var
(
mp_obj_exception_t
,
void
*
,
2
);
o
->
base
.
type
=
&
exception_type
;
o
->
id
=
id
;
o
->
n_args
=
2
;
o
->
args
[
0
]
=
fmt
;
o
->
args
[
1
]
=
a1
;
return
o
;
return
mp_obj_new_exception_msg_varg
(
id
,
fmt
,
a1
);
}
mp_obj_t
mp_obj_new_exception_msg_2_args
(
qstr
id
,
const
char
*
fmt
,
const
char
*
a1
,
const
char
*
a2
)
{
mp_obj_exception_t
*
o
=
m_new_obj_var
(
mp_obj_exception_t
,
void
*
,
3
);
o
->
base
.
type
=
&
exception_type
;
o
->
id
=
id
;
o
->
n_args
=
3
;
o
->
args
[
0
]
=
fmt
;
o
->
args
[
1
]
=
a1
;
o
->
args
[
2
]
=
a2
;
return
o
;
return
mp_obj_new_exception_msg_varg
(
id
,
fmt
,
a1
,
a2
);
}
mp_obj_t
mp_obj_new_exception_msg_varg
(
qstr
id
,
const
char
*
fmt
,
...)
{
// count number of arguments by number of % signs, excluding %%
int
n_args
=
1
;
// count fmt
for
(
const
char
*
s
=
fmt
;
*
s
;
s
++
)
{
if
(
*
s
==
'%'
)
{
if
(
s
[
1
]
==
'%'
)
{
s
+=
1
;
}
else
{
n_args
+=
1
;
}
}
}
// make exception object
mp_obj_exception_t
*
o
=
m_new_obj_var
(
mp_obj_exception_t
,
void
*
,
n_args
);
mp_obj_exception_t
*
o
=
m_new_obj_var
(
mp_obj_exception_t
,
mp_obj_t
*
,
0
);
o
->
base
.
type
=
&
exception_type
;
o
->
id
=
id
;
o
->
n_args
=
n_args
;
o
->
args
[
0
]
=
fmt
;
// extract args and store them
va_list
ap
;
va_start
(
ap
,
fmt
);
for
(
int
i
=
1
;
i
<
n_args
;
i
++
)
{
o
->
args
[
i
]
=
va_arg
(
ap
,
void
*
);
o
->
args
.
len
=
0
;
if
(
fmt
==
NULL
)
{
o
->
msg
=
0
;
}
else
{
// render exception message
vstr_t
*
vstr
=
vstr_new
();
va_list
ap
;
va_start
(
ap
,
fmt
);
vstr_vprintf
(
vstr
,
fmt
,
ap
);
va_end
(
ap
);
o
->
msg
=
qstr_from_str_take
(
vstr
->
buf
,
vstr
->
alloc
);
}
va_end
(
ap
);
return
o
;
}
...
...
tests/basics/tests/exception1.py
0 → 100644
View file @
39eab8de
# TODO: requires repr()
#a = IndexError(1, "test", [100, 200])
#print(repr(a))
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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