2
0
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:
Ullrich Köthe
2000-11-24 11:56:17 +00:00
parent 517b307622
commit 0bcf6cfba1
6 changed files with 107 additions and 165 deletions

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.