We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Modules, Packaging and Tooling step 11 of 41
List Every Import Cycle Once
In Find One Import Cycle you stopped at
the first cycle. A real check reports every cycle, so you can fix them all in
one pass. Write find_import_cycles(graph), which lists every cycle in an
import graph exactly once.
def find_import_cycles(graph: Mapping[str, Sequence[str]]) -> list[tuple[str, ...]]: ...
graph maps each module name to the modules it imports.
find_import_cycles({"b": ["c"], "c": ["a"], "a": ["b"]})
# [("a", "b", "c")]
find_import_cycles({"a": ["b", "c"], "b": ["c"], "c": ["a", "b"]})
# [("a", "b", "c"), ("a", "c"), ("b", "c")]
find_import_cycles({"a": ["a", "a", "external"]})
# [("a",)]
find_import_cycles({})
# []
What counts as a cycle
- Only the graph's keys are modules. Skip any import of a name that is not a key, such as
"external"above. - Treat a target listed twice as one import.
- Compare names as plain strings.
"Models"and"models"are different, and the dots in a name have no special meaning. - A cycle follows imports from a module back to itself without visiting any other module twice.
- Cycles that share a module are separate findings. Do not join them into one longer path that repeats the shared module.
- A module that imports itself is a cycle of one.
How to write each cycle
- Write a cycle as a tuple of its modules in import order, without repeating the first module at the end. This differs from the easy problem, which returned a list that starts and ends on the same module.
- Rotate the tuple so the smallest name, as
min()would pick it, comes first.("b", "c", "a")and("c", "a", "b")are both written("a", "b", "c"). - Do not sort the names inside a cycle.
("a", "c", "b")is a different cycle from("a", "b", "c"), and you report it only if those imports exist. - Return the cycles sorted with normal tuple ordering.
Search the whole graph, including modules that nothing imports. Do not change
graph or its lists. Your solution must pass mypy --strict.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Python reference solution
Sign in to track your attempts toward unlocking the reference solution.