On 27 February 2012 19:27, Mark Janssen <dreamingforward@gmail.com> wrote:
On Fri, Feb 17, 2012 at 10:08 PM, Steven D'Aprano <steve@pearwood.info> wrote:
> Mark Janssen wrote:
>> 1. Execution context determined by outer-scope doctest defintions.
>
> Can you give an example of how you would like this to work?
>

Sure, I wish I had a good example off the top of my head, but perhaps
this will convey the idea:

class MyClass():
 """Yadda Yadda: foo's bars.

>>> m = MyClass({some, sufficiently, interesting, initialization})  #tPOINT1:  this variable (m) now accessible by all methods.
"foobar check"   #POINT2: possible output here is a useful test case
not well-definable elsewhere without losing context.
"""

   def method1(self, other):
        """Method method method method.

        >>> m.method("foo")  #Now we see m is already defined and useable.
        "bar"
         """

   def meth2(self, other):
       """Method to foo all bars

      >>> m.method("bar") #would have to decide whether a fresh m is
redefined with each innerscope doctest (if we want side-effects to
carry across inner doctests).

(END)

This is a basic example, sorry it's rather crude.  There's probably a
better example.  (Think establishing a network socket connection or
something in the class' doc which is then used by all the methods, for
example.)

>> 2. Smart Comparisons that will detect output of a non-ordered type
>> (dict/set), lift and recast it and do a real comparison.>
>
> I would love to see a doctest directive that accepted differences in output
> order, e.g. would match {1, 2, 3} and {3, 1, 2}. But I think that's a hard
> problem to solve in the general case.

I think this would be as simple as lifting the (string) output and
doing an eval("{1,2,3}")=={3,2,1}, or (for security) using
ast.literal_eval like Devin suggested.



How will that handle not-particularly-obscure code like this:

>>> class Foo(object):
...  def __init__(self, a):
...   self.a = a
...  def __repr__(self):
...   return '<Foo a=%r>' % self.a
...
>>> a = {Foo(1), Foo(2), Foo(3)}
>>> b = {Foo(4), Foo(5), Foo(6)}
>>> {'first': a, 'second': b}
{'second': set([<Foo a=4>, <Foo a=6>, <Foo a=5>]), 'first': set([<Foo a=3>, <Foo a=2>, <Foo a=1>])}


I don't think a *general* solution for unordered types is even possible because you can't parse arbitrary reprs.

All the best,

Michael

 
> I'd like a #3 as well: an abbreviated way to spell doctest directives,
> because they invariably push my tests well past the 80 character mark.

Hmm, seem like an alias could be defined easily enough, but I'll try
to think about this when I have more time.

mark
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
http://mail.python.org/mailman/listinfo/python-ideas



--
http://www.voidspace.org.uk/

May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing http://www.sqlite.org/different.html