[Tutor] Do not understand code snippet from "26.8. test — Regression tests package for Python"
boB Stepp
robertvstepp at gmail.com
Mon Apr 17 22:49:12 EDT 2017
Ah, Peter, if only I could achieve your understanding and mastery!
On Mon, Apr 17, 2017 at 3:37 AM, Peter Otten <__peter__ at web.de> wrote:
> Perhaps it becomes clearer if we build our own class discovery / method
> runner system. Given T as the baseclass for classes that provide foo_...()
> methods that we want to run, and M as the mix-in that provides such methods
> but isn't itself a subclass of T...
>
[snip]
> As you can see, to the discovery algorithm it doesn't matter where the
> method is defined, it suffices that it's part of the class and can be found
> by dir() or vars().
>
[snip]
>
> $ cat discovery6.py
> class T:
> pass
>
> class M:
> def foo_one(self):
> print(self.__class__.__name__, "one")
> def foo_two(self):
> print(self.__class__.__name__, "two")
>
> class X(T):
> def foo_x(self):
> print(self.__class__.__name__, "x")
>
> class Y(M, T):
> pass
>
> def safe_issubclass(S, B):
> try:
> return issubclass(S, B)
> except TypeError:
> return False
>
> def discover_Ts():
> for C in globals().values():
> if safe_issubclass(C, T) and C is not T:
> print("found", C, "with foo_... methods")
> for name in dir(C):
> if name.startswith("foo_"):
> yield C, name
So your discover function does not need to instantiate any objects; it
just searches the module's global namespace for class names. Cool!
And dir(C) gives all attributes of C including _inherited_ attributes!
This clarifies so much. Many thanks, Peter!
> def run_method(cls, methodname):
> inst = cls()
> method = getattr(inst, methodname)
> method()
>
> def main():
> for cls, methodname in discover_Ts():
> run_method(cls, methodname)
>
> if __name__ == "__main__":
> main()
> $ python3 discovery6.py
> found <class '__main__.Y'> with foo_... methods
> Y one
> Y two
> found <class '__main__.X'> with foo_... methods
> X x
>
> That was easy. We have replicated something similar to the unit test
> framework with very little code.
>
> Now you can go and find the equivalent parts in the unittest source code :)
But not tonight ~(:>))
--
boB
More information about the Tutor
mailing list