mirror of
https://github.com/boostorg/python.git
synced 2026-02-02 21:12:15 +00:00
further simplifications of error reporting code
[SVN r8315]
This commit is contained in:
@@ -35,6 +35,20 @@ string argument_tuple_as_string(tuple arguments)
|
||||
return result;
|
||||
}
|
||||
|
||||
string description_as_string(tuple description)
|
||||
{
|
||||
string result("(");
|
||||
for (std::size_t i = 0; i < description.size(); ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
result += ", ";
|
||||
result += string(description[i]);
|
||||
}
|
||||
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
|
||||
struct function::type_object :
|
||||
singleton<function::type_object, getattrable<callable<python::detail::type_object<function> > > >
|
||||
{
|
||||
@@ -85,7 +99,7 @@ PyObject* function::getattr(const char * name) const
|
||||
list signatures;
|
||||
for (const function* f = this; f != 0; f = f->m_overloads.get())
|
||||
{
|
||||
signatures.push_back(f->description());
|
||||
signatures.push_back(ref(f->description()));
|
||||
}
|
||||
return signatures.reference().release();
|
||||
|
||||
@@ -136,10 +150,11 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
|
||||
message += "' ";
|
||||
}
|
||||
message += "expected argument(s) ";
|
||||
message += description_as_string();
|
||||
tuple desc(this->description());
|
||||
message += description_as_string(desc);
|
||||
message += ",\nbut got ";
|
||||
tuple arguments(ref(args, ref::increment_count));
|
||||
message += argument_types_as_string(arguments);
|
||||
message += argument_tuple_as_string(arguments);
|
||||
message += " instead.";
|
||||
PyErr_SetObject(PyExc_TypeError, message.get());
|
||||
}
|
||||
@@ -162,40 +177,21 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
|
||||
message += " matches argument(s):\n";
|
||||
|
||||
tuple arguments(ref(args, ref::increment_count));
|
||||
message += argument_types_as_string(arguments);
|
||||
message += argument_tuple_as_string(arguments);
|
||||
|
||||
message += "\nCandidates are:\n";
|
||||
for (const function* f1 = this; f1 != 0; f1 = f1->m_overloads.get())
|
||||
{
|
||||
if (f1 != this)
|
||||
message += "\n";
|
||||
message += f1->description_as_string();
|
||||
tuple desc(f1->description());
|
||||
message += description_as_string(desc);
|
||||
}
|
||||
|
||||
PyErr_SetObject(PyExc_TypeError, message.get());
|
||||
return 0;
|
||||
}
|
||||
|
||||
string function::description_as_string() const
|
||||
{
|
||||
string result("(");
|
||||
tuple arguments(ref(this->description()));
|
||||
for (std::size_t i = 0; i < arguments.size(); ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
result += ", ";
|
||||
result += string(arguments[i]);
|
||||
}
|
||||
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
|
||||
string function::argument_types_as_string(tuple arguments) const
|
||||
{
|
||||
return argument_tuple_as_string(arguments);
|
||||
}
|
||||
|
||||
bound_function* bound_function::create(const ref& target, const ref& fn)
|
||||
{
|
||||
bound_function* const result = free_list;
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace python { namespace detail {
|
||||
class extension_instance;
|
||||
|
||||
string argument_tuple_as_string(tuple args);
|
||||
string description_as_string(tuple description);
|
||||
|
||||
|
||||
// function --
|
||||
@@ -47,8 +48,6 @@ class function : public python_object
|
||||
virtual PyObject* description() const = 0;
|
||||
private:
|
||||
virtual PyObject* do_call(PyObject* args, PyObject* keywords) const = 0;
|
||||
virtual string description_as_string() const;
|
||||
virtual string argument_types_as_string(tuple args) const;
|
||||
virtual string function_name() const = 0;
|
||||
virtual bool rephrase_argument_error() const
|
||||
{ return true; }
|
||||
|
||||
@@ -130,8 +130,6 @@ private: // override function hook
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
private:
|
||||
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* tail_args, PyObject* keywords) const = 0;
|
||||
string description_as_string() const;
|
||||
string argument_types_as_string(tuple args) const;
|
||||
};
|
||||
""" + gen_functions("""
|
||||
|
||||
@@ -150,8 +148,7 @@ struct init%x : init
|
||||
|
||||
PyObject* description() const
|
||||
{
|
||||
return function_signature(get_python_type_name(python::type<T>())%(,
|
||||
get_python_type_name(python::type<A%n>())%));
|
||||
return function_signature((void (*)(%(A%n%:, %)))0);
|
||||
}
|
||||
|
||||
string function_name() const
|
||||
|
||||
@@ -33,24 +33,4 @@ namespace python { namespace detail {
|
||||
return none();
|
||||
}
|
||||
|
||||
string init::description_as_string() const
|
||||
{
|
||||
tuple arguments(ref(this->description()));
|
||||
string result("(");
|
||||
for (std::size_t i = 1; i < arguments.size(); ++i)
|
||||
{
|
||||
if (i != 1)
|
||||
result += ", ";
|
||||
result += string(arguments[i]);
|
||||
}
|
||||
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
|
||||
string init::argument_types_as_string(tuple arguments) const
|
||||
{
|
||||
return argument_tuple_as_string(arguments.slice(1,arguments.size()));
|
||||
}
|
||||
|
||||
}} // namespace python::detail
|
||||
|
||||
@@ -165,8 +165,6 @@ private: // override function hook
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
private:
|
||||
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* tail_args, PyObject* keywords) const = 0;
|
||||
string description_as_string() const;
|
||||
string argument_types_as_string(tuple args) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -183,7 +181,7 @@ struct init0 : init
|
||||
|
||||
PyObject* description() const
|
||||
{
|
||||
return function_signature(get_python_type_name(python::type<T>()));
|
||||
return function_signature((void (*)())0);
|
||||
}
|
||||
|
||||
string function_name() const
|
||||
@@ -209,8 +207,7 @@ struct init1 : init
|
||||
|
||||
PyObject* description() const
|
||||
{
|
||||
return function_signature(get_python_type_name(python::type<T>()),
|
||||
get_python_type_name(python::type<A1>()));
|
||||
return function_signature((void (*)(A1))0);
|
||||
}
|
||||
|
||||
string function_name() const
|
||||
@@ -238,9 +235,7 @@ struct init2 : init
|
||||
|
||||
PyObject* description() const
|
||||
{
|
||||
return function_signature(get_python_type_name(python::type<T>()),
|
||||
get_python_type_name(python::type<A1>()),
|
||||
get_python_type_name(python::type<A2>()));
|
||||
return function_signature((void (*)(A1, A2))0);
|
||||
}
|
||||
|
||||
string function_name() const
|
||||
@@ -270,10 +265,7 @@ struct init3 : init
|
||||
|
||||
PyObject* description() const
|
||||
{
|
||||
return function_signature(get_python_type_name(python::type<T>()),
|
||||
get_python_type_name(python::type<A1>()),
|
||||
get_python_type_name(python::type<A2>()),
|
||||
get_python_type_name(python::type<A3>()));
|
||||
return function_signature((void (*)(A1, A2, A3))0);
|
||||
}
|
||||
|
||||
string function_name() const
|
||||
@@ -305,11 +297,7 @@ struct init4 : init
|
||||
|
||||
PyObject* description() const
|
||||
{
|
||||
return function_signature(get_python_type_name(python::type<T>()),
|
||||
get_python_type_name(python::type<A1>()),
|
||||
get_python_type_name(python::type<A2>()),
|
||||
get_python_type_name(python::type<A3>()),
|
||||
get_python_type_name(python::type<A4>()));
|
||||
return function_signature((void (*)(A1, A2, A3, A4))0);
|
||||
}
|
||||
|
||||
string function_name() const
|
||||
@@ -343,12 +331,7 @@ struct init5 : init
|
||||
|
||||
PyObject* description() const
|
||||
{
|
||||
return function_signature(get_python_type_name(python::type<T>()),
|
||||
get_python_type_name(python::type<A1>()),
|
||||
get_python_type_name(python::type<A2>()),
|
||||
get_python_type_name(python::type<A3>()),
|
||||
get_python_type_name(python::type<A4>()),
|
||||
get_python_type_name(python::type<A5>()));
|
||||
return function_signature((void (*)(A1, A2, A3, A4, A5))0);
|
||||
}
|
||||
|
||||
string function_name() const
|
||||
|
||||
169
test_extclass.py
169
test_extclass.py
@@ -12,18 +12,16 @@ a single long parameter.
|
||||
|
||||
>>> try: ext = Foo()
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "'demo.Foo.__init__' expected argument\(s\) \(int\),\n"
|
||||
... "but got \(\) instead.", str(err))
|
||||
... print str(err)
|
||||
... else: print 'no exception'
|
||||
|
||||
'demo.Foo.__init__' expected argument(s) (int),
|
||||
but got (demo.Foo) instead.
|
||||
>>> try: ext = Foo('foo')
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "'demo.Foo.__init__' expected argument\(s\) \(int\),\n"
|
||||
... "but got \(string\) instead.", str(err))
|
||||
... print str(err)
|
||||
... else: print 'no exception'
|
||||
|
||||
'demo.Foo.__init__' expected argument(s) (int),
|
||||
but got (demo.Foo, string) instead.
|
||||
>>> ext = Foo(1)
|
||||
|
||||
Call a virtual function. This call takes a trip into C++ where
|
||||
@@ -165,10 +163,10 @@ But objects not derived from Bar cannot:
|
||||
|
||||
>>> try: baz.pass_bar(baz)
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "'pass_bar' expected argument\(s\) \(demo.Baz, demo.Bar\),\n"
|
||||
... "but got \(demo.Baz, demo.Baz\) instead.", str(err))
|
||||
... print str(err)
|
||||
... else: print 'no exception'
|
||||
'pass_bar' expected argument(s) (demo.Baz, demo.Bar),
|
||||
but got (demo.Baz, demo.Baz) instead.
|
||||
|
||||
(this error was:
|
||||
TypeError: extension class 'Baz' is not convertible into 'Bar'.
|
||||
@@ -361,16 +359,15 @@ Some simple overloading tests:
|
||||
>>> r.finish
|
||||
7
|
||||
>>> try: r = Range('yikes')
|
||||
... except TypeError, e:
|
||||
... assert re.match(
|
||||
... "No variant of overloaded function 'demo.Range.__init__' matches argument\(s\):\n"
|
||||
... "\(string\)\n"
|
||||
... "Candidates are:\n"
|
||||
... "\(int\)\n"
|
||||
... "\(int, int\)",
|
||||
... str(e))
|
||||
... except TypeError, err:
|
||||
... print str(err)
|
||||
... else: print 'no exception'
|
||||
|
||||
No variant of overloaded function 'demo.Range.__init__' matches argument(s):
|
||||
(demo.Range, string)
|
||||
Candidates are:
|
||||
(int)
|
||||
(int, int)
|
||||
|
||||
Sequence tests:
|
||||
>>> len(Range(3, 10))
|
||||
7
|
||||
@@ -577,20 +574,19 @@ Testing overloaded free functions
|
||||
15
|
||||
>>> try: overloaded(1, 'foo')
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "No variant of overloaded function 'overloaded' matches argument\(s\):\n"
|
||||
... "\(int, string\)\n"
|
||||
... "Candidates are:\n"
|
||||
... "\(\)\n"
|
||||
... "\(int\)\n"
|
||||
... "\(string\)\n"
|
||||
... "\(int, int\)\n"
|
||||
... "\(int, int, int\)\n"
|
||||
... "\(int, int, int, int\)\n"
|
||||
... "\(int, int, int, int, int\)",
|
||||
... str(err))
|
||||
... print str(err)
|
||||
... else:
|
||||
... print 'no exception'
|
||||
No variant of overloaded function 'overloaded' matches argument(s):
|
||||
(int, string)
|
||||
Candidates are:
|
||||
()
|
||||
(int)
|
||||
(string)
|
||||
(int, int)
|
||||
(int, int, int)
|
||||
(int, int, int, int)
|
||||
(int, int, int, int, int)
|
||||
|
||||
Testing overloaded constructors
|
||||
|
||||
@@ -617,20 +613,19 @@ Testing overloaded constructors
|
||||
5
|
||||
>>> try: over = OverloadTest(1, 'foo')
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "No variant of overloaded function 'demo.OverloadTest.__init__' matches argument\(s\):\n"
|
||||
... "\(int, string\)\n"
|
||||
... "Candidates are:\n"
|
||||
... "\(\)\n"
|
||||
... "\(demo.OverloadTest\)\n"
|
||||
... "\(int\)\n"
|
||||
... "\(int, int\)\n"
|
||||
... "\(int, int, int\)\n"
|
||||
... "\(int, int, int, int\)\n"
|
||||
... "\(int, int, int, int, int\)",
|
||||
... str(err))
|
||||
... print str(err)
|
||||
... else:
|
||||
... print 'no exception'
|
||||
No variant of overloaded function 'demo.OverloadTest.__init__' matches argument(s):
|
||||
(demo.OverloadTest, int, string)
|
||||
Candidates are:
|
||||
()
|
||||
(demo.OverloadTest)
|
||||
(int)
|
||||
(int, int)
|
||||
(int, int, int)
|
||||
(int, int, int, int)
|
||||
(int, int, int, int, int)
|
||||
|
||||
Testing overloaded methods
|
||||
|
||||
@@ -649,30 +644,28 @@ Testing overloaded methods
|
||||
5
|
||||
>>> try: over.overloaded(1,'foo')
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "No variant of overloaded function 'overloaded' matches argument\(s\):\n"
|
||||
... "\(demo.OverloadTest, int, string\)\n"
|
||||
... "Candidates are:\n"
|
||||
... "\(demo.OverloadTest\)\n"
|
||||
... "\(demo.OverloadTest, int\)\n"
|
||||
... "\(demo.OverloadTest, int, int\)\n"
|
||||
... "\(demo.OverloadTest, int, int, int\)\n"
|
||||
... "\(demo.OverloadTest, int, int, int, int\)\n"
|
||||
... "\(demo.OverloadTest, int, int, int, int, int\)",
|
||||
... str(err))
|
||||
... print str(err)
|
||||
... else:
|
||||
... print 'no exception'
|
||||
No variant of overloaded function 'overloaded' matches argument(s):
|
||||
(demo.OverloadTest, int, string)
|
||||
Candidates are:
|
||||
(demo.OverloadTest)
|
||||
(demo.OverloadTest, int)
|
||||
(demo.OverloadTest, int, int)
|
||||
(demo.OverloadTest, int, int, int)
|
||||
(demo.OverloadTest, int, int, int, int)
|
||||
(demo.OverloadTest, int, int, int, int, int)
|
||||
|
||||
Testing base class conversions
|
||||
|
||||
>>> try: testUpcast(over)
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "'testUpcast' expected argument\(s\) \(demo.Base\),\n"
|
||||
... "but got \(demo.OverloadTest\) instead.",
|
||||
... str(err))
|
||||
... print str(err)
|
||||
... else:
|
||||
... print 'no exception'
|
||||
'testUpcast' expected argument(s) (demo.Base),
|
||||
but got (demo.OverloadTest) instead.
|
||||
|
||||
(this error was:
|
||||
TypeError: extension class 'OverloadTest' is not convertible into 'Base'.
|
||||
@@ -688,12 +681,11 @@ TypeError: extension class 'OverloadTest' is not convertible into 'Base'.
|
||||
1000
|
||||
>>> try: testDowncast2(der1)
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "'testDowncast2' expected argument\(s\) \(demo.Derived2\),\n"
|
||||
... "but got \(demo.Base\) instead.",
|
||||
... str(err))
|
||||
... print str(err)
|
||||
... else:
|
||||
... print 'no exception'
|
||||
'testDowncast2' expected argument(s) (demo.Derived2),
|
||||
but got (demo.Base) instead.
|
||||
|
||||
(this error was:
|
||||
TypeError: extension class 'Base' is not convertible into 'Derived2'.
|
||||
@@ -707,12 +699,11 @@ TypeError: extension class 'OverloadTest' is not convertible into 'Base'.
|
||||
>>> der2 = derived2Factory(1111)
|
||||
>>> try: testDowncast2(der2)
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "'testDowncast2' expected argument\(s\) \(demo.Derived2\),\n"
|
||||
... "but got \(demo.Base\) instead.",
|
||||
... str(err))
|
||||
... print str(err)
|
||||
... else:
|
||||
... print 'no exception'
|
||||
'testDowncast2' expected argument(s) (demo.Derived2),
|
||||
but got (demo.Base) instead.
|
||||
|
||||
(this error was:
|
||||
TypeError: extension class 'Base' is not convertible into 'Derived2'.
|
||||
@@ -729,12 +720,11 @@ Testing interaction between callbacks, base declarations, and overloading
|
||||
2
|
||||
>>> try: c.testCallback('foo')
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "'testCallback' expected argument\(s\) \(demo.CallbackTestBase, int\),\n"
|
||||
... "but got \(demo.CallbackTest, string\) instead.",
|
||||
... str(err))
|
||||
... print str(err)
|
||||
... else:
|
||||
... print 'no exception'
|
||||
'testCallback' expected argument(s) (demo.CallbackTestBase, int),
|
||||
but got (demo.CallbackTest, string) instead.
|
||||
>>> c.callback(1)
|
||||
2
|
||||
>>> c.callback('foo')
|
||||
@@ -755,12 +745,11 @@ Testing interaction between callbacks, base declarations, and overloading
|
||||
'foo 1'
|
||||
>>> try: r.testCallback('foo')
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "'testCallback' expected argument\(s\) \(demo.CallbackTestBase, int\),\n"
|
||||
... "but got \(demo.RedefineCallback, string\) instead.",
|
||||
... str(err))
|
||||
... print str(err)
|
||||
... else:
|
||||
... print 'no exception'
|
||||
'testCallback' expected argument(s) (demo.CallbackTestBase, int),
|
||||
but got (demo.RedefineCallback, string) instead.
|
||||
>>> r.testCallback(1)
|
||||
-1
|
||||
>>> testCallback(r, 1)
|
||||
@@ -1050,28 +1039,26 @@ test inheritB2
|
||||
32
|
||||
>>> try: j = pow(i, 5, k)
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "No variant of overloaded function '__pow__' matches argument\(s\):\n"
|
||||
... "\(demo.Int, int, demo.Int\)\n"
|
||||
... "Candidates are:\n"
|
||||
... "\(demo.Int, demo.Int\)\n"
|
||||
... "\(demo.Int, demo.Int, demo.Int\)\n"
|
||||
... "\(demo.Int, int\)",
|
||||
... str(err))
|
||||
... print str(err)
|
||||
... else:
|
||||
... print 'no exception'
|
||||
No variant of overloaded function '__pow__' matches argument(s):
|
||||
(demo.Int, int, demo.Int)
|
||||
Candidates are:
|
||||
(demo.Int, demo.Int)
|
||||
(demo.Int, demo.Int, demo.Int)
|
||||
(demo.Int, int)
|
||||
>>> try: j = pow(i, 5, 5)
|
||||
... except TypeError, err:
|
||||
... assert re.match(
|
||||
... "No variant of overloaded function '__pow__' matches argument\(s\):\n"
|
||||
... "\(demo.Int, int, int\)\n"
|
||||
... "Candidates are:\n"
|
||||
... "\(demo.Int, demo.Int\)\n"
|
||||
... "\(demo.Int, demo.Int, demo.Int\)\n"
|
||||
... "\(demo.Int, int\)",
|
||||
... str(err))
|
||||
... print str(err)
|
||||
... else:
|
||||
... print 'no exception'
|
||||
No variant of overloaded function '__pow__' matches argument(s):
|
||||
(demo.Int, int, int)
|
||||
Candidates are:
|
||||
(demo.Int, demo.Int)
|
||||
(demo.Int, demo.Int, demo.Int)
|
||||
(demo.Int, int)
|
||||
>>> j = i/1
|
||||
Traceback (innermost last):
|
||||
TypeError: __div__(demo.Int, int) undefined.
|
||||
|
||||
Reference in New Issue
Block a user