On Thu, Jan 16, 2014 at 2:46 PM, Roy Smith <r...@panix.com> wrote: > So, I figured I would write a meta-test, which used introspection to > find all the methods in the class, extract the strings from them (they > are all assigned to a variable named RECEIPT), and check to make sure > they're all different.
In theory, it should be. You can disassemble the function and find the assignment. Check out Lib/dis.py - or just call it and process its output. Names of local variables are found in test_t1.__code__.co_names, the constants themselves are in test_1.__code__.co_consts, and then it's just a matter of matching up which constant got assigned to the slot represented by the name RECEIPT. But you might be able to shortcut it enormously. You say the strings are "about 2500 characters long, hex-encoded". What are the chances of having another constant, somewhere in the test function, that also happens to be roughly that long and hex-encoded? If the answer is "practically zero", then skip the code, skip co_names, and just look through co_consts. class TestCase: pass # not running this in the full environment class Foo(TestCase): def test_t1(self): RECEIPT = "some string" def test_t2(self): RECEIPT = "some other string" def test_t3(self): RECEIPT = "yet a third string" def test_oops(self): RECEIPT = "some other string" unique = {} for funcname in dir(Foo): if funcname.startswith("test_"): for const in getattr(Foo,funcname).__code__.co_consts: if isinstance(const, str) and const.endswith("string"): if const in unique: print("Collision!", unique[const], "and", funcname) unique[const] = funcname This depends on your RECEIPT strings ending with the word "string" - change the .endswith() check to be whatever it takes to distinguish your critical constants from everything else you might have. Maybe: CHARSET = set("0123456789ABCDEF") # or use lower-case letters, or both, according to your hex encoding if isinstance(const, str) and len(const)>2048 and set(const)<=CHARSET: Anything over 2KB with no characters outside of that set is highly likely to be what you want. Of course, this whole theory goes out the window if your test functions can reference another test's RECEIPT; though if you can guarantee that this is the *first* such literal (if RECEIPT="..." is the first thing the function does), then you could just add a 'break' after the unique[const]=funcname assignment and it'll check only the first - co_consts is ordered. An interesting little problem! ChrisA -- https://mail.python.org/mailman/listinfo/python-list