Find cycles in Graph using Union Find Algorithm on Adjacency List
addnode(self, key1, key2, edge=0)

The parameter edge is not used.  Either remove it, or use it, but keeping it with a default value and not using it is obfuscation.

self.graph is a defaultdict(list), so testing if key2 is not present, and setting that key’s value to an empty list if it isn’t present, which is the raison d’être for the defaultdict(list), isn’t using that class properly.  You want the key to exist, but don’t want to add any values to it.  Simply use:

_ = self.graph[key2]


findcycle(self)

This function returns True or None.  It would be much easier to write documentation for the function if it returned only one “kind” of value.  Add return False to the end of the function. 

Test cases

Put your test cases inside a __name__ == '__main__' guard.  Then you can import this as a module into another file without the tests running, but running this file by itself will still execute the tests. 

if __name__ == '__main__':
    g = graph()
    g.addnode(0, 1)
    # ...


PEP8

Follow the PEP8 standard guidelines.  Put a space after all commas, don’t put a space before the parentheses in function calls.  Use an automatic checker (pylint, pyflakes, ...) to ensure you don’t violate these guidelines.