physdes-py 0.6__tar.gz → 0.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. {physdes_py-0.6 → physdes_py-0.7}/.gitignore +4 -0
  2. physdes_py-0.7/CHANGELOG.md +16 -0
  3. {physdes_py-0.6/src/physdes_py.egg-info → physdes_py-0.7}/PKG-INFO +1 -2
  4. {physdes_py-0.6 → physdes_py-0.7}/docs/build_from_md.py +17 -15
  5. {physdes_py-0.6 → physdes_py-0.7}/docs/build_remark.py +28 -21
  6. {physdes_py-0.6 → physdes_py-0.7}/docs/build_slides.py +32 -24
  7. {physdes_py-0.6 → physdes_py-0.7}/docs/examples/plot_cts.py +10 -4
  8. {physdes_py-0.6 → physdes_py-0.7}/docs/examples/plot_global_router.py +24 -7
  9. {physdes_py-0.6 → physdes_py-0.7}/docs/examples/plot_rectangles.py +2 -1
  10. {physdes_py-0.6 → physdes_py-0.7}/docs/examples/plot_rpolygon.py +1 -0
  11. {physdes_py-0.6 → physdes_py-0.7}/my_congestion.svg +1 -1
  12. physdes_py-0.7/mypy.ini +6 -0
  13. {physdes_py-0.6 → physdes_py-0.7}/setup.cfg +0 -1
  14. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/__init__.py +1 -8
  15. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/cts/dme_algorithm.py +178 -348
  16. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/manhattan_arc.py +1 -29
  17. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/point.py +1 -2
  18. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/polygon.py +1 -2
  19. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/recti.py +3 -7
  20. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/router/routing_tree.py +33 -33
  21. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/router/routing_tree3d.tpy +27 -27
  22. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/router/routing_visualizer.py +6 -6
  23. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/rpolygon.py +1 -26
  24. physdes_py-0.7/src/physdes/skeleton.py +3 -0
  25. {physdes_py-0.6 → physdes_py-0.7/src/physdes_py.egg-info}/PKG-INFO +1 -2
  26. {physdes_py-0.6 → physdes_py-0.7}/src/physdes_py.egg-info/SOURCES.txt +3 -2
  27. {physdes_py-0.6 → physdes_py-0.7}/src/physdes_py.egg-info/requires.txt +0 -3
  28. physdes_py-0.7/src/physdes_py.egg-info/scm_file_list.json +246 -0
  29. physdes_py-0.7/src/physdes_py.egg-info/scm_version.json +8 -0
  30. {physdes_py-0.6 → physdes_py-0.7}/tests/test_dme_algorithm.py +70 -144
  31. {physdes_py-0.6 → physdes_py-0.7}/tests/test_global_router3d_with_keepouts.py +3 -3
  32. {physdes_py-0.6 → physdes_py-0.7}/tests/test_routing_tree.py +68 -68
  33. physdes_py-0.6/mypy.ini +0 -21
  34. physdes_py-0.6/mypy_test_errors.txt +0 -50
  35. physdes_py-0.6/src/physdes/skeleton.py +0 -169
  36. physdes_py-0.6/tests/test_skeleton.py +0 -36
  37. {physdes_py-0.6 → physdes_py-0.7}/.benchmarks/test_area.py +0 -0
  38. {physdes_py-0.6 → physdes_py-0.7}/.coveragerc +0 -0
  39. {physdes_py-0.6 → physdes_py-0.7}/.flake8 +0 -0
  40. {physdes_py-0.6 → physdes_py-0.7}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  41. {physdes_py-0.6 → physdes_py-0.7}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  42. {physdes_py-0.6 → physdes_py-0.7}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  43. {physdes_py-0.6 → physdes_py-0.7}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  44. {physdes_py-0.6 → physdes_py-0.7}/.github/workflows/jekyll-gh-pages.yml +0 -0
  45. {physdes_py-0.6 → physdes_py-0.7}/.github/workflows/multi-platforms.yml +0 -0
  46. {physdes_py-0.6 → physdes_py-0.7}/.github/workflows/python-app.yml +0 -0
  47. {physdes_py-0.6 → physdes_py-0.7}/.github/workflows/python-publish.yml +0 -0
  48. {physdes_py-0.6 → physdes_py-0.7}/.gitpod.Dockerfile +0 -0
  49. {physdes_py-0.6 → physdes_py-0.7}/.gitpod.yml +0 -0
  50. {physdes_py-0.6 → physdes_py-0.7}/.hadolint.yaml +0 -0
  51. {physdes_py-0.6 → physdes_py-0.7}/.isort.cfg +0 -0
  52. {physdes_py-0.6 → physdes_py-0.7}/.markdownlint.yaml +0 -0
  53. {physdes_py-0.6 → physdes_py-0.7}/.pre-commit-config.yaml +0 -0
  54. {physdes_py-0.6 → physdes_py-0.7}/.readthedocs.yml +0 -0
  55. {physdes_py-0.6 → physdes_py-0.7}/.shellcheckrc +0 -0
  56. {physdes_py-0.6 → physdes_py-0.7}/AGENTS.md +0 -0
  57. {physdes_py-0.6 → physdes_py-0.7}/AUTHORS.rst +0 -0
  58. {physdes_py-0.6 → physdes_py-0.7}/CHANGELOG.rst +0 -0
  59. {physdes_py-0.6 → physdes_py-0.7}/CONTRIBUTING.rst +0 -0
  60. {physdes_py-0.6 → physdes_py-0.7}/GEMINI.md +0 -0
  61. {physdes_py-0.6 → physdes_py-0.7}/LICENSE +0 -0
  62. {physdes_py-0.6 → physdes_py-0.7}/README.md +0 -0
  63. {physdes_py-0.6 → physdes_py-0.7}/_config.yml +0 -0
  64. {physdes_py-0.6 → physdes_py-0.7}/alpha10.svg +0 -0
  65. {physdes_py-0.6 → physdes_py-0.7}/alpha12.svg +0 -0
  66. {physdes_py-0.6 → physdes_py-0.7}/alpha14.svg +0 -0
  67. {physdes_py-0.6 → physdes_py-0.7}/alpha8.svg +0 -0
  68. {physdes_py-0.6 → physdes_py-0.7}/alpha9998.svg +0 -0
  69. {physdes_py-0.6 → physdes_py-0.7}/changelog/1.misc.rst +0 -0
  70. {physdes_py-0.6 → physdes_py-0.7}/changelog/README.md +0 -0
  71. {physdes_py-0.6 → physdes_py-0.7}/coverage.json +0 -0
  72. {physdes_py-0.6 → physdes_py-0.7}/demo_overlap.py +0 -0
  73. {physdes_py-0.6 → physdes_py-0.7}/demo_overlap.svg +0 -0
  74. {physdes_py-0.6 → physdes_py-0.7}/diagram.bob +0 -0
  75. {physdes_py-0.6 → physdes_py-0.7}/dme_algorithm-slides.html +0 -0
  76. {physdes_py-0.6 → physdes_py-0.7}/dme_algorithm-slides.md +0 -0
  77. {physdes_py-0.6 → physdes_py-0.7}/docs/Makefile +0 -0
  78. {physdes_py-0.6 → physdes_py-0.7}/docs/_static/.gitignore +0 -0
  79. {physdes_py-0.6 → physdes_py-0.7}/docs/authors.rst +0 -0
  80. {physdes_py-0.6 → physdes_py-0.7}/docs/changelog.rst +0 -0
  81. {physdes_py-0.6 → physdes_py-0.7}/docs/conf.py +0 -0
  82. {physdes_py-0.6 → physdes_py-0.7}/docs/contributing.md +0 -0
  83. {physdes_py-0.6 → physdes_py-0.7}/docs/contributing.rst +0 -0
  84. {physdes_py-0.6 → physdes_py-0.7}/docs/essays/essay.md +0 -0
  85. {physdes_py-0.6 → physdes_py-0.7}/docs/essays/polygon_vs_rpolygon_comparison.html +0 -0
  86. {physdes_py-0.6 → physdes_py-0.7}/docs/essays/polygon_vs_rpolygon_comparison.md +0 -0
  87. {physdes_py-0.6 → physdes_py-0.7}/docs/figures_demo.rst +0 -0
  88. {physdes_py-0.6 → physdes_py-0.7}/docs/index.rst +0 -0
  89. {physdes_py-0.6 → physdes_py-0.7}/docs/license.rst +0 -0
  90. {physdes_py-0.6 → physdes_py-0.7}/docs/misc/note.md +0 -0
  91. {physdes_py-0.6 → physdes_py-0.7}/docs/misc/report.md +0 -0
  92. {physdes_py-0.6 → physdes_py-0.7}/docs/my_congestion.svg +0 -0
  93. {physdes_py-0.6 → physdes_py-0.7}/docs/proposals/fyproj2026.md +0 -0
  94. {physdes_py-0.6 → physdes_py-0.7}/docs/proposals/fyproj2026.md.bad +0 -0
  95. {physdes_py-0.6 → physdes_py-0.7}/docs/proposals/fyproj2026_cts.md +0 -0
  96. {physdes_py-0.6 → physdes_py-0.7}/docs/proposals/fyproj2026_cts_2d.md +0 -0
  97. {physdes_py-0.6 → physdes_py-0.7}/docs/proposals/mulit-fpga-routing.md +0 -0
  98. {physdes_py-0.6 → physdes_py-0.7}/docs/readme.rst +0 -0
  99. {physdes_py-0.6 → physdes_py-0.7}/docs/requirements.txt +0 -0
  100. {physdes_py-0.6 → physdes_py-0.7}/docs/slides_content.md +0 -0
  101. {physdes_py-0.6 → physdes_py-0.7}/docs/steiner_forest_diagonal.svg +0 -0
  102. {physdes_py-0.6 → physdes_py-0.7}/environment.yml +0 -0
  103. {physdes_py-0.6 → physdes_py-0.7}/example_route3d_with_constraint_and_keepouts.svg +0 -0
  104. {physdes_py-0.6 → physdes_py-0.7}/example_route3d_with_steiner_and_keepouts.svg +0 -0
  105. {physdes_py-0.6 → physdes_py-0.7}/example_route_with_delay_constraint.svg +0 -0
  106. {physdes_py-0.6 → physdes_py-0.7}/example_route_with_keepouts.svg +0 -0
  107. {physdes_py-0.6 → physdes_py-0.7}/example_route_with_steiner.svg +0 -0
  108. {physdes_py-0.6 → physdes_py-0.7}/example_route_with_steiner_and_keepouts.svg +0 -0
  109. {physdes_py-0.6 → physdes_py-0.7}/example_route_with_steiner_special.svg +0 -0
  110. {physdes_py-0.6 → physdes_py-0.7}/examples/steiner_forest_grid_example.py +0 -0
  111. {physdes_py-0.6 → physdes_py-0.7}/examples/steiner_forest_grid_large_example.py +0 -0
  112. {physdes_py-0.6 → physdes_py-0.7}/examples/steiner_forest_simple_example.py +0 -0
  113. {physdes_py-0.6 → physdes_py-0.7}/experimental/distance_comparison.png +0 -0
  114. {physdes_py-0.6 → physdes_py-0.7}/experimental/rectilinear_distance_field.png +0 -0
  115. {physdes_py-0.6 → physdes_py-0.7}/experimental/rectilinear_voronoi.ipynb +0 -0
  116. {physdes_py-0.6 → physdes_py-0.7}/experimental/rectilinear_voronoi.py +0 -0
  117. {physdes_py-0.6 → physdes_py-0.7}/experimental/rectilinear_voronoi_diamond.png +0 -0
  118. {physdes_py-0.6 → physdes_py-0.7}/experimental/rectilinear_voronoi_grid.png +0 -0
  119. {physdes_py-0.6 → physdes_py-0.7}/experimental/rectilinear_voronoi_random.png +0 -0
  120. {physdes_py-0.6 → physdes_py-0.7}/experimental/steiner_trees_demo.py +0 -0
  121. {physdes_py-0.6 → physdes_py-0.7}/global_router-slides.html +0 -0
  122. {physdes_py-0.6 → physdes_py-0.7}/global_router-slides.md +0 -0
  123. {physdes_py-0.6 → physdes_py-0.7}/neg_specical10.svg +0 -0
  124. {physdes_py-0.6 → physdes_py-0.7}/oryx-build-commands.txt +0 -0
  125. {physdes_py-0.6 → physdes_py-0.7}/outputs/comparison.svg +0 -0
  126. {physdes_py-0.6 → physdes_py-0.7}/outputs/convex_hull.svg +0 -0
  127. {physdes_py-0.6 → physdes_py-0.7}/outputs/delay_model_comparison.svg +0 -0
  128. {physdes_py-0.6 → physdes_py-0.7}/outputs/delay_model_comparison3d.svg +0 -0
  129. {physdes_py-0.6 → physdes_py-0.7}/outputs/elmore_model_clock_tree.svg +0 -0
  130. {physdes_py-0.6 → physdes_py-0.7}/outputs/elmore_model_clock_tree3d.svg +0 -0
  131. {physdes_py-0.6 → physdes_py-0.7}/outputs/example_route3d_with_constraint.svg +0 -0
  132. {physdes_py-0.6 → physdes_py-0.7}/outputs/example_route3d_with_constraint_and_keepouts.svg +0 -0
  133. {physdes_py-0.6 → physdes_py-0.7}/outputs/example_route3d_with_steiner.svg +0 -0
  134. {physdes_py-0.6 → physdes_py-0.7}/outputs/example_route3d_with_steiner_and_keepouts.svg +0 -0
  135. {physdes_py-0.6 → physdes_py-0.7}/outputs/example_route_with_constraint.svg +0 -0
  136. {physdes_py-0.6 → physdes_py-0.7}/outputs/example_route_with_constraint_specical.svg +0 -0
  137. {physdes_py-0.6 → physdes_py-0.7}/outputs/example_route_with_delay_constraint.svg +0 -0
  138. {physdes_py-0.6 → physdes_py-0.7}/outputs/example_route_with_keepouts.svg +0 -0
  139. {physdes_py-0.6 → physdes_py-0.7}/outputs/example_route_with_steiner.svg +0 -0
  140. {physdes_py-0.6 → physdes_py-0.7}/outputs/example_route_with_steiner_and_keepouts.svg +0 -0
  141. {physdes_py-0.6 → physdes_py-0.7}/outputs/example_route_with_steiner_special.svg +0 -0
  142. {physdes_py-0.6 → physdes_py-0.7}/outputs/linear_model_clock_tree.svg +0 -0
  143. {physdes_py-0.6 → physdes_py-0.7}/outputs/linear_model_clock_tree3d.svg +0 -0
  144. {physdes_py-0.6 → physdes_py-0.7}/outputs/my_congestion.svg +0 -0
  145. {physdes_py-0.6 → physdes_py-0.7}/outputs/neg_specical10.svg +0 -0
  146. {physdes_py-0.6 → physdes_py-0.7}/outputs/polygon_convex_hull.svg +0 -0
  147. {physdes_py-0.6 → physdes_py-0.7}/outputs/polygon_convex_hull13.svg +0 -0
  148. {physdes_py-0.6 → physdes_py-0.7}/outputs/rectilinear-shapes-for-vlsi-physical-desgin.svg +0 -0
  149. {physdes_py-0.6 → physdes_py-0.7}/outputs/rpolygon_convex_cut.svg +0 -0
  150. {physdes_py-0.6 → physdes_py-0.7}/outputs/rpolygon_cut_explicit.svg +0 -0
  151. {physdes_py-0.6 → physdes_py-0.7}/outputs/rpolyon_convex_hull.svg +0 -0
  152. {physdes_py-0.6 → physdes_py-0.7}/outputs/rpolyon_convex_hull13.svg +0 -0
  153. {physdes_py-0.6 → physdes_py-0.7}/outputs/rpolyon_cut_convex.svg +0 -0
  154. {physdes_py-0.6 → physdes_py-0.7}/outputs/rpolyon_cut_convex2.svg +0 -0
  155. {physdes_py-0.6 → physdes_py-0.7}/outputs/rpolyon_xmono.svg +0 -0
  156. {physdes_py-0.6 → physdes_py-0.7}/outputs/rpolyon_xmono_hull.svg +0 -0
  157. {physdes_py-0.6 → physdes_py-0.7}/outputs/rpolyon_ymono_hull.svg +0 -0
  158. {physdes_py-0.6 → physdes_py-0.7}/outputs/steiner_forest.svg +0 -0
  159. {physdes_py-0.6 → physdes_py-0.7}/outputs/steiner_forest_diagonal.svg +0 -0
  160. {physdes_py-0.6 → physdes_py-0.7}/outputs/test.svg +0 -0
  161. {physdes_py-0.6 → physdes_py-0.7}/outputs/xmono_hull.svg +0 -0
  162. {physdes_py-0.6 → physdes_py-0.7}/plot_alpha.py +0 -0
  163. {physdes_py-0.6 → physdes_py-0.7}/presentation_overlap_detection.html +0 -0
  164. {physdes_py-0.6 → physdes_py-0.7}/presentation_overlap_detection.md +0 -0
  165. {physdes_py-0.6 → physdes_py-0.7}/pyproject.toml +0 -0
  166. {physdes_py-0.6 → physdes_py-0.7}/requirements/README.md +0 -0
  167. {physdes_py-0.6 → physdes_py-0.7}/requirements/default.txt +0 -0
  168. {physdes_py-0.6 → physdes_py-0.7}/requirements/dev.txt +0 -0
  169. {physdes_py-0.6 → physdes_py-0.7}/requirements/doc.txt +0 -0
  170. {physdes_py-0.6 → physdes_py-0.7}/requirements/extras.txt +0 -0
  171. {physdes_py-0.6 → physdes_py-0.7}/requirements/test.txt +0 -0
  172. {physdes_py-0.6 → physdes_py-0.7}/requirements.txt +0 -0
  173. {physdes_py-0.6 → physdes_py-0.7}/rpolygon-slides.html +0 -0
  174. {physdes_py-0.6 → physdes_py-0.7}/rpolygon-slides.md +0 -0
  175. {physdes_py-0.6 → physdes_py-0.7}/setup.py +0 -0
  176. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/cts/clk_tree3d_vis.py +0 -0
  177. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/cts/clk_tree_vis.py +0 -0
  178. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/generic.py +0 -0
  179. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/generic.tpy +0 -0
  180. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/interval.py +0 -0
  181. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/manhattan_arc_3d.py +0 -0
  182. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/manhattan_arc_3d.tpy +0 -0
  183. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/point.tpy +0 -0
  184. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/py.typed +0 -0
  185. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/rdllist.py +0 -0
  186. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/router/global_router.py +0 -0
  187. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/router/global_router3d.tpy +0 -0
  188. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/router/steiner_forest.md +0 -0
  189. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/rpolygon_cut.py +0 -0
  190. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/steiner_forest/congestion_map.py +0 -0
  191. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/steiner_forest/my_congestion.svg +0 -0
  192. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/steiner_forest/steiner_forest.md +0 -0
  193. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/steiner_forest/steiner_forest.svg +0 -0
  194. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/steiner_forest/steiner_forest_diagonal.svg +0 -0
  195. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/steiner_forest/steiner_forest_grid.py +0 -0
  196. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/to_polygon.py +0 -0
  197. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/vector2.py +0 -0
  198. {physdes_py-0.6 → physdes_py-0.7}/src/physdes/vector2.tpy +0 -0
  199. {physdes_py-0.6 → physdes_py-0.7}/src/physdes_py.egg-info/dependency_links.txt +0 -0
  200. {physdes_py-0.6 → physdes_py-0.7}/src/physdes_py.egg-info/not-zip-safe +0 -0
  201. {physdes_py-0.6 → physdes_py-0.7}/src/physdes_py.egg-info/top_level.txt +0 -0
  202. {physdes_py-0.6 → physdes_py-0.7}/svgo.config.js +0 -0
  203. {physdes_py-0.6 → physdes_py-0.7}/test.svg +0 -0
  204. {physdes_py-0.6 → physdes_py-0.7}/tests/__init__.py +0 -0
  205. {physdes_py-0.6 → physdes_py-0.7}/tests/conftest.py +0 -0
  206. {physdes_py-0.6 → physdes_py-0.7}/tests/golden.txt +0 -0
  207. {physdes_py-0.6 → physdes_py-0.7}/tests/mysvg.css +0 -0
  208. {physdes_py-0.6 → physdes_py-0.7}/tests/pnrpoly.svg +0 -0
  209. {physdes_py-0.6 → physdes_py-0.7}/tests/run_failing_tests.py +0 -0
  210. {physdes_py-0.6 → physdes_py-0.7}/tests/test_alpha.py +0 -0
  211. {physdes_py-0.6 → physdes_py-0.7}/tests/test_clk_tree_vis.py +0 -0
  212. {physdes_py-0.6 → physdes_py-0.7}/tests/test_generic_functions.py +0 -0
  213. {physdes_py-0.6 → physdes_py-0.7}/tests/test_global_router.py +0 -0
  214. {physdes_py-0.6 → physdes_py-0.7}/tests/test_global_router3d.py +0 -0
  215. {physdes_py-0.6 → physdes_py-0.7}/tests/test_global_router3d.tpy +0 -0
  216. {physdes_py-0.6 → physdes_py-0.7}/tests/test_global_router3d_with_keepouts2.py +0 -0
  217. {physdes_py-0.6 → physdes_py-0.7}/tests/test_global_router_logic.py +0 -0
  218. {physdes_py-0.6 → physdes_py-0.7}/tests/test_global_router_logic3d.tpy +0 -0
  219. {physdes_py-0.6 → physdes_py-0.7}/tests/test_global_router_with_keepouts.py +0 -0
  220. {physdes_py-0.6 → physdes_py-0.7}/tests/test_global_router_with_keepouts2.py +0 -0
  221. {physdes_py-0.6 → physdes_py-0.7}/tests/test_interval.py +0 -0
  222. {physdes_py-0.6 → physdes_py-0.7}/tests/test_manhattan_arc_3d.py +0 -0
  223. {physdes_py-0.6 → physdes_py-0.7}/tests/test_manhattan_arc_3d.tpy +0 -0
  224. {physdes_py-0.6 → physdes_py-0.7}/tests/test_merge.py +0 -0
  225. {physdes_py-0.6 → physdes_py-0.7}/tests/test_merge3d.tpy +0 -0
  226. {physdes_py-0.6 → physdes_py-0.7}/tests/test_nearest_point_to.tpy +0 -0
  227. {physdes_py-0.6 → physdes_py-0.7}/tests/test_overlap.py +0 -0
  228. {physdes_py-0.6 → physdes_py-0.7}/tests/test_point.py +0 -0
  229. {physdes_py-0.6 → physdes_py-0.7}/tests/test_point_extended.py +0 -0
  230. {physdes_py-0.6 → physdes_py-0.7}/tests/test_point_hypothesis.py +0 -0
  231. {physdes_py-0.6 → physdes_py-0.7}/tests/test_polygon.py +0 -0
  232. {physdes_py-0.6 → physdes_py-0.7}/tests/test_polygon.svg +0 -0
  233. {physdes_py-0.6 → physdes_py-0.7}/tests/test_polygon_convex_decomposition.py +0 -0
  234. {physdes_py-0.6 → physdes_py-0.7}/tests/test_polygon_hypothesis.py +0 -0
  235. {physdes_py-0.6 → physdes_py-0.7}/tests/test_rdllist.py +0 -0
  236. {physdes_py-0.6 → physdes_py-0.7}/tests/test_rect3d.py +0 -0
  237. {physdes_py-0.6 → physdes_py-0.7}/tests/test_recti.py +0 -0
  238. {physdes_py-0.6 → physdes_py-0.7}/tests/test_recti_hypothesis.py +0 -0
  239. {physdes_py-0.6 → physdes_py-0.7}/tests/test_routing_tree3d.tpy +0 -0
  240. {physdes_py-0.6 → physdes_py-0.7}/tests/test_routing_visualizer.py +0 -0
  241. {physdes_py-0.6 → physdes_py-0.7}/tests/test_rpolygon.py +0 -0
  242. {physdes_py-0.6 → physdes_py-0.7}/tests/test_rpolygon_convex_cut.py +0 -0
  243. {physdes_py-0.6 → physdes_py-0.7}/tests/test_rpolygon_convex_hull.py +0 -0
  244. {physdes_py-0.6 → physdes_py-0.7}/tests/test_rpolygon_cut.py +0 -0
  245. {physdes_py-0.6 → physdes_py-0.7}/tests/test_steiner_forest_grid.py +0 -0
  246. {physdes_py-0.6 → physdes_py-0.7}/tests/test_to_polygon.py +0 -0
  247. {physdes_py-0.6 → physdes_py-0.7}/tests/test_vector2.py +0 -0
  248. {physdes_py-0.6 → physdes_py-0.7}/tests/test_vector2_hypothesis.py +0 -0
  249. {physdes_py-0.6 → physdes_py-0.7}/tests/xmono_polygon.svg +0 -0
  250. {physdes_py-0.6 → physdes_py-0.7}/tests/xmono_polygon2.svg +0 -0
  251. {physdes_py-0.6 → physdes_py-0.7}/tests/ymono_polygon.svg +0 -0
  252. {physdes_py-0.6 → physdes_py-0.7}/tests/ymono_rpolygon.svg +0 -0
  253. {physdes_py-0.6 → physdes_py-0.7}/tox.ini +0 -0
  254. {physdes_py-0.6 → physdes_py-0.7}/wirelength_vs_alpha.png +0 -0
  255. {physdes_py-0.6 → physdes_py-0.7}/wirelength_vs_alpha_small.png +0 -0
@@ -185,3 +185,7 @@ mypy_error.log
185
185
  # Build artifacts
186
186
  diagram.bob
187
187
  oryx-build-commands.txt
188
+
189
+ # Cache dirs
190
+ .ruff_cache/
191
+ .benchmarks/
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ ## Version 0.7 (2026-07-16)
4
+
5
+ ### Performance
6
+ - **`__slots__` on core geometry classes**: Added `__slots__` to `Point`, `ManhattanArc`, `Polygon`, `RPolygon`, `TreeNode`, `Sink` — saving ~176 bytes per instance. Most impactful on `Point` which is used everywhere in the codebase. (#64242a6)
7
+
8
+ ### Bug Fixes
9
+ - **DME alignment with Rust**: Fixed elongation calculation with `raw_extend_left` to match Rust/C++. Replaced `sorted()` with median-partition in `build_merging_tree` (matches Rust `nth_element`). (#0267be3)
10
+ - **NodeType rename**: Changed `ALL_CAPS` enum values to `PascalCase` to align with Rust naming conventions. (#0267be3)
11
+
12
+ ### Documentation
13
+ - **Doc build scripts**: Updated remark and slide build scripts. Updated example plot scripts for RPolygon, CTS, and global router. (#0a613b3)
14
+
15
+ ### Code Cleanup
16
+ - **Removed PyScaffold boilerplate**: Deleted `skeleton.py`/`test_skeleton.py`, removed Python < 3.9 compat, unused mypy ignores, stale files. (#e594991)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: physdes-py
3
- Version: 0.6
3
+ Version: 0.7
4
4
  Summary: Physical Design Python Code
5
5
  Home-page: https://github.com/luk036/physdes-py/
6
6
  Author: Wai-Shing Luk
@@ -11,7 +11,6 @@ Platform: any
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Programming Language :: Python
13
13
  Description-Content-Type: text/markdown; charset=UTF-8
14
- Requires-Dist: importlib-metadata; python_version < "3.9"
15
14
  Requires-Dist: typing_extensions
16
15
  Requires-Dist: mywheel
17
16
  Requires-Dist: icecream
@@ -4,31 +4,33 @@ Run: python build_from_md.py
4
4
  """
5
5
  import re
6
6
 
7
- with open('D:/github/py/physdes-py/docs/slides_content.md', 'r', encoding='utf-8') as f:
7
+ with open("D:/github/py/physdes-py/docs/slides_content.md", encoding="utf-8") as f:
8
8
  md = f.read()
9
9
 
10
10
  # Split into slides
11
- slides = [s.strip() for s in re.split(r'\n---\n', md) if s.strip()]
11
+ slides = [s.strip() for s in re.split(r"\n---\n", md) if s.strip()]
12
12
 
13
13
  # Annotate slides
14
14
  annotated = []
15
15
  for i, slide in enumerate(slides):
16
- first_line = slide.split('\n')[0]
17
- is_qa = '❓ Questions' in first_line
18
- is_end = '🙏 Thank You' in first_line
16
+ first_line = slide.split("\n")[0]
17
+ is_qa = "❓ Questions" in first_line
18
+ is_end = "🙏 Thank You" in first_line
19
19
  if i == 0 or is_qa or is_end:
20
- annotated.append(f'count: false\nclass: nord-dark, middle, center\n\n{slide}')
21
- elif first_line.startswith('## 🐍'):
22
- annotated.append(f'class: nord-light, middle, center\n\n{slide}')
20
+ annotated.append(f"count: false\nclass: nord-dark, middle, center\n\n{slide}")
21
+ elif first_line.startswith("## 🐍"):
22
+ annotated.append(f"class: nord-light, middle, center\n\n{slide}")
23
23
  else:
24
24
  annotated.append(slide)
25
25
 
26
- remark_content = 'layout: true\nclass: typo, typo-selection\n\n---\n' + '\n\n---\n\n'.join(annotated)
26
+ remark_content = (
27
+ "layout: true\nclass: typo, typo-selection\n\n---\n" + "\n\n---\n\n".join(annotated)
28
+ )
27
29
 
28
30
  # Escape for HTML textarea
29
- remark_content = remark_content.replace('</textarea>', '&lt;/textarea&gt;')
31
+ remark_content = remark_content.replace("</textarea>", "&lt;/textarea&gt;")
30
32
 
31
- html = f'''<!doctype html>
33
+ html = f"""<!doctype html>
32
34
  <html>
33
35
  <head>
34
36
  <title>Embedding Figures in Docs — Python &amp; Rust</title>
@@ -75,10 +77,10 @@ html = f'''<!doctype html>
75
77
  </script>
76
78
  <script src="../js/mermaid-init.js"></script>
77
79
  </body>
78
- </html>'''
80
+ </html>"""
79
81
 
80
- out = 'D:/github/luk036.github.io/idea/doc-fig-py-remark-v2.html'
81
- with open(out, 'w', encoding='utf-8') as f:
82
+ out = "D:/github/luk036.github.io/idea/doc-fig-py-remark-v2.html"
83
+ with open(out, "w", encoding="utf-8") as f:
82
84
  f.write(html)
83
85
 
84
- print(f'Written {len(html)} bytes, {len(slides)} slides to {out}')
86
+ print(f"Written {len(html)} bytes, {len(slides)} slides to {out}")
@@ -4,7 +4,8 @@ Run: python build_remark.py
4
4
  """
5
5
  import re
6
6
 
7
- MD = r'''layout: true
7
+ MD = (
8
+ r'''layout: true
8
9
  class: typo, typo-selection
9
10
 
10
11
  ---
@@ -249,12 +250,13 @@ docs/_build/html/ target/doc/my_crate/
249
250
  .. svgbob::
250
251
  :align: center
251
252
 
252
- _.-'''''''-._
253
+ _.-'''
254
+ """'-._
253
255
  ,' | `.
254
256
  / | \
255
257
  | | . |
256
258
  | | |
257
- \ | /
259
+ \\ | /
258
260
  `._ | _.'
259
261
  '-......-'
260
262
  ```
@@ -294,12 +296,12 @@ docs/_build/html/ target/doc/my_crate/
294
296
  ```rst
295
297
  .. math::
296
298
 
297
- \phi_b(n) =
298
- \sum_{k=0}^{m} \frac{d_k}{b^{k+1}}
299
+ \\phi_b(n) =
300
+ \\sum_{k=0}^{m} \frac{d_k}{b^{k+1}}
299
301
  ```
300
302
 
301
303
  ```rst
302
- Inline :math:`\phi_2(n)` works too.
304
+ Inline :math:`\\phi_2(n)` works too.
303
305
  ```
304
306
 
305
307
  ✅ `.. math::` display equations
@@ -316,9 +318,9 @@ Inline :math:`\phi_2(n)` works too.
316
318
 
317
319
  ```rust
318
320
  //! Display:
319
- //! $$ \phi_b(n) = \sum_{k=0}^{m} \frac{d_k}{b^{k+1}} $$
321
+ //! $$ \\phi_b(n) = \\sum_{k=0}^{m} \frac{d_k}{b^{k+1}} $$
320
322
  //!
321
- //! Inline: $ \phi_2(n) $
323
+ //! Inline: $ \\phi_2(n) $
322
324
  ```
323
325
 
324
326
  ✅ `$$...$$` display equations
@@ -578,27 +580,30 @@ class: nord-dark, middle, center
578
580
  - [`github.com/luk036/ellalgo`](https://github.com/luk036/ellalgo)
579
581
 
580
582
  @luk036 👨‍💻 · 2026 📅
581
- '''
583
+ """
584
+ )
582
585
 
583
586
  # Split into slides
584
- slides = [s.strip() for s in re.split(r'\n---\n', MD) if s.strip()]
587
+ slides = [s.strip() for s in re.split(r"\n---\n", MD) if s.strip()]
585
588
 
586
589
  # Annotate slides
587
590
  annotated = []
588
591
  for i, slide in enumerate(slides):
589
- first_line = slide.split('\n')[0]
590
- is_qa = '❓ Questions' in first_line
591
- is_end = '🙏 Thank You' in first_line
592
+ first_line = slide.split("\n")[0]
593
+ is_qa = "❓ Questions" in first_line
594
+ is_end = "🙏 Thank You" in first_line
592
595
  if i == 0 or is_qa or is_end:
593
- annotated.append(f'count: false\nclass: nord-dark, middle, center\n\n{slide}')
594
- elif first_line.startswith('## 🐍'):
595
- annotated.append(f'class: nord-light, middle, center\n\n{slide}')
596
+ annotated.append(f"count: false\nclass: nord-dark, middle, center\n\n{slide}")
597
+ elif first_line.startswith("## 🐍"):
598
+ annotated.append(f"class: nord-light, middle, center\n\n{slide}")
596
599
  else:
597
600
  annotated.append(slide)
598
601
 
599
- remark_content = 'layout: true\nclass: typo, typo-selection\n\n---\n' + '\n\n---\n\n'.join(annotated)
602
+ remark_content = (
603
+ "layout: true\nclass: typo, typo-selection\n\n---\n" + "\n\n---\n\n".join(annotated)
604
+ )
600
605
 
601
- html = f'''<!doctype html>
606
+ html = f"""<!doctype html>
602
607
  <html>
603
608
  <head>
604
609
  <title>Embedding Figures in Docs — Python &amp; Rust</title>
@@ -645,9 +650,11 @@ html = f'''<!doctype html>
645
650
  </script>
646
651
  <script src="../js/mermaid-init.js"></script>
647
652
  </body>
648
- </html>'''
653
+ </html>"""
649
654
 
650
- with open('D:/github/luk036.github.io/idea/doc-fig-py-remark.html', 'w', encoding='utf-8') as f:
655
+ with open(
656
+ "D:/github/luk036.github.io/idea/doc-fig-py-remark.html", "w", encoding="utf-8"
657
+ ) as f:
651
658
  f.write(html)
652
659
 
653
- print(f'Written {len(html)} bytes, {len(slides)} slides')
660
+ print(f"Written {len(html)} bytes, {len(slides)} slides")
@@ -4,11 +4,14 @@ Run: python build_slides.py
4
4
  """
5
5
  import re
6
6
 
7
+
7
8
  def esc(t):
8
9
  """Escape backtick for f-string."""
9
- return t.replace('`', '\\`')
10
+ return t.replace("`", "\\`")
11
+
10
12
 
11
- MD = r'''layout: true
13
+ MD = (
14
+ r'''layout: true
12
15
  class: typo, typo-selection
13
16
 
14
17
  ---
@@ -249,12 +252,13 @@ class: nord-light, middle, center
249
252
  .. svgbobdoc::
250
253
  :align: center
251
254
 
252
- _.-'''''''-._
255
+ _.-'''
256
+ """'-._
253
257
  ,' | `.
254
258
  / | \
255
259
  | | . |
256
260
  | | |
257
- \ | /
261
+ \\ | /
258
262
  `._ | _.'
259
263
  '-......-'
260
264
  ```
@@ -271,7 +275,8 @@ class: nord-light, middle, center
271
275
 
272
276
  ```rust
273
277
  //! ```svgbobdoc
274
- //! _.-'''''''-._
278
+ //! _.-"""
279
+ """'-._
275
280
  //! ,' | `.
276
281
  //! ```
277
282
  ```
@@ -295,12 +300,12 @@ class: nord-light, middle, center
295
300
  ```rst
296
301
  .. math::
297
302
 
298
- \phi_b(n) =
299
- \sum_{k=0}^{m} \frac{d_k}{b^{k+1}}
303
+ \\phi_b(n) =
304
+ \\sum_{k=0}^{m} \frac{d_k}{b^{k+1}}
300
305
  ```
301
306
 
302
307
  ```rst
303
- Inline :math:`\phi_2(n)` works too.
308
+ Inline :math:`\\phi_2(n)` works too.
304
309
  ```
305
310
 
306
311
  ✅ `.. math::` display equations
@@ -315,9 +320,9 @@ Inline :math:`\phi_2(n)` works too.
315
320
 
316
321
  ```rust
317
322
  //! Display:
318
- //! $$ \phi_b(n) = \sum_{k=0}^{m} \frac{d_k}{b^{k+1}} $$
323
+ //! $$ \\phi_b(n) = \\sum_{k=0}^{m} \frac{d_k}{b^{k+1}} $$
319
324
  //!
320
- //! Inline: $ \phi_2(n) $
325
+ //! Inline: $ \\phi_2(n) $
321
326
  ```
322
327
 
323
328
  ✅ `$$...$$` display equations
@@ -571,27 +576,30 @@ class: nord-dark, middle, center
571
576
  - [`github.com/luk036/ellalgo`](https://github.com/luk036/ellalgo)
572
577
 
573
578
  @luk036 👨‍💻 · 2026 📅
574
- '''
579
+ """
580
+ )
575
581
 
576
582
  # Split into slides
577
- slides = [s.strip() for s in re.split(r'\n---\n', MD) if s.strip()]
583
+ slides = [s.strip() for s in re.split(r"\n---\n", MD) if s.strip()]
578
584
 
579
585
  # Annotate slides
580
586
  annotated = []
581
587
  for i, slide in enumerate(slides):
582
- first_line = slide.split('\n')[0]
583
- is_qa = '❓ Questions' in first_line
584
- is_end = '🙏 Thank You' in first_line
588
+ first_line = slide.split("\n")[0]
589
+ is_qa = "❓ Questions" in first_line
590
+ is_end = "🙏 Thank You" in first_line
585
591
  if i == 0 or is_qa or is_end:
586
- annotated.append(f'count: false\nclass: nord-dark, middle, center\n\n{slide}')
587
- elif first_line.startswith('## 🐍'):
588
- annotated.append(f'class: nord-light, middle, center\n\n{slide}')
592
+ annotated.append(f"count: false\nclass: nord-dark, middle, center\n\n{slide}")
593
+ elif first_line.startswith("## 🐍"):
594
+ annotated.append(f"class: nord-light, middle, center\n\n{slide}")
589
595
  else:
590
596
  annotated.append(slide)
591
597
 
592
- remark_content = 'layout: true\nclass: typo, typo-selection\n\n---\n' + '\n\n---\n\n'.join(annotated)
598
+ remark_content = (
599
+ "layout: true\nclass: typo, typo-selection\n\n---\n" + "\n\n---\n\n".join(annotated)
600
+ )
593
601
 
594
- html = f'''<!doctype html>
602
+ html = f"""<!doctype html>
595
603
  <html>
596
604
  <head>
597
605
  <title>Embedding Figures in Docs — Python &amp; Rust</title>
@@ -638,10 +646,10 @@ html = f'''<!doctype html>
638
646
  </script>
639
647
  <script src="../js/mermaid-init.js"></script>
640
648
  </body>
641
- </html>'''
649
+ </html>"""
642
650
 
643
- out = 'D:/github/luk036.github.io/idea/doc-fig-py-remark-v2.html'
644
- with open(out, 'w', encoding='utf-8') as f:
651
+ out = "D:/github/luk036.github.io/idea/doc-fig-py-remark-v2.html"
652
+ with open(out, "w", encoding="utf-8") as f:
645
653
  f.write(html)
646
654
 
647
- print(f'Written {len(html)} bytes, {len(slides)} slides to {out}')
655
+ print(f"Written {len(html)} bytes, {len(slides)} slides to {out}")
@@ -6,8 +6,9 @@ Clock tree built with the DME algorithm using a linear delay model.
6
6
  Sinks are green, internal nodes are blue, source is red.
7
7
  """
8
8
  import matplotlib.pyplot as plt
9
+
10
+ from physdes.cts.dme_algorithm import DMEAlgorithm, LinearDelayCalculator, Sink
9
11
  from physdes.point import Point
10
- from physdes.cts.dme_algorithm import DMEAlgorithm, Sink, LinearDelayCalculator
11
12
 
12
13
  sinks = [
13
14
  Sink("s1", Point(-100, 40), 1.0),
@@ -27,6 +28,7 @@ tree = dme.build_clock_tree()
27
28
 
28
29
  sink_positions = {(s.position.xcoord, s.position.ycoord) for s in sinks}
29
30
 
31
+
30
32
  def walk(node, depth=0):
31
33
  """Collect nodes recursively."""
32
34
  if node is None:
@@ -40,6 +42,7 @@ def walk(node, depth=0):
40
42
  edges.extend(ce)
41
43
  return nodes, edges
42
44
 
45
+
43
46
  nodes, edges = walk(tree)
44
47
 
45
48
  fig, ax = plt.subplots(figsize=(8, 7))
@@ -47,7 +50,9 @@ for parent, child in edges:
47
50
  ax.plot(
48
51
  [parent.position.xcoord, child.position.xcoord],
49
52
  [parent.position.ycoord, child.position.ycoord],
50
- color="gray", linewidth=1.5, zorder=1,
53
+ color="gray",
54
+ linewidth=1.5,
55
+ zorder=1,
51
56
  )
52
57
 
53
58
  for node, _depth in nodes:
@@ -62,8 +67,9 @@ for node, _depth in nodes:
62
67
  color, size, label = "#2196F3", 60, None
63
68
  ax.scatter(x, y, c=color, s=size, edgecolors="black", linewidths=0.8, zorder=2)
64
69
  if is_root:
65
- ax.annotate(label, (x, y), xytext=(5, 8),
66
- textcoords="offset points", fontsize=9)
70
+ ax.annotate(
71
+ label, (x, y), xytext=(5, 8), textcoords="offset points", fontsize=9
72
+ )
67
73
 
68
74
  ax.set_title("DME Clock Tree (Linear Delay Model)")
69
75
  ax.set_xlabel("x")
@@ -6,20 +6,26 @@ A routing tree built with the global router using Steiner-point
6
6
  optimisation. Source is red, Steiner nodes are blue, terminals are green.
7
7
  """
8
8
  import matplotlib.pyplot as plt
9
+
9
10
  from physdes.point import Point
10
11
  from physdes.router.global_router import GlobalRouter
11
12
  from physdes.router.routing_tree import NodeType
12
13
 
13
14
  source = Point(0, 0)
14
15
  terminals = [
15
- Point(10, 5), Point(3, 8), Point(12, 12),
16
- Point(5, -4), Point(-4, 6), Point(8, -2),
16
+ Point(10, 5),
17
+ Point(3, 8),
18
+ Point(12, 12),
19
+ Point(5, -4),
20
+ Point(-4, 6),
21
+ Point(8, -2),
17
22
  ]
18
23
 
19
24
  router = GlobalRouter(source, terminals)
20
25
  router.route_with_steiners()
21
26
  tree = router.tree
22
27
 
28
+
23
29
  def collect(node):
24
30
  """Flatten tree to (nodes, edges)."""
25
31
  nodes, edges = [node], []
@@ -30,6 +36,7 @@ def collect(node):
30
36
  edges.extend(ce)
31
37
  return nodes, edges
32
38
 
39
+
33
40
  nodes, edges = collect(tree.source)
34
41
 
35
42
  colors = {
@@ -48,17 +55,27 @@ for parent, child in edges:
48
55
  ax.plot(
49
56
  [parent.pt.xcoord, child.pt.xcoord],
50
57
  [parent.pt.ycoord, child.pt.ycoord],
51
- color="gray", linewidth=1.5, zorder=1,
58
+ color="gray",
59
+ linewidth=1.5,
60
+ zorder=1,
52
61
  )
53
62
 
54
63
  for node in nodes:
55
64
  x, y = node.pt.xcoord, node.pt.ycoord
56
- ax.scatter(x, y, c=colors[node.type], s=sizes[node.type],
57
- edgecolors="black", linewidths=0.8, zorder=2)
65
+ ax.scatter(
66
+ x,
67
+ y,
68
+ c=colors[node.type],
69
+ s=sizes[node.type],
70
+ edgecolors="black",
71
+ linewidths=0.8,
72
+ zorder=2,
73
+ )
58
74
 
59
75
  if node.type == NodeType.SOURCE:
60
- ax.annotate("Source", (x, y), xytext=(5, 8),
61
- textcoords="offset points", fontsize=9)
76
+ ax.annotate(
77
+ "Source", (x, y), xytext=(5, 8), textcoords="offset points", fontsize=9
78
+ )
62
79
 
63
80
  wl = tree.calculate_total_wirelength()
64
81
  ax.set_title(f"Global Router (Steiner) — Total wirelength: {wl:.1f}")
@@ -5,8 +5,9 @@ Rectangle overlap detection
5
5
  Several rectangles visualized with overlapping pairs highlighted in red,
6
6
  using the sweep-line algorithm from ``detect_overlap_gen``.
7
7
  """
8
- import matplotlib.pyplot as plt
9
8
  import matplotlib.patches as mpatches
9
+ import matplotlib.pyplot as plt
10
+
10
11
  from physdes.interval import Interval
11
12
  from physdes.recti import Rectangle, detect_overlap_gen
12
13
 
@@ -7,6 +7,7 @@ A rectilinear polygon is converted to a general ``Polygon`` via
7
7
  are axis-aligned, then plotted.
8
8
  """
9
9
  import matplotlib.pyplot as plt
10
+
10
11
  from physdes.point import Point
11
12
  from physdes.rpolygon import RPolygon
12
13
  from physdes.to_polygon import to_polygon
@@ -60,4 +60,4 @@
60
60
  <line x1="295" y1="180" x2="300" y2="180" stroke="black" stroke-width="1"/>
61
61
  <text x="340" y="135" font-size="12" font-family="Arial">100</text>
62
62
  <line x1="295" y1="130" x2="300" y2="130" stroke="black" stroke-width="1"/>
63
- </svg>
63
+ </svg>
@@ -0,0 +1,6 @@
1
+ [mypy]
2
+ python_version = 3.12
3
+ warn_unused_configs = True
4
+
5
+ [mypy-setuptools.*]
6
+ ignore_missing_imports = True
@@ -22,7 +22,6 @@ include_package_data = True
22
22
  package_dir =
23
23
  =src
24
24
  install_requires =
25
- importlib-metadata; python_version<"3.9"
26
25
  typing_extensions
27
26
  mywheel
28
27
  icecream
@@ -6,16 +6,9 @@ Vector2, ManhattanArc) and algorithms for clock tree synthesis (DME), global
6
6
  routing, Steiner forest construction, and polygon decomposition.
7
7
  """
8
8
 
9
- import sys
10
-
11
- if sys.version_info[:2] >= (3, 8):
12
- # TODO: Import directly (no need for conditional) when `python_requires = >= 3.9`
13
- from importlib.metadata import PackageNotFoundError, version # pragma: no cover
14
- else:
15
- from importlib_metadata import PackageNotFoundError, version # pragma: no cover
9
+ from importlib.metadata import PackageNotFoundError, version
16
10
 
17
11
  try:
18
- # Change here if project is renamed and does not equal the package name
19
12
  dist_name = "physdes-py"
20
13
  __version__ = version(dist_name)
21
14
  except PackageNotFoundError: # pragma: no cover