# Build dependency graph
graph = build_dependency_graph()
print(f"Found {len(graph.modules)} modules with {len(graph.dependencies)} dependencies")Found 7 modules with 19 dependenciesModuleDependency (source:str, target:str, import_type:str, imported_names:List[str]=<factory>)
Represents a dependency between modules
DependencyGraph (modules:Dict[str,cjm_nbdev_overview.parsers.ModuleInfo] =<factory>, dependencies:List[__main__.ModuleDependency]=<factory>)
Dependency graph for a project
extract_project_imports (import_str:str, project_name:str)
Extract project-internal imports from an import statement
| Type | Details | |
|---|---|---|
| import_str | str | Import statement | 
| project_name | str | Project package name | 
| Returns | Optional | Dependency if internal | 
analyze_module_dependencies (module:cjm_nbdev_overview.parsers.ModuleInf o, project_name:str)
Analyze a module’s imports to find project-internal dependencies
| Type | Details | |
|---|---|---|
| module | ModuleInfo | Module to analyze | 
| project_name | str | Project package name | 
| Returns | List | Dependencies found | 
build_dependency_graph (path:pathlib.Path=None, project_name:Optional[str]=None)
Build a dependency graph for all modules in a project
| Type | Default | Details | |
|---|---|---|---|
| path | Path | None | Project path | 
| project_name | Optional | None | Override project name | 
| Returns | DependencyGraph | Dependency graph | 
generate_mermaid_diagram (graph:__main__.DependencyGraph, direction:str='TD', show_imports:bool=False)
Generate a Mermaid.js dependency diagram from a dependency graph
| Type | Default | Details | |
|---|---|---|---|
| graph | DependencyGraph | Dependency graph | |
| direction | str | TD | Diagram direction (TD/LR) | 
| show_imports | bool | False | Show imported names | 
| Returns | str | Mermaid diagram code | 
generate_dependency_matrix (graph:__main__.DependencyGraph)
Generate a dependency matrix showing which modules depend on which
| Type | Details | |
|---|---|---|
| graph | DependencyGraph | Dependency graph | 
| Returns | str | Markdown table | 
Let’s test the dependency analysis on our project:
Found 7 modules with 19 dependencies
api_docs depends on:
  - parsers: *
  - dependencies: *
  - tree: *
  - core: *
cli depends on:
  - parsers: *
  - tree: *
  - api_docs: *
  - dependencies: *
dependencies depends on:
  - dependencies: ModuleDependency
  - parsers: *
  - parsers: ModuleInfo
  - dependencies: generate_mermaid_diagram
  - core: *
  - dependencies: DependencyGraph
generators depends on:
  - tree: *
  - core: *
parsers depends on:
  - tree: extract_notebook_info
  - core: *
tree depends on:
  - core: *# Test with a sample graph that includes reserved keywords
from cjm_nbdev_overview.dependencies import DependencyGraph, ModuleDependency, generate_mermaid_diagram
from cjm_nbdev_overview.parsers import ModuleInfo
from pathlib import Path
# Create test graph with reserved keywords
test_graph = DependencyGraph()
# Add modules including ones with reserved keywords
modules_data = [
    ("colors", "Colors"),
    ("core", "Core"),
    ("examples", "Practical Usage Examples"),
    ("layout", "Layout"),
    ("modern", "Modern"),
    ("style", "Style"),  # This should trigger the reserved keyword handling
    ("types", "Type Definitions"),
    ("validation", "Validation"),
    ("variants", "Variants")
]
for name, title in modules_data:
    module = ModuleInfo(
        path=Path(f"nbs/{name}.ipynb"),
        name=name,
        title=title,
        description=None,
        functions=[],
        classes=[],
        variables=[],
        imports=[]
    )
    test_graph.add_module(module)
