Core-dump when (mis)using scale_transform

Hi,

I've been using matplotlib for a little while and am finding it very
useful. Yesterday, though, I hit a problem:

Because I didn't read the docs properly, I tried to use

   matplotlib.transforms.scale_transform

like this:

   t = scale_transform(1.0, 2.0)

but then I got a core-dump when trying to use it:

   from matplotlib.transforms import scale_transform
   t = scale_transform(1.0, 2.0)
   print t.xy_tup((1.0, 0.2))

What I should have done was this, which works:

   from matplotlib.transforms import scale_transform, Value
   t = scale_transform(Value(1.0), Value(2.0))
   print t.xy_tup((1.0, 0.2))

The function _transforms_module::new_affine() in _transforms.cpp does
contain checks that its args are LazyValue objects, but it seems to
ignore the results. The following patch (against 0.90.1) makes the
constructor throw a TypeError if it doesn't get what it wants. (It also
fixes a small typo in a separate error string.)

--- ORIG/_transforms.cpp 2007-07-17 10:10:37.443202000 +0100
+++ NEW/_transforms.cpp 2007-07-17 10:11:00.257365000 +0100
@@ -42,7 +42,7 @@
int
LazyValue::compare(const Py::Object &other) {
   if (!check(other))
- throw Py::TypeError("Can on compare LazyValues with LazyValues");
+ throw Py::TypeError("Can only compare LazyValues with LazyValues");
   LazyValue* pother = static_cast<LazyValue*>(other.ptr());
   double valself = val();
   double valother = pother->val();
@@ -2116,12 +2116,13 @@

   args.verify_length(6);

- LazyValue::check(args[0]);
- LazyValue::check(args[1]);
- LazyValue::check(args[2]);
- LazyValue::check(args[3]);
- LazyValue::check(args[4]);
- LazyValue::check(args[5]);
+ if (!LazyValue::check(args[0])
+ || !LazyValue::check(args[1])
+ || !LazyValue::check(args[2])
+ || !LazyValue::check(args[3])
+ || !LazyValue::check(args[4])
+ || !LazyValue::check(args[5]))
+ throw Py::TypeError("Affine(a, b, c, d, tx, ty) expected 6 LazyValue args");

   LazyValue* a = static_cast<LazyValue*>(args[0].ptr());
   LazyValue* b = static_cast<LazyValue*>(args[1].ptr());

Would this be worth applying? By the look of the code in transform.py,
translation_transform() and possibly others might be affected by this
too. Maybe a better solution might be to automatically construct Value
objects from Python floats where required, but that might need a bit
more thought.

Ben.

Thanks for tracking this down, Ben. Applied in svn as r3547.

Ben North wrote:

···

I've been using matplotlib for a little while and am finding it very
useful. Yesterday, though, I hit a problem: