Circular dependencies between packages are more common nowadays than they used to be in the past. It is often necessary to employ various hacks or toggle USE flags to bootstrap packages.
I can think of two major kinds of circular dependencies that are met commonly:
a. test dependencies on tested package -> i.e. dev-python/py[test] requires dev-python/pytest, dev-python/pytest requires dev-python/py,
b. build tool dependencies on libraries using the build tools -> i.e. dev-util/cmake deps on dev-libs/jsoncpp, dev-libs/jsoncpp uses dev-util/cmake as build system.
For the former, the user having FEATURES=test enabled is usually explicitly hit by the circular dep error and required to take explicit action. For the latter, we usually default to enabling bundled libraries and require users to explcitly disable them later on (which sucks from sec standpoint).
So, in order to improve things I'd like to suggest adding explicit circular dep solving suggestions to ebuild. The idea would be to use a trivial, REQUIRED_USE-like format, e.g.:
which would mean, respectively, 'if you met circular deps, try disabling test' and 'if you met circular deps, try enabling bundled-libs'.
For the initial implementation, it would be enough to display those suggestions if the package gets involved in circular dependency chain [note: how deep do we want to handle this?]. While this would still require explicit action from user, he would at least see a clear suggestion of what he might do instead of guessing.
Eventually, I think we could make Portage try to automatically reevaluate the dependency graph with suggestions applied when hitting circular dependencies. This could make it both possible to handle circular dependencies automatically but also to perform multi-stage builds, i.e. rebuild the package with proper USE flags after building the revdep.