# Add some test dependencies
test_dependencies = [
    ("colors", "validation"),
    ("colors", "types"),
    ("core", "types"),
    ("core", "validation"),
    ("examples", "validation"),
    ("examples", "variants"),
    ("examples", "core"),
    ("examples", "modern"),
    ("examples", "colors"),
    ("examples", "layout"),
    ("examples", "style"),  # This should work with escaped style
    ("layout", "core"),
    ("layout", "types"),
    ("layout", "validation"),
    ("modern", "core"),
    ("style", "core"),      # This should work with escaped style
    ("style", "types"),     # This should work with escaped style
    ("style", "colors"),    # This should work with escaped style
    ("style", "validation"),# This should work with escaped style
    ("variants", "core")
]
for source, target in test_dependencies:
    dep = ModuleDependency(source=source, target=target, import_type="from", imported_names=["*"])
    test_graph.add_dependency(dep)
# Generate diagram that should now work without parse errors
print("## Test Diagram with Reserved Keywords Handled\n")
print(generate_mermaid_diagram(test_graph, direction="LR"))## Test Diagram with Reserved Keywords Handled
```mermaid
graph LR
    colors[colors<br/>Colors]
    core[core<br/>Core]
    examples[examples<br/>Practical Usage Examples]
    layout[layout<br/>Layout]
    modern[modern<br/>Modern]
    style_mod[style<br/>Style]
    types[types<br/>Type Definitions]
    validation[validation<br/>Validation]
    variants[variants<br/>Variants]
    colors --> validation
    colors --> types
    core --> types
    core --> validation
    examples --> validation
    examples --> variants
    examples --> core
    examples --> modern
    examples --> colors
    examples --> layout
    examples --> style_mod
    layout --> core
    layout --> types
    layout --> validation
    modern --> core
    style_mod --> core
    style_mod --> types
    style_mod --> colors
    style_mod --> validation
    variants --> core
```# Test nested module imports
test_imports = [
    "from cjm_fasthtml_daisyui.core.base import DaisyComponent, DaisySize",
    "from cjm_fasthtml_daisyui.core.colors import SemanticColor",
    "from cjm_fasthtml_daisyui.core.behaviors import InteractiveMixin, FormControlMixin",
    "from cjm_fasthtml_daisyui.core.modifiers import StyleType, HasStyles",
    "from cjm_fasthtml_daisyui.core.htmx import HTMXComponent, HTMXAttrs",
    "from cjm_fasthtml_daisyui.core import *"
]
print("Testing nested module import extraction:")
print("-" * 50)
for import_str in test_imports:
    dep = extract_project_imports(import_str, "cjm_fasthtml_daisyui")
    if dep:
        print(f"Import: {import_str}")
        print(f"  Target module: {dep.target}")
        print(f"  Imported names: {', '.join(dep.imported_names)}")
        print()Testing nested module import extraction:
--------------------------------------------------
Import: from cjm_fasthtml_daisyui.core.base import DaisyComponent, DaisySize
  Target module: core.base
  Imported names: DaisyComponent, DaisySize
Import: from cjm_fasthtml_daisyui.core.colors import SemanticColor
  Target module: core.colors
  Imported names: SemanticColor
Import: from cjm_fasthtml_daisyui.core.behaviors import InteractiveMixin, FormControlMixin
  Target module: core.behaviors
  Imported names: InteractiveMixin, FormControlMixin
Import: from cjm_fasthtml_daisyui.core.modifiers import StyleType, HasStyles
  Target module: core.modifiers
  Imported names: StyleType, HasStyles
Import: from cjm_fasthtml_daisyui.core.htmx import HTMXComponent, HTMXAttrs
  Target module: core.htmx
  Imported names: HTMXComponent, HTMXAttrs
Import: from cjm_fasthtml_daisyui.core import *
  Target module: core
  Imported names: *
