Temporary variables used in class construction: can nose tests use them?

16 views
Skip to first unread message

EOL

unread,
May 22, 2009, 4:52:55 AM5/22/09
to nose-users
Hello,

Is there a way of writing tests that use temporary variables used
during class construction? To be specific, I have code that behaves
like this:

**
class C(object):

tmp = {...}
# Construction of class attibutes through tmp…
for t in tmp:
exec("__%s__ = 123" % t)

def test_class_construction_OK():
# Test _with the help of tmp_ that the attributes that were just
added are OK
# …

del tmp, t # Temporary variables should not be class attributes
**

nose complains that tmp does not exist, which is indeed the case after
instantiating the class. What can nose do in such a case, where
temporary variables used during class construction are better deleted,
but are needed by test functions?

Nat Williams

unread,
May 22, 2009, 7:57:11 PM5/22/09
to nose-...@googlegroups.com
Eric,

I'm having some trouble understanding what is going on with your code.  Is all that in the same module?  or are you importing C into the test module containing test_class_construction_OK?  Also, I'm not quite sure what you mean with "temporary variables".  Python is good enough at garbage collection that you shouldn't have to be worrying about deleting things.  Especially variables that you actually want to use later.  Have you tried just removing that del statement?  I don't think that this is actually a nose issue, but rather just one of scope.

(Also, the __setattr__ method would probably be a lot cleaner than that exec call)

Nat

EOL

unread,
May 23, 2009, 6:32:40 AM5/23/09
to nose-users
Thanks for the reply, Nat.

The code I mentioned is in a single module. I run tests with
nosetests on the file containing the code.

Running nose works if "del tmp, t" is commented out, but with an
inconvenient side effect. tmp and t should in fact be "temporary":
they are used for defining the class, but keeping them is not
necessary (or desired). If you don't delete them, they will not be
garbage collected, but instead become class attributes, which is
confusing for the user (when he does "dir" on an instance of C, for
example, he'll see that his instance has a tmp attribute, whose
meaning is not documented). What do you think of this?

Any idea/thought would be much appreciated!

Eric

PS: I'm not sure about the setattr that you suggest (setattr(C, …)
does not work since C is being defined). In any case, the code I
quote is not the real code, but a simplified version of it, and I do
need "exec".

On May 23, 1:57 am, Nat Williams <nat.willi...@gmail.com> wrote:
> Eric,
>
> I'm having some trouble understanding what is going on with your code.  Is
> all that in the same module?  or are you importing C into the test module
> containing test_class_construction_OK?  Also, I'm not quite sure what you
> mean with "temporary variables".  Python is good enough at garbage
> collection that you shouldn't have to be worrying about deleting things.
> Especially variables that you actually want to use later.  Have you tried
> just removing that del statement?  I don't think that this is actually a
> nose issue, but rather just one of scope.
>
> (Also, the __setattr__ method would probably be a lot cleaner than that exec
> call)
>
> Nat
>

jason pellerin

unread,
May 23, 2009, 9:11:57 AM5/23/09
to nose-...@googlegroups.com
Short answer: no, nose can't run tests at class construction time. If
an attribute is deleted from the class before nose sees it, nose can't
use it.

Long, opinionated answer: Move the class munging code someplace else.
Put it in a function called by a metaclass, then you can run the
function against any container you want and test the results.

But.... I'm not sure why you want to test this temporary code anyway.
Isn't that looking inside the box too much? Shouldn't you just be
testing the resulting class? If the resulting class doesn't tell you
enough about whether the temporary code worked, what's that code
doing?

JP

EOL

unread,
May 23, 2009, 2:25:27 PM5/23/09
to nose-users
Thanks for responding, Jason!

I'll investigate your idea of using a metaclass.

I actually have the same need as the one exemplified with a class, in
the original post, but also for some code run _when the module is
imported_, and I don't see how metaclasses could be used, in this case
(maybe I'm too naive, here :) ).

Here is an example of why I need tests that use variables that would
be temporary if there were no tests: I redefine functions of the math
module, where some of these functions are given analytical derivatives
_through the temporary variable_, which contain the analytical
formulas (the temporary variable in itself is not needed anymore by
the module, when the corresponding math functions are redefined). I
want to make sure that the analytical derivatives yield the same
result as numerical approximate derivatives. If I delete the
temporary variable when they are not needed anymore (tests
notwithstanding), the test function does not have access to the list
of functions to be checked. If I don't delete the temporary
dictionary of analytical formulas, then the module has a useless
attribute.

In the particular case above, I could certainly make the temporary
variables private, even though this would still leave an unnecessary
memory footprint. But in the case of a class (like in the example I
gave initially), non-deleted temporary variables appear as attributes
of each instance, which is confusing to any user doing a dir() on
instances. To respond to your question: I could test the behavior of
instances, but the testing code would be less robust, as it would have
to duplicate the list of attributes of interest, instead of using the
list of attributes currently defined in a variable (that I wish could
be temporary). Thus, if I later decide to modify the class to be
tested, I need not to forget to update the testing code as well (by
extending a list of defined attributes in _both_ the class and the
testing code). I wanted to use a variable in order to avoid just
that: the class construction and the test would perform the attribute
construction and the test on the same elements (defined in the
temporary list)--this would be possible if there was a way of running
the test during class construction.

So far, the best solution I see is to use private (__) temporary
variables for modules (the memory footprint of these variables is
small), and to duplicate the lists used during class construction in
the tests for the class (even though this violation of the "don't
duplicate" rule makes me cringe :) ).

I hope that the example of why I asked the initial question is
clearer!

All the best,

EOL

Vicki

unread,
May 23, 2009, 6:41:14 PM5/23/09
to nose-users


On May 23, 2:25 pm, EOL <eric.lebi...@normalesup.org> wrote:

> So far, the best solution I see is to use private (__) temporary
> variables for modules (the memory footprint of these variables is
> small), and to duplicate the lists used during class construction in
> the tests for the class (even though this violation of the "don't
> duplicate" rule makes me cringe :) ).

Why not put the temporary variables into their own module, and import
them both into the class (where they will be deleted after
instantiation), and into the test (where they will not be)?

EOL

unread,
May 24, 2009, 5:09:37 AM5/24/09
to nose-users
This looks like a nice solution for hiding temporary variables from
the user, Vicki. A slightly less heavy, similar solution would be to
make all temporary variables private (__) globals of the module.

This is a reasonable solution because the objects used by both the
class construction and the tests are not too big. Otherwise, it looks
to me like adding tests would be expensive, in this situation where
test functions need objects that the module user does not need.

I'd like to say that I really appreciate this discussion! It's good
to get input from knowledgeable people. :)

Jesse

unread,
May 26, 2009, 11:37:07 AM5/26/09
to nose-users
Eric,

Just felt the need to chime in that regardless how you name your
attributes,
exec is absolutely not necessary.

There are various ways of setting arbitrary attributes to a class
during
its definition. Below are listed some examples; though they vary in
awesomeness, I would argue they're all preferable to exec.

class Foo(object):
"""Since the obvious way is essentially to define variables in
the class
scope, updating the dictionary returned by the call of
'locals' achieves
the same thing.
>>> Foo.foo
'bar'
>>> Foo.hi
'hello'
"""
locals().update({'foo': 'bar', 'hi': 'hello'})

class Bar(object):
"""Methods with access to the class may use 'setattr', (which
is short
for accessing the special '__setattr__' method), with the
class reference
its first argument.
__new__ is a special classmethod, which gets called on the
class upon
object instantiation before __init__ is called on the
instance, (and
which need not be explicitly defined as a 'classmethod').
>>> hasattr(Bar, 'foo')
False
>>> ## instantiating Bar implicitly calls __new__
>>> assert Bar()
>>> Bar.foo
'bar'
"""
def __new__(cls):
setattr(cls, 'foo', 'bar')
return super(Bar, cls).__new__(cls)

class FooBar(object):
"""The class is furthermore accessible on the object, via the
special
__class__ attribute, and can thereby be interacted with by all
instance
methods, including the constructor.
>>> hasattr(FooBar, 'foo')
False
>>> ## instantiating FooBar implicitly calls __init__
>>> assert FooBar()
>>> FooBar.foo
'bar'
"""
def __init__(self):
setattr(self.__class__, 'foo', 'bar')

...Anyway, good luck with your testing.
Jesse
Reply all
Reply to author
Forward
0 new messages