# Migration Guide This guide covers changes between the git tag `release` and the current tree. At `release`, `masque.__version__` was `3.3`; the current tree reports `3.4`. Most downstream changes are in `masque/builder/*`, but there are a few other API changes that may require code updates. ## Routing API: renamed and consolidated The routing helpers were consolidated into a single implementation in `masque/builder/pather.py`. The biggest migration point is that the old routing verbs were renamed: | Old API | New API | | --- | --- | | `Pather.path(...)` | `Pather.trace(...)` | | `Pather.path_to(...)` | `Pather.trace_to(...)` | | `Pather.mpath(...)` | `Pather.trace(...)` / `Pather.trace_to(...)` with multiple ports | | `Pather.path_into(...)` | `Pather.trace_into(...)` | | `RenderPather.path(...)` | `RenderPather.trace(...)` | | `RenderPather.path_to(...)` | `RenderPather.trace_to(...)` | | `RenderPather.mpath(...)` | `RenderPather.trace(...)` / `RenderPather.trace_to(...)` | | `RenderPather.path_into(...)` | `RenderPather.trace_into(...)` | There are also new convenience wrappers: - `straight(...)` for `trace_to(..., ccw=None, ...)` - `ccw(...)` for `trace_to(..., ccw=True, ...)` - `cw(...)` for `trace_to(..., ccw=False, ...)` - `jog(...)` for S-bends - `uturn(...)` for U-bends Important: `Pather.path()` is no longer the routing API. It now forwards to `Pattern.path()` and creates a geometric `Path` element. Any old routing code that still calls `pather.path(...)` must be renamed. ### Common rewrites ```python # old pather.path('VCC', False, 6_000) pather.path_to('VCC', None, x=0) pather.mpath(['GND', 'VCC'], True, xmax=-10_000, spacing=5_000) pather.path_into('src', 'dst') # new pather.cw('VCC', 6_000) pather.straight('VCC', x=0) pather.ccw(['GND', 'VCC'], xmax=-10_000, spacing=5_000) pather.trace_into('src', 'dst') ``` If you prefer the more explicit spelling, `trace(...)` and `trace_to(...)` remain the underlying primitives: ```python pather.trace('VCC', False, 6_000) pather.trace_to('VCC', None, x=0) ``` ## `PortPather` and `.at(...)` Routing can now be written in a fluent style via `.at(...)`, which returns a `PortPather`. ```python (rpather.at('VCC') .trace(False, length=6_000) .trace_to(None, x=0) ) ``` This is additive, not required for migration. Existing code can stay with the non-fluent `Pather`/`RenderPather` methods after renaming the verbs above. ## Imports and module layout `Builder`, `Pather`, and `RenderPather` now live together in `masque/builder/pather.py`. The old module files `masque/builder/builder.py` and `masque/builder/renderpather.py` were removed. Update imports like this: ```python # old from masque.builder.builder import Builder from masque.builder.renderpather import RenderPather # new from masque.builder import Builder, RenderPather ``` Top-level imports from `masque` also continue to work. `Builder` is now a thin compatibility wrapper over the unified `Pather` implementation with `auto_render=True`. `RenderPather` is the same wrapper with `auto_render=False`. ## `BasicTool` was replaced `BasicTool` is no longer exported. Use: - `SimpleTool` for the simple "one straight generator + one bend cell" case - `AutoTool` if you need transitions, multiple candidate straights/bends, or S-bends/U-bends ### Old `BasicTool` ```python from masque.builder.tools import BasicTool tool = BasicTool( straight=(make_straight, 'input', 'output'), bend=(lib.abstract('bend'), 'input', 'output'), transitions={ 'm2wire': (lib.abstract('via'), 'top', 'bottom'), }, ) ``` ### New `AutoTool` ```python from masque.builder.tools import AutoTool tool = AutoTool( straights=[ AutoTool.Straight( ptype='m1wire', fn=make_straight, in_port_name='input', out_port_name='output', ), ], bends=[ AutoTool.Bend( abstract=lib.abstract('bend'), in_port_name='input', out_port_name='output', clockwise=True, ), ], sbends=[], transitions={ ('m2wire', 'm1wire'): AutoTool.Transition( lib.abstract('via'), 'top', 'bottom', ), }, default_out_ptype='m1wire', ) ``` The key differences are: - `BasicTool` -> `SimpleTool` or `AutoTool` - `straight=(fn, in_name, out_name)` -> `straights=[AutoTool.Straight(...)]` - `bend=(abstract, in_name, out_name)` -> `bends=[AutoTool.Bend(...)]` - transition keys are now `(external_ptype, internal_ptype)` tuples - transitions use `AutoTool.Transition(...)` instead of raw tuples If your old `BasicTool` usage did not rely on transitions or multiple routing options, `SimpleTool` is the closest replacement. ## Custom `Tool` subclasses If you maintain your own `Tool` subclass, the interface changed: - `Tool.path(...)` became `Tool.traceL(...)` - `Tool.traceS(...)` and `Tool.traceU(...)` were added for native S/U routes - `planL()` / `planS()` / `planU()` remain the planning hooks used by deferred rendering In practice, a minimal old implementation like: ```python class MyTool(Tool): def path(self, ccw, length, **kwargs): ... ``` should now become: ```python class MyTool(Tool): def traceL(self, ccw, length, **kwargs): ... ``` If you do not implement `traceS()` or `traceU()`, the unified pather will either fall back to the planning hooks or synthesize those routes from simpler steps where possible. ## Transform semantics changed The other major user-visible change is that `mirror()` and `rotate()` are now treated more consistently as intrinsic transforms on low-level objects. The practical migration rule is: - use `mirror()` / `rotate()` when you want to change the object relative to its own origin - use `flip_across(...)`, `rotate_around(...)`, or container-level transforms when you want to move the object in its parent coordinate system ### Example: `Port` Old behavior: ```python port.mirror(0) # changed both offset and orientation ``` New behavior: ```python port.mirror(0) # changes orientation only port.flip_across(axis=0) # old "mirror in the parent pattern" behavior ``` ### What to audit Check code that calls: - `Port.mirror(...)` - `Ref.rotate(...)` - `Ref.mirror(...)` - `Label.rotate_around(...)` / `Label.mirror(...)` If that code expected offsets or repetition grids to move automatically, it needs updating. For whole-pattern transforms, prefer calling `Pattern.mirror()` or `Pattern.rotate_around(...)` at the container level. ## Other user-facing changes ### DXF environments If you install the DXF extra, the supported `ezdxf` baseline moved from `~=1.0.2` to `~=1.4`. Any pinned environments should be updated accordingly. ### New exports These are additive, but available now from `masque` and `masque.builder`: - `PortPather` - `SimpleTool` - `AutoTool` - `boolean` ## Minimal migration checklist If your code uses the routing stack, do these first: 1. Replace `path`/`path_to`/`mpath`/`path_into` calls with `trace`/`trace_to`/multi-port `trace`/`trace_into`. 2. Replace `BasicTool` with `SimpleTool` or `AutoTool`. 3. Fix imports that still reference `masque.builder.builder` or `masque.builder.renderpather`. 4. Audit any low-level `mirror()` usage, especially on `Port` and `Ref`. If your code only uses `Pattern`, `Library`, `place()`, and `plug()` without the routing helpers, you may not need any changes beyond the transform audit and any stale imports.