# Test with a graph that simulates the nested module structure from the bug report
nested_test_graph = DependencyGraph()
# Add nested modules like in the bug report
nested_modules = [
    ("actions.button", "Button"),
    ("core.animation", "Animation & Transitions"),
    ("core.base", "Core Base Classes"),
    ("core.behaviors", "Behavior States"),
    ("core.colors", "Colors"),
    ("core.config", "Configuration"),
    ("core.factory", "Component Factory"),
    ("core.htmx", "HTMX Integration"),
    ("core.modifiers", "Style Modifiers"),
    ("core.parts", "Component Parts"),
    ("core.placement", "Placement & Direction"),
    ("core.resources", "Resources"),
    ("core.testing", "Testing"),
    ("core.validation", "Validation"),
    ("core.variants", "Variant System")
]
for name, title in nested_modules:
    module = ModuleInfo(
        path=Path(f"nbs/{name.replace('.', '/')}.ipynb"),
        name=name,
        title=title,
        description=None,
        functions=[],
        classes=[],
        variables=[],
        imports=[]
    )
    nested_test_graph.add_module(module)
# Add dependencies from actions.button to various core modules
dependencies_to_add = [
    ("actions.button", "core.base", ["DaisyComponent", "DaisySize"]),
    ("actions.button", "core.colors", ["SemanticColor"]),
    ("actions.button", "core.behaviors", ["InteractiveMixin", "FormControlMixin"]),
    ("actions.button", "core.modifiers", ["StyleType", "HasStyles"]),
    ("actions.button", "core.htmx", ["HTMXComponent", "HTMXAttrs"]),
    # Self-dependencies within core
    ("core.base", "core.colors", ["*"]),
    ("core.factory", "core.base", ["*"]),
    ("core.htmx", "core.base", ["*"]),
    ("core.testing", "core.validation", ["*"]),
    ("core.validation", "core.config", ["*"])
]
for source, target, imported in dependencies_to_add:
    dep = ModuleDependency(source=source, target=target, import_type="from", imported_names=imported)
    nested_test_graph.add_dependency(dep)
# Generate the corrected diagram
print("## Fixed Mermaid Diagram with Nested Modules\n")
print(generate_mermaid_diagram(nested_test_graph, direction="LR"))
print(f"\n*{len(nested_test_graph.dependencies)} cross-module dependencies detected*")## Fixed Mermaid Diagram with Nested Modules
```mermaid
graph LR
    actions_button[actions.button<br/>Button]
    core_animation[core.animation<br/>Animation & Transitions]
    core_base[core.base<br/>Core Base Classes]
    core_behaviors[core.behaviors<br/>Behavior States]
    core_colors[core.colors<br/>Colors]
    core_config[core.config<br/>Configuration]
    core_factory[core.factory<br/>Component Factory]
    core_htmx[core.htmx<br/>HTMX Integration]
    core_modifiers[core.modifiers<br/>Style Modifiers]
    core_parts[core.parts<br/>Component Parts]
    core_placement[core.placement<br/>Placement & Direction]
    core_resources[core.resources<br/>Resources]
    core_testing[core.testing<br/>Testing]
    core_validation[core.validation<br/>Validation]
    core_variants[core.variants<br/>Variant System]
    actions_button --> core_base
    actions_button --> core_colors
    actions_button --> core_behaviors
    actions_button --> core_modifiers
    actions_button --> core_htmx
    core_base --> core_colors
    core_factory --> core_base
    core_htmx --> core_base
    core_testing --> core_validation
    core_validation --> core_config
```
*10 cross-module dependencies detected*
## Dependency Matrix
| Module | api_docs | cli | core | dependencies | generators | parsers | tree |
|--------|----|----|----|----|----|----|----|
| api_docs |   |   | ✓ | ✓ |   | ✓ | ✓ |
| cli | ✓ |   |   | ✓ |   | ✓ | ✓ |
| core |   |   |   |   |   |   |   |
| dependencies |   |   | ✓ | ✓ |   | ✓ |   |
| generators |   |   | ✓ |   |   |   | ✓ |
| parsers |   |   | ✓ |   |   |   | ✓ |
| tree |   |   | ✓ |   |   |   |   |