Surprising code !!!

2 views
Skip to first unread message

Florent Hivert

unread,
Jun 14, 2010, 6:10:22 PM6/14/10
to Sage Devel
Hi there,

Looking into sage library, I found the following code: file matrix0.pyx

cdef class Matrix(sage.structure.element.Matrix):
...
def __copy__(self):
"""
...
"""
return self.__copy__()

what is the intention here ? I hope this code is never executed ? Why not
return an error ?

Cheers,

Florent

Jason Grout

unread,
Jun 14, 2010, 6:25:38 PM6/14/10
to sage-...@googlegroups.com

Generic matrices have their own __copy__ method (overriding this). I
hope the above code isn't ever executed either.

Here is the result of executing the method, which gives the expected error:

sage: import sage.matrix.matrix0
sage: A = sage.matrix.matrix0.Matrix(MatrixSpace(QQ,2))
sage: type(A)
<type 'sage.matrix.matrix0.Matrix'>
sage: copy(A)
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)

/Users/grout/sage-4.4.2-test3/spkg/standard/sagenb-0.8.p3/src/sagenb/<ipython
console> in <module>()

/Users/grout/sage/local/lib/python/copy.pyc in copy(x)
77 copier = getattr(cls, "__copy__", None)
78 if copier:
---> 79 return copier(x)
80
81 reductor = dispatch_table.get(cls)

/Users/grout/sage/local/lib/python2.6/site-packages/sage/matrix/matrix0.so
in sage.matrix.matrix0.Matrix.__copy__ (sage/matrix/matrix0.c:2718)()

[snip]

RuntimeError: maximum recursion depth exceeded while calling a Python object
sage:

So the doctests for that function are useless for testing that function,
obviously.

Jason

Florent Hivert

unread,
Jun 14, 2010, 6:50:17 PM6/14/10
to sage-...@googlegroups.com
Hi Jason,

So this is just a strange way to raise an error ;-) No particular strange
Cython stuff to allows for inheritance or whatever...

Cheers,

Florent

William Stein

unread,
Jun 14, 2010, 7:40:39 PM6/14/10
to sage-...@googlegroups.com

Nope. You can (and I hope will) *definitely* safely just delete that
whole function.
The matrix_dense.pyx and matrix_sparse.pyx files both define their own __copy__,
and all matrices derive from one or the other.

This is now http://trac.sagemath.org/sage_trac/ticket/9239

William

-- William

Florent Hivert

unread,
Jun 14, 2010, 8:17:21 PM6/14/10
to sage-...@googlegroups.com
> Nope. You can (and I hope will) *definitely* safely just delete that
> whole function.
> [...]

Done

Florent

daveloeffler

unread,
Jun 15, 2010, 5:09:55 AM6/15/10
to sage-devel


On Jun 14, 11:25 pm, Jason Grout <jason-s...@creativetrax.com> wrote:

> So the doctests for that function are useless for testing that function,
> obviously.

I've wondered before if there's any way to make the test script check
that a given function has actually been called. I've seen several
errors similar to the above, with buggy code that was masked by code
in other modules, so the doctests for the original function were
actually calling something entirely different.

David

William Stein

unread,
Jun 15, 2010, 6:15:57 AM6/15/10
to sage-...@googlegroups.com

I doubt it in *general* due to the subtlety of Cython, which is a
massive part of Sage...

I very often write doctests that defensively avoid this. E.g., if I'm
writing a test in a class Foo,
then in my test I'll put

sage: make object X
sage: type(X)
Foo
sage: ...

This is especially important, because "make object X" could in the
future make an object of a totally different class, e.g., when
polynomials over QQ eventually switch to using FLINT. Then all tests
using them would not really be testing the generic polynomial class!
So the above means the relevant tests would break, and one would have
to replaces polys over QQ by some other generic poly class for generic
tests.

>
> David
>
> --
> To post to this group, send an email to sage-...@googlegroups.com
> To unsubscribe from this group, send an email to sage-devel+...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/sage-devel
> URL: http://www.sagemath.org
>

--
William Stein
Professor of Mathematics
University of Washington
http://wstein.org

Robert Bradshaw

unread,
Jun 21, 2010, 2:03:51 PM6/21/10
to sage-...@googlegroups.com
On Jun 15, 2010, at 3:15 AM, William Stein wrote:

> On Tue, Jun 15, 2010 at 2:09 AM, daveloeffler
> <dave.l...@gmail.com> wrote:
>>
>>
>> On Jun 14, 11:25 pm, Jason Grout <jason-s...@creativetrax.com> wrote:
>>
>>> So the doctests for that function are useless for testing that
>>> function,
>>> obviously.
>>
>> I've wondered before if there's any way to make the test script check
>> that a given function has actually been called. I've seen several
>> errors similar to the above, with buggy code that was masked by code
>> in other modules, so the doctests for the original function were
>> actually calling something entirely different.
>
> I doubt it in *general* due to the subtlety of Cython, which is a
> massive part of Sage...

With line profiling (to be implemented, but not too hard), we can
start getting line coverage stats for our test suite, which would be
very interesting to look at. (In fact, we could get function coverage
right now, as function profiling works for both Cython and Python).

> I very often write doctests that defensively avoid this. E.g., if I'm
> writing a test in a class Foo,
> then in my test I'll put
>
> sage: make object X
> sage: type(X)
> Foo
> sage: ...
>
> This is especially important, because "make object X" could in the
> future make an object of a totally different class, e.g., when
> polynomials over QQ eventually switch to using FLINT. Then all tests
> using them would not really be testing the generic polynomial class!
> So the above means the relevant tests would break, and one would have
> to replaces polys over QQ by some other generic poly class for generic
> tests.

+1. I try to do this too (not for every doctests, but for enough that
things will break if I start creating/testing the wrong implementation).

- Robert

Reply all
Reply to author
Forward
0 new messages