physdes-py 0.5__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.
- {physdes_py-0.5 → physdes_py-0.7}/.benchmarks/test_area.py +2 -2
- {physdes_py-0.5 → physdes_py-0.7}/.flake8 +1 -1
- physdes_py-0.7/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
- physdes_py-0.7/.github/ISSUE_TEMPLATE/documentation.md +29 -0
- physdes_py-0.7/.github/ISSUE_TEMPLATE/feature_request.md +25 -0
- physdes_py-0.7/.github/PULL_REQUEST_TEMPLATE.md +57 -0
- {physdes_py-0.5 → physdes_py-0.7}/.github/workflows/multi-platforms.yml +6 -7
- physdes_py-0.7/.github/workflows/python-app.yml +89 -0
- {physdes_py-0.5 → physdes_py-0.7}/.gitignore +13 -0
- {physdes_py-0.5 → physdes_py-0.7}/.pre-commit-config.yaml +2 -0
- physdes_py-0.7/AGENTS.md +273 -0
- physdes_py-0.7/CHANGELOG.md +16 -0
- physdes_py-0.7/CHANGELOG.rst +40 -0
- {physdes_py-0.5 → physdes_py-0.7}/CONTRIBUTING.rst +43 -108
- physdes_py-0.7/PKG-INFO +154 -0
- physdes_py-0.7/README.md +120 -0
- physdes_py-0.7/alpha10.svg +71 -0
- physdes_py-0.7/alpha12.svg +67 -0
- physdes_py-0.7/alpha14.svg +63 -0
- physdes_py-0.7/alpha8.svg +67 -0
- physdes_py-0.7/alpha9998.svg +71 -0
- physdes_py-0.7/changelog/1.misc.rst +14 -0
- physdes_py-0.7/changelog/README.md +25 -0
- physdes_py-0.7/coverage.json +1 -0
- physdes_py-0.7/demo_overlap.py +155 -0
- physdes_py-0.7/demo_overlap.svg +502 -0
- physdes_py-0.7/dme_algorithm-slides.html +1308 -0
- physdes_py-0.7/dme_algorithm-slides.md +993 -0
- physdes_py-0.7/docs/build_from_md.py +86 -0
- physdes_py-0.7/docs/build_remark.py +660 -0
- physdes_py-0.7/docs/build_slides.py +655 -0
- {physdes_py-0.5 → physdes_py-0.7}/docs/conf.py +67 -10
- {physdes_py-0.5 → physdes_py-0.7}/docs/contributing.md +20 -18
- physdes_py-0.7/docs/essays/essay.md +252 -0
- physdes_py-0.7/docs/essays/polygon_vs_rpolygon_comparison.html +1172 -0
- physdes_py-0.7/docs/essays/polygon_vs_rpolygon_comparison.md +830 -0
- physdes_py-0.7/docs/examples/plot_cts.py +78 -0
- physdes_py-0.7/docs/examples/plot_global_router.py +85 -0
- physdes_py-0.7/docs/examples/plot_rectangles.py +58 -0
- physdes_py-0.7/docs/examples/plot_rpolygon.py +40 -0
- physdes_py-0.7/docs/figures_demo.rst +61 -0
- {physdes_py-0.5 → physdes_py-0.7}/docs/index.rst +1 -0
- {physdes_py-0.5 → physdes_py-0.7}/docs/license.rst +1 -1
- physdes_py-0.7/docs/misc/report.md +124 -0
- physdes_py-0.7/docs/my_congestion.svg +63 -0
- physdes_py-0.7/docs/proposals/fyproj2026.md +194 -0
- physdes_py-0.7/docs/proposals/fyproj2026.md.bad +41 -0
- physdes_py-0.7/docs/proposals/fyproj2026_cts.md +220 -0
- physdes_py-0.7/docs/proposals/fyproj2026_cts_2d.md +215 -0
- physdes_py-0.7/docs/proposals/mulit-fpga-routing.md +266 -0
- physdes_py-0.7/docs/readme.rst +7 -0
- {physdes_py-0.5 → physdes_py-0.7}/docs/requirements.txt +1 -1
- physdes_py-0.7/docs/slides_content.md +654 -0
- physdes_py-0.7/docs/steiner_forest_diagonal.svg +1 -0
- {physdes_py-0.5 → physdes_py-0.7}/environment.yml +1 -0
- physdes_py-0.7/example_route3d_with_constraint_and_keepouts.svg +71 -0
- physdes_py-0.7/example_route3d_with_steiner_and_keepouts.svg +71 -0
- physdes_py-0.7/example_route_with_delay_constraint.svg +71 -0
- physdes_py-0.7/example_route_with_keepouts.svg +66 -0
- physdes_py-0.7/example_route_with_steiner.svg +63 -0
- physdes_py-0.7/example_route_with_steiner_and_keepouts.svg +66 -0
- physdes_py-0.7/example_route_with_steiner_special.svg +83 -0
- physdes_py-0.7/examples/steiner_forest_grid_example.py +77 -0
- physdes_py-0.7/examples/steiner_forest_grid_large_example.py +81 -0
- physdes_py-0.7/examples/steiner_forest_simple_example.py +81 -0
- physdes_py-0.7/experimental/distance_comparison.png +0 -0
- physdes_py-0.7/experimental/rectilinear_distance_field.png +0 -0
- physdes_py-0.7/experimental/rectilinear_voronoi.ipynb +588 -0
- physdes_py-0.7/experimental/rectilinear_voronoi.py +392 -0
- physdes_py-0.7/experimental/rectilinear_voronoi_diamond.png +0 -0
- physdes_py-0.7/experimental/rectilinear_voronoi_grid.png +0 -0
- physdes_py-0.7/experimental/rectilinear_voronoi_random.png +0 -0
- physdes_py-0.7/experimental/steiner_trees_demo.py +123 -0
- physdes_py-0.7/global_router-slides.html +1223 -0
- physdes_py-0.7/global_router-slides.md +904 -0
- physdes_py-0.7/my_congestion.svg +63 -0
- physdes_py-0.7/mypy.ini +6 -0
- physdes_py-0.7/neg_specical10.svg +103 -0
- physdes_py-0.7/outputs/comparison.svg +47 -0
- physdes_py-0.7/outputs/delay_model_comparison.svg +203 -0
- physdes_py-0.7/outputs/delay_model_comparison3d.svg +203 -0
- physdes_py-0.7/outputs/elmore_model_clock_tree.svg +105 -0
- physdes_py-0.7/outputs/elmore_model_clock_tree3d.svg +105 -0
- physdes_py-0.7/outputs/example_route3d_with_constraint.svg +75 -0
- physdes_py-0.7/outputs/example_route3d_with_constraint_and_keepouts.svg +65 -0
- physdes_py-0.7/outputs/example_route3d_with_steiner.svg +75 -0
- physdes_py-0.7/outputs/example_route3d_with_steiner_and_keepouts.svg +65 -0
- physdes_py-0.7/outputs/example_route_with_constraint.svg +75 -0
- physdes_py-0.7/outputs/example_route_with_constraint_specical.svg +103 -0
- physdes_py-0.7/outputs/example_route_with_delay_constraint.svg +71 -0
- physdes_py-0.7/outputs/example_route_with_keepouts.svg +65 -0
- physdes_py-0.7/outputs/example_route_with_steiner.svg +63 -0
- physdes_py-0.7/outputs/example_route_with_steiner_and_keepouts.svg +65 -0
- physdes_py-0.7/outputs/example_route_with_steiner_special.svg +83 -0
- physdes_py-0.7/outputs/linear_model_clock_tree.svg +105 -0
- physdes_py-0.7/outputs/linear_model_clock_tree3d.svg +105 -0
- physdes_py-0.7/outputs/my_congestion.svg +63 -0
- physdes_py-0.7/outputs/neg_specical10.svg +103 -0
- physdes_py-0.7/outputs/rpolygon_convex_cut.svg +13 -0
- physdes_py-0.7/outputs/rpolygon_cut_explicit.svg +22 -0
- physdes_py-0.7/outputs/steiner_forest.svg +1 -0
- physdes_py-0.7/outputs/steiner_forest_diagonal.svg +1 -0
- physdes_py-0.7/plot_alpha.py +33 -0
- physdes_py-0.7/presentation_overlap_detection.html +821 -0
- physdes_py-0.7/presentation_overlap_detection.md +438 -0
- physdes_py-0.7/pyproject.toml +96 -0
- {physdes_py-0.5 → physdes_py-0.7}/requirements/default.txt +2 -1
- physdes_py-0.7/requirements/dev.txt +17 -0
- physdes_py-0.7/requirements/extras.txt +1 -0
- {physdes_py-0.5 → physdes_py-0.7}/requirements/test.txt +1 -1
- physdes_py-0.7/requirements.txt +17 -0
- physdes_py-0.7/rpolygon-slides.html +1073 -0
- physdes_py-0.7/rpolygon-slides.md +862 -0
- {physdes_py-0.5 → physdes_py-0.7}/setup.cfg +12 -2
- physdes_py-0.7/src/physdes/__init__.py +17 -0
- physdes_py-0.7/src/physdes/cts/clk_tree3d_vis.py +611 -0
- physdes_py-0.7/src/physdes/cts/clk_tree_vis.py +617 -0
- physdes_py-0.7/src/physdes/cts/dme_algorithm.py +746 -0
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes/generic.py +168 -43
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes/interval.py +316 -103
- physdes_py-0.7/src/physdes/manhattan_arc.py +321 -0
- physdes_py-0.7/src/physdes/manhattan_arc_3d.py +351 -0
- physdes_py-0.7/src/physdes/manhattan_arc_3d.tpy +292 -0
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes/point.py +369 -74
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes/polygon.py +217 -109
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes/rdllist.py +66 -3
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes/recti.py +62 -34
- physdes_py-0.7/src/physdes/router/global_router.py +168 -0
- physdes_py-0.7/src/physdes/router/global_router3d.tpy +93 -0
- physdes_py-0.7/src/physdes/router/routing_tree.py +892 -0
- physdes_py-0.7/src/physdes/router/routing_tree3d.tpy +891 -0
- physdes_py-0.7/src/physdes/router/routing_visualizer.py +483 -0
- physdes_py-0.7/src/physdes/router/steiner_forest.md +204 -0
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes/rpolygon.py +302 -393
- physdes_py-0.7/src/physdes/rpolygon_cut.py +335 -0
- physdes_py-0.7/src/physdes/skeleton.py +3 -0
- physdes_py-0.7/src/physdes/steiner_forest/congestion_map.py +129 -0
- physdes_py-0.7/src/physdes/steiner_forest/my_congestion.svg +63 -0
- physdes_py-0.7/src/physdes/steiner_forest/steiner_forest.md +204 -0
- physdes_py-0.7/src/physdes/steiner_forest/steiner_forest.svg +1 -0
- physdes_py-0.7/src/physdes/steiner_forest/steiner_forest_diagonal.svg +1 -0
- physdes_py-0.7/src/physdes/steiner_forest/steiner_forest_grid.py +469 -0
- physdes_py-0.7/src/physdes/to_polygon.py +55 -0
- physdes_py-0.7/src/physdes/vector2.py +459 -0
- physdes_py-0.7/src/physdes_py.egg-info/PKG-INFO +154 -0
- physdes_py-0.7/src/physdes_py.egg-info/SOURCES.txt +250 -0
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes_py.egg-info/requires.txt +11 -2
- physdes_py-0.7/src/physdes_py.egg-info/scm_file_list.json +246 -0
- physdes_py-0.7/src/physdes_py.egg-info/scm_version.json +8 -0
- physdes_py-0.7/test.svg +35 -0
- physdes_py-0.7/tests/__init__.py +0 -0
- physdes_py-0.7/tests/conftest.py +128 -0
- physdes_py-0.7/tests/golden.txt +0 -0
- physdes_py-0.7/tests/run_failing_tests.py +16 -0
- physdes_py-0.7/tests/test_alpha.py +157 -0
- physdes_py-0.7/tests/test_clk_tree_vis.py +698 -0
- physdes_py-0.7/tests/test_dme_algorithm.py +650 -0
- physdes_py-0.7/tests/test_generic_functions.py +196 -0
- physdes_py-0.7/tests/test_global_router.py +120 -0
- physdes_py-0.7/tests/test_global_router3d.py +41 -0
- physdes_py-0.7/tests/test_global_router3d.tpy +87 -0
- physdes_py-0.7/tests/test_global_router3d_with_keepouts.py +94 -0
- physdes_py-0.7/tests/test_global_router3d_with_keepouts2.py +42 -0
- physdes_py-0.7/tests/test_global_router_logic.py +60 -0
- physdes_py-0.7/tests/test_global_router_logic3d.tpy +36 -0
- physdes_py-0.7/tests/test_global_router_with_keepouts.py +51 -0
- physdes_py-0.7/tests/test_global_router_with_keepouts2.py +49 -0
- physdes_py-0.7/tests/test_interval.py +556 -0
- physdes_py-0.7/tests/test_manhattan_arc_3d.py +336 -0
- physdes_py-0.7/tests/test_manhattan_arc_3d.tpy +155 -0
- physdes_py-0.7/tests/test_merge.py +99 -0
- physdes_py-0.7/tests/test_merge3d.tpy +66 -0
- physdes_py-0.7/tests/test_nearest_point_to.tpy +10 -0
- physdes_py-0.7/tests/test_overlap.py +10 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/test_point.py +20 -15
- physdes_py-0.7/tests/test_point_extended.py +81 -0
- physdes_py-0.7/tests/test_point_hypothesis.py +411 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/test_polygon.py +18 -67
- physdes_py-0.7/tests/test_polygon_convex_decomposition.py +174 -0
- physdes_py-0.7/tests/test_polygon_hypothesis.py +471 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/test_rdllist.py +5 -5
- {physdes_py-0.5 → physdes_py-0.7}/tests/test_rect3d.py +8 -8
- physdes_py-0.7/tests/test_recti.py +161 -0
- physdes_py-0.7/tests/test_recti_hypothesis.py +500 -0
- physdes_py-0.7/tests/test_routing_tree.py +632 -0
- physdes_py-0.7/tests/test_routing_tree3d.tpy +316 -0
- physdes_py-0.7/tests/test_routing_visualizer.py +69 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/test_rpolygon.py +81 -117
- physdes_py-0.7/tests/test_rpolygon_convex_cut.py +46 -0
- physdes_py-0.7/tests/test_rpolygon_convex_hull.py +38 -0
- physdes_py-0.7/tests/test_rpolygon_cut.py +48 -0
- physdes_py-0.7/tests/test_steiner_forest_grid.py +425 -0
- physdes_py-0.7/tests/test_to_polygon.py +29 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/test_vector2.py +5 -5
- physdes_py-0.7/tests/test_vector2_hypothesis.py +402 -0
- physdes_py-0.7/wirelength_vs_alpha.png +0 -0
- physdes_py-0.7/wirelength_vs_alpha_small.png +0 -0
- physdes_py-0.5/.github/workflows/python-app.yml +0 -48
- physdes_py-0.5/CHANGELOG.rst +0 -10
- physdes_py-0.5/LICENSE.txt +0 -21
- physdes_py-0.5/PKG-INFO +0 -55
- physdes_py-0.5/README.md +0 -29
- physdes_py-0.5/README.rst +0 -39
- physdes_py-0.5/docs/readme.rst +0 -2
- physdes_py-0.5/mypy.ini +0 -24
- physdes_py-0.5/pyproject.toml +0 -9
- physdes_py-0.5/requirements/extras.txt +0 -1
- physdes_py-0.5/requirements.txt +0 -19
- physdes_py-0.5/src/physdes/__init__.py +0 -16
- physdes_py-0.5/src/physdes/merge_obj.py +0 -274
- physdes_py-0.5/src/physdes/skeleton.py +0 -149
- physdes_py-0.5/src/physdes/vector2.py +0 -386
- physdes_py-0.5/src/physdes_py.egg-info/PKG-INFO +0 -55
- physdes_py-0.5/src/physdes_py.egg-info/SOURCES.txt +0 -109
- physdes_py-0.5/tests/conftest.py +0 -10
- physdes_py-0.5/tests/test_interval.py +0 -250
- physdes_py-0.5/tests/test_merge.py +0 -51
- physdes_py-0.5/tests/test_overlap.py +0 -10
- physdes_py-0.5/tests/test_recti.py +0 -91
- physdes_py-0.5/tests/test_rpolygon.svg +0 -4
- physdes_py-0.5/tests/test_rpolygon_convex_cut.py +0 -52
- physdes_py-0.5/tests/test_rpolygon_convex_hull.py +0 -42
- physdes_py-0.5/tests/test_skeleton.py +0 -36
- physdes_py-0.5/tests/travis_install.sh +0 -60
- {physdes_py-0.5 → physdes_py-0.7}/.coveragerc +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/.github/workflows/jekyll-gh-pages.yml +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/.github/workflows/python-publish.yml +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/.gitpod.Dockerfile +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/.gitpod.yml +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/.hadolint.yaml +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/.isort.cfg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/.markdownlint.yaml +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/.readthedocs.yml +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/.shellcheckrc +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/AUTHORS.rst +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/GEMINI.md +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/LICENSE +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/_config.yml +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/diagram.bob +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/docs/Makefile +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/docs/_static/.gitignore +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/docs/authors.rst +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/docs/changelog.rst +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/docs/contributing.rst +0 -0
- {physdes_py-0.5 → physdes_py-0.7/docs/misc}/note.md +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/oryx-build-commands.txt +0 -0
- {physdes_py-0.5 → physdes_py-0.7/outputs}/convex_hull.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/outputs/polygon_convex_hull.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/outputs/polygon_convex_hull13.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7/outputs}/rectilinear-shapes-for-vlsi-physical-desgin.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/outputs/rpolyon_convex_hull.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/outputs/rpolyon_convex_hull13.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/outputs/rpolyon_cut_convex.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/outputs/rpolyon_cut_convex2.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/outputs/rpolyon_xmono.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/outputs/rpolyon_xmono_hull.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/outputs/rpolyon_ymono_hull.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/outputs/test.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7/outputs}/xmono_hull.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/requirements/README.md +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/requirements/doc.txt +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/setup.py +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes/generic.tpy +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes/point.tpy +0 -0
- /physdes_py-0.5/tests/golden.txt → /physdes_py-0.7/src/physdes/py.typed +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes/vector2.tpy +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes_py.egg-info/dependency_links.txt +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes_py.egg-info/not-zip-safe +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/src/physdes_py.egg-info/top_level.txt +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/svgo.config.js +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/mysvg.css +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/pnrpoly.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/test_polygon.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/xmono_polygon.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/xmono_polygon2.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/ymono_polygon.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/tests/ymono_rpolygon.svg +0 -0
- {physdes_py-0.5 → physdes_py-0.7}/tox.ini +0 -0
|
@@ -16,14 +16,14 @@ def rectilinear_polygon_points():
|
|
|
16
16
|
return [Point(x, y) for x, y in RECTILINEAR_POLYGON_COORDS]
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def test_polygon_signed_area(benchmark, rectilinear_polygon_points):
|
|
19
|
+
def test_polygon_signed_area(benchmark, rectilinear_polygon_points) -> None:
|
|
20
20
|
rp = RPolygon(rectilinear_polygon_points)
|
|
21
21
|
p: Polygon = rp.to_polygon()
|
|
22
22
|
result = benchmark(lambda: p.signed_area_x2)
|
|
23
23
|
assert abs(result) == 150
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
def test_rpolygon_signed_area(benchmark, rectilinear_polygon_points):
|
|
26
|
+
def test_rpolygon_signed_area(benchmark, rectilinear_polygon_points) -> None:
|
|
27
27
|
rp = RPolygon(rectilinear_polygon_points)
|
|
28
28
|
result = benchmark(lambda: rp.signed_area)
|
|
29
29
|
assert abs(result) == 75
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: 'Create a report to help us improve'
|
|
4
|
+
title: '[BUG] <title>'
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**Describe the bug**
|
|
9
|
+
A clear and concise description of what the bug is.
|
|
10
|
+
|
|
11
|
+
**To Reproduce**
|
|
12
|
+
Steps to reproduce the behavior:
|
|
13
|
+
1. Go to '...'
|
|
14
|
+
2. Click on '....'
|
|
15
|
+
3. Scroll down to '....'
|
|
16
|
+
4. See error
|
|
17
|
+
|
|
18
|
+
**Expected behavior**
|
|
19
|
+
A clear and concise description of what you expected to happen.
|
|
20
|
+
|
|
21
|
+
**Actual behavior**
|
|
22
|
+
A clear and concise description of what actually happened.
|
|
23
|
+
|
|
24
|
+
**Screenshots**
|
|
25
|
+
If applicable, add screenshots to help explain your problem.
|
|
26
|
+
|
|
27
|
+
**Environment**
|
|
28
|
+
- OS: [e.g., Windows, macOS, Linux]
|
|
29
|
+
- Python version: [e.g., 3.8, 3.9, 3.10]
|
|
30
|
+
- physdes-py version: [e.g., 0.1.0]
|
|
31
|
+
- How did you install physdes-py?: [pip install, git clone, conda]
|
|
32
|
+
|
|
33
|
+
**Additional context**
|
|
34
|
+
Add any other context about the problem here.
|
|
35
|
+
|
|
36
|
+
**Code snippet**
|
|
37
|
+
If relevant, please provide a minimal code snippet that reproduces the issue:
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
# Your code here
|
|
41
|
+
```
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Documentation
|
|
3
|
+
about: 'Suggest improvements or report issues with documentation'
|
|
4
|
+
title: '[DOCS] <title>'
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**Describe the documentation issue**
|
|
9
|
+
A clear and concise description of what's wrong or what could be improved.
|
|
10
|
+
|
|
11
|
+
**Which documentation?**
|
|
12
|
+
Please specify which documentation has issue:
|
|
13
|
+
- README.md
|
|
14
|
+
- AGENTS.md
|
|
15
|
+
- CONTRIBUTING.rst
|
|
16
|
+
- API documentation (docs/)
|
|
17
|
+
- Other (please specify)
|
|
18
|
+
|
|
19
|
+
**What needs to be fixed/improved?**
|
|
20
|
+
Describe what's missing, unclear, or incorrect.
|
|
21
|
+
|
|
22
|
+
**Suggested fix**
|
|
23
|
+
If you have a suggestion for how to improve documentation, please describe it here.
|
|
24
|
+
|
|
25
|
+
**Screenshots (if applicable)**
|
|
26
|
+
Add screenshots to help illustrate the documentation issue.
|
|
27
|
+
|
|
28
|
+
**Additional context**
|
|
29
|
+
Add any other context about the documentation issue here.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: 'Suggest an idea for physdes-py'
|
|
4
|
+
title: '[FEATURE] <title>'
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**Is your feature request related to a problem? Please describe**
|
|
9
|
+
A clear and concise description of what problem is. Ex. I'm always frustrated when [...]
|
|
10
|
+
|
|
11
|
+
**Describe the solution you'd like**
|
|
12
|
+
A clear and concise description of what you want to happen.
|
|
13
|
+
|
|
14
|
+
**Describe alternatives you've considered**
|
|
15
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
|
16
|
+
|
|
17
|
+
**Additional context**
|
|
18
|
+
Add any other context or screenshots about the feature request here.
|
|
19
|
+
|
|
20
|
+
**Use cases**
|
|
21
|
+
Please describe specific use cases for this feature. This helps us understand how feature would be used in practice.
|
|
22
|
+
|
|
23
|
+
Example use cases:
|
|
24
|
+
- "When I'm working with X, I need Y because..."
|
|
25
|
+
- "In my project, I want to implement Z, but I can't because..."
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Pull Request
|
|
3
|
+
about: 'Create a pull request to contribute changes'
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Description
|
|
8
|
+
Please include a summary of changes and motivation behind them.
|
|
9
|
+
|
|
10
|
+
## Type of change
|
|
11
|
+
- [ ] Bug fix (non-breaking change which fixes an issue)
|
|
12
|
+
- [ ] New feature (non-breaking change which adds functionality)
|
|
13
|
+
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
|
14
|
+
- [ ] Documentation update
|
|
15
|
+
- [ ] Performance improvement
|
|
16
|
+
- [ ] Code refactoring (no functional changes, no API changes)
|
|
17
|
+
- [ ] Other (please describe):
|
|
18
|
+
|
|
19
|
+
## Related Issues
|
|
20
|
+
Fixes #<issue_number>
|
|
21
|
+
Related to #<issue_number>
|
|
22
|
+
|
|
23
|
+
## How Has This Been Tested?
|
|
24
|
+
Please describe the tests that you ran to verify your changes:
|
|
25
|
+
- [ ] Unit tests added/updated
|
|
26
|
+
- [ ] All existing tests pass
|
|
27
|
+
- [ ] Manual testing performed (describe steps)
|
|
28
|
+
- [ ] Tested on Python 3.8
|
|
29
|
+
- [ ] Tested on Python 3.9
|
|
30
|
+
- [ ] Tested on Python 3.10
|
|
31
|
+
- [ ] Tested on Python 3.11
|
|
32
|
+
- [ ] Tested on Python 3.12
|
|
33
|
+
|
|
34
|
+
## Checklist:
|
|
35
|
+
- [ ] My code follows the style guidelines of this project
|
|
36
|
+
- [ ] I have performed a self-review of my own code
|
|
37
|
+
- [ ] I have commented my code, particularly in hard-to-understand areas
|
|
38
|
+
- [ ] I have made corresponding changes to the documentation
|
|
39
|
+
- [ ] My changes generate no new warnings
|
|
40
|
+
- [ ] I have added tests that prove my fix is effective or that my feature works
|
|
41
|
+
- [ ] New and existing unit tests pass locally with my changes
|
|
42
|
+
- [ ] I have updated the CHANGELOG (if applicable) using towncrier
|
|
43
|
+
|
|
44
|
+
## Additional Notes
|
|
45
|
+
Add any other notes or context about the pull request here.
|
|
46
|
+
|
|
47
|
+
### Breaking Changes
|
|
48
|
+
If this PR introduces breaking changes, please describe them here:
|
|
49
|
+
- API changes that may break existing code
|
|
50
|
+
- Configuration changes
|
|
51
|
+
- Migration steps needed
|
|
52
|
+
|
|
53
|
+
### Performance Impact
|
|
54
|
+
If this PR affects performance, please describe:
|
|
55
|
+
- Benchmarks before
|
|
56
|
+
- Benchmarks after
|
|
57
|
+
- Performance improvements
|
|
@@ -8,10 +8,10 @@ jobs:
|
|
|
8
8
|
strategy:
|
|
9
9
|
matrix:
|
|
10
10
|
os: ["ubuntu-latest", "windows-latest"]
|
|
11
|
-
version: ["3.10", "3.
|
|
11
|
+
version: ["3.10", "3.11"]
|
|
12
12
|
steps:
|
|
13
|
-
- uses: actions/checkout@
|
|
14
|
-
- uses: conda-incubator/setup-miniconda@
|
|
13
|
+
- uses: actions/checkout@v3
|
|
14
|
+
- uses: conda-incubator/setup-miniconda@v3
|
|
15
15
|
with:
|
|
16
16
|
activate-environment: test
|
|
17
17
|
environment-file: environment.yml
|
|
@@ -31,9 +31,8 @@ jobs:
|
|
|
31
31
|
shell: bash -l {0}
|
|
32
32
|
run: |
|
|
33
33
|
conda install pytest
|
|
34
|
-
|
|
34
|
+
conda install pip
|
|
35
|
+
conda install setuptools wheel setuptools_scm
|
|
35
36
|
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
|
36
|
-
pip install
|
|
37
|
-
pip install git+https://github.com/luk036/mywheel.git
|
|
38
|
-
python setup.py develop
|
|
37
|
+
pip install -e .
|
|
39
38
|
pytest
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# This workflow will install Python dependencies, run tests and lint with multiple Python versions
|
|
2
|
+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
|
3
|
+
|
|
4
|
+
name: Python application
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [ main, dev ]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [ main, dev ]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
17
|
+
os: [ubuntu-latest]
|
|
18
|
+
|
|
19
|
+
runs-on: ${{ matrix.os }}
|
|
20
|
+
env:
|
|
21
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
27
|
+
uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: ${{ matrix.python-version }}
|
|
30
|
+
|
|
31
|
+
- name: Cache pip dependencies
|
|
32
|
+
uses: actions/cache@v4
|
|
33
|
+
with:
|
|
34
|
+
path: ~/.cache/pip
|
|
35
|
+
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
|
36
|
+
restore-keys: |
|
|
37
|
+
${{ runner.os }}-pip-
|
|
38
|
+
|
|
39
|
+
- name: Install dependencies
|
|
40
|
+
run: |
|
|
41
|
+
python -m pip install --upgrade pip
|
|
42
|
+
pip install flake8 pytest pytest-cov pytest-benchmark bandit safety
|
|
43
|
+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
|
44
|
+
pip install -e .
|
|
45
|
+
pip install pre-commit
|
|
46
|
+
# pip install mypy
|
|
47
|
+
|
|
48
|
+
- name: Lint with flake8
|
|
49
|
+
run: |
|
|
50
|
+
# stop the build if there are Python syntax errors or undefined names
|
|
51
|
+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
|
52
|
+
# exit-zero treats all errors as warnings. The GitHub editor is 188 chars wide
|
|
53
|
+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=188 --statistics
|
|
54
|
+
|
|
55
|
+
# - name: Type check with mypy
|
|
56
|
+
# run: |
|
|
57
|
+
# mypy src/physdes
|
|
58
|
+
|
|
59
|
+
# - name: Install and run pre-commit
|
|
60
|
+
# env:
|
|
61
|
+
# SKIP: no-commit-to-branch
|
|
62
|
+
# run: |
|
|
63
|
+
# pre-commit install
|
|
64
|
+
# pre-commit run --all-files --show-diff-on-failure
|
|
65
|
+
#
|
|
66
|
+
# - name: Security scan with bandit
|
|
67
|
+
# run: |
|
|
68
|
+
# bandit -r src/ -f screen
|
|
69
|
+
#
|
|
70
|
+
# - name: Security check with safety
|
|
71
|
+
# run: |
|
|
72
|
+
# safety check --full-report
|
|
73
|
+
|
|
74
|
+
- name: Test with pytest
|
|
75
|
+
run: |
|
|
76
|
+
pytest --cov=src/ --cov-report=term-missing --cov-report=xml --cov-fail-under=80 -v
|
|
77
|
+
|
|
78
|
+
- name: Run benchmarks
|
|
79
|
+
run: |
|
|
80
|
+
pytest --benchmark-only --benchmark-autosave
|
|
81
|
+
|
|
82
|
+
- name: Upload coverage to Codecov
|
|
83
|
+
uses: codecov/codecov-action@v4
|
|
84
|
+
with:
|
|
85
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
86
|
+
files: ./coverage.xml
|
|
87
|
+
flags: unittests
|
|
88
|
+
name: codecov-umbrella
|
|
89
|
+
fail_ci_if_error: true
|
|
@@ -176,3 +176,16 @@ MANIFEST
|
|
|
176
176
|
|
|
177
177
|
# my stuffs
|
|
178
178
|
.hypothesis
|
|
179
|
+
|
|
180
|
+
# Temporary log files
|
|
181
|
+
*.log
|
|
182
|
+
coverage.json
|
|
183
|
+
mypy_error.log
|
|
184
|
+
|
|
185
|
+
# Build artifacts
|
|
186
|
+
diagram.bob
|
|
187
|
+
oryx-build-commands.txt
|
|
188
|
+
|
|
189
|
+
# Cache dirs
|
|
190
|
+
.ruff_cache/
|
|
191
|
+
.benchmarks/
|
|
@@ -14,8 +14,10 @@ repos:
|
|
|
14
14
|
- id: debug-statements
|
|
15
15
|
- id: end-of-file-fixer
|
|
16
16
|
- id: requirements-txt-fixer
|
|
17
|
+
exclude: "requirements/dev[.]txt$"
|
|
17
18
|
- id: mixed-line-ending
|
|
18
19
|
args: ["--fix=auto"] # replace 'auto' with 'lf' to enforce Linux/Mac line endings or 'crlf' for Windows
|
|
20
|
+
exclude: "requirements[.]txt$"
|
|
19
21
|
|
|
20
22
|
## If you want to avoid flake8 errors due to unused vars or imports:
|
|
21
23
|
# - repo: https://github.com/myint/autoflake
|
physdes_py-0.7/AGENTS.md
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# AGENTS.md - physdes-py
|
|
2
|
+
|
|
3
|
+
This file guides agentic coding agents working in the physdes-py repository.
|
|
4
|
+
|
|
5
|
+
## Build/Lint/Test Commands
|
|
6
|
+
|
|
7
|
+
### Testing
|
|
8
|
+
```bash
|
|
9
|
+
# Run all tests
|
|
10
|
+
pytest
|
|
11
|
+
|
|
12
|
+
# Run single test
|
|
13
|
+
pytest tests/test_module.py::test_function_name
|
|
14
|
+
|
|
15
|
+
# Run with coverage (already enabled by default)
|
|
16
|
+
pytest --cov physdes --cov-report term-missing
|
|
17
|
+
|
|
18
|
+
# Run tests in specific directory
|
|
19
|
+
pytest tests/test_point.py
|
|
20
|
+
|
|
21
|
+
# Run with verbose output (default)
|
|
22
|
+
pytest -v
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Linting/Formatting
|
|
26
|
+
```bash
|
|
27
|
+
# Run pre-commit hooks (includes isort, black, flake8)
|
|
28
|
+
pre-commit run --all-files
|
|
29
|
+
|
|
30
|
+
# Format code with black
|
|
31
|
+
black src/physdes tests/
|
|
32
|
+
|
|
33
|
+
# Sort imports with isort
|
|
34
|
+
isort src/physdes tests/
|
|
35
|
+
|
|
36
|
+
# Run flake8 linting
|
|
37
|
+
flake8 src/physdes tests/
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Build
|
|
41
|
+
```bash
|
|
42
|
+
# Build package
|
|
43
|
+
python -m build
|
|
44
|
+
|
|
45
|
+
# Or using tox
|
|
46
|
+
tox -e build
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Docs
|
|
50
|
+
```bash
|
|
51
|
+
# Build documentation
|
|
52
|
+
sphinx-build -b html docs/ docs/_build/html
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Code Style Guidelines
|
|
56
|
+
|
|
57
|
+
### Imports
|
|
58
|
+
- **Standard library imports first**, then third-party, then project imports
|
|
59
|
+
- Use explicit `from typing import` statements:
|
|
60
|
+
```python
|
|
61
|
+
from typing import Any, Generic, TypeVar, Union, Optional, List, Tuple, Dict, Callable, TYPE_CHECKING
|
|
62
|
+
```
|
|
63
|
+
- Use relative imports for project modules:
|
|
64
|
+
```python
|
|
65
|
+
from .generic import center, contain, displacement
|
|
66
|
+
from .interval import enlarge, hull
|
|
67
|
+
```
|
|
68
|
+
- For Python version compatibility (supports 3.8+):
|
|
69
|
+
```python
|
|
70
|
+
if sys.version_info[:2] >= (3, 8):
|
|
71
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
72
|
+
else:
|
|
73
|
+
from importlib_metadata import PackageNotFoundError, version
|
|
74
|
+
```
|
|
75
|
+
- Import debugging tools with `# type: ignore`:
|
|
76
|
+
```python
|
|
77
|
+
from icecream import ic # type: ignore
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Formatting
|
|
81
|
+
- **Line length**: 188 characters (configured in setup.cfg)
|
|
82
|
+
- **Formatter**: Black (version 23.7.0) with line length 188
|
|
83
|
+
- **Import sorter**: isort (version 5.12.0)
|
|
84
|
+
- **Linting**: flake8 with these exceptions: `E203, W503` (black-compatible)
|
|
85
|
+
- **Line endings**: Mixed line endings fixed automatically via pre-commit
|
|
86
|
+
|
|
87
|
+
### Type Hints
|
|
88
|
+
- **Required**: All functions and methods must have type hints
|
|
89
|
+
- **Generic types**: Use `TypeVar` and `Generic` for reusable classes:
|
|
90
|
+
```python
|
|
91
|
+
T = TypeVar("T", int, float)
|
|
92
|
+
class Interval(Generic[T]):
|
|
93
|
+
def __init__(self, lb: T, ub: T) -> None: ...
|
|
94
|
+
```
|
|
95
|
+
- **Union types**: Use pipe syntax for Python 3.10+, `Union` for older:
|
|
96
|
+
```python
|
|
97
|
+
def min_dist_with(self, obj: Union["Interval[T]", T]) -> T | int:
|
|
98
|
+
```
|
|
99
|
+
- **Forward references**: Use string quotes for types not yet defined:
|
|
100
|
+
```python
|
|
101
|
+
def __lt__(self, other: "Point[T1, T2]") -> bool:
|
|
102
|
+
```
|
|
103
|
+
- **Ignore sparingly**: Use `# type: ignore` only when unavoidable (e.g., icecream, mywheel imports)
|
|
104
|
+
|
|
105
|
+
### Naming Conventions
|
|
106
|
+
- **Classes**: `PascalCase` (e.g., `Point`, `Interval`, `Vector2`)
|
|
107
|
+
- **Functions/Methods**: `snake_case` (e.g., `hull_with`, `min_dist_with`, `get_center`)
|
|
108
|
+
- **Variables**: `snake_case` (e.g., `xcoord`, `ycoord`, `lower_bound`)
|
|
109
|
+
- **Constants**: `UPPER_SNAKE_CASE` (less common in this codebase)
|
|
110
|
+
- **Properties**: Use `@property` for computed attributes:
|
|
111
|
+
```python
|
|
112
|
+
@property
|
|
113
|
+
def lb(self) -> T:
|
|
114
|
+
return self._lb
|
|
115
|
+
```
|
|
116
|
+
- **Private attributes**: Prefix with underscore (e.g., `_lb`, `_ub`)
|
|
117
|
+
|
|
118
|
+
### Operator Overloading
|
|
119
|
+
- Implement dunder methods for mathematical operations:
|
|
120
|
+
```python
|
|
121
|
+
def __add__(self, rhs: Union["Interval[T]", T]) -> "Interval[T]":
|
|
122
|
+
def __iadd__(self, rhs: Union["Interval[T]", T]) -> "Interval[T]":
|
|
123
|
+
def __lt__(self, other: Union["Interval[T]", T]) -> bool:
|
|
124
|
+
```
|
|
125
|
+
- Return `NotImplemented` for unsupported type comparisons:
|
|
126
|
+
```python
|
|
127
|
+
def __eq__(self, other: object) -> bool:
|
|
128
|
+
if not isinstance(other, Point):
|
|
129
|
+
return NotImplemented
|
|
130
|
+
return (self.xcoord, self.ycoord) == (other.xcoord, other.ycoord)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Documentation
|
|
134
|
+
- **Docstrings required** for all public classes and methods
|
|
135
|
+
- **Style**: Google-style or similar (examples show detailed parameter descriptions)
|
|
136
|
+
- **Include**: Parameters, return types, and examples:
|
|
137
|
+
```python
|
|
138
|
+
def hull_with(self, other: "Point[T1, T2]") -> "Point[Any, Any]":
|
|
139
|
+
"""
|
|
140
|
+
The `hull_with` function takes another object and returns a new object
|
|
141
|
+
with the hull of the x and y coordinates of both objects.
|
|
142
|
+
|
|
143
|
+
:param other: The `other` parameter is an object of the same type as `self`.
|
|
144
|
+
:return: an instance of the same class as `self`.
|
|
145
|
+
"""
|
|
146
|
+
```
|
|
147
|
+
- **Examples**: Use doctest format when appropriate:
|
|
148
|
+
```python
|
|
149
|
+
Examples:
|
|
150
|
+
>>> a = Point(3, 5)
|
|
151
|
+
>>> print(a.hull_with(b))
|
|
152
|
+
([3, 5], [4, 6])
|
|
153
|
+
```
|
|
154
|
+
- **ASCII art**: Use `svgbob` for geometric diagrams:
|
|
155
|
+
```python
|
|
156
|
+
.. svgbob::
|
|
157
|
+
:align: center
|
|
158
|
+
|
|
159
|
+
.-----------.------.
|
|
160
|
+
| self | |
|
|
161
|
+
'-----------' |
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Error Handling
|
|
165
|
+
- **Minimal explicit error handling** - rely on Python's natural exceptions
|
|
166
|
+
- **Use assertions** for preconditions:
|
|
167
|
+
```python
|
|
168
|
+
assert lhs == rhs
|
|
169
|
+
```
|
|
170
|
+
- **Return invalid objects** when appropriate (e.g., `Interval` with `lb > ub`):
|
|
171
|
+
```python
|
|
172
|
+
def is_invalid(self) -> bool:
|
|
173
|
+
return self.lb > self.ub
|
|
174
|
+
```
|
|
175
|
+
- Avoid empty catch blocks (`except: pass`)
|
|
176
|
+
|
|
177
|
+
### Testing
|
|
178
|
+
- **Framework**: pytest with doctest support enabled
|
|
179
|
+
- **Coverage**: Required (--cov physdes --cov-report term-missing)
|
|
180
|
+
- **Property-based testing**: Use hypothesis for complex algorithms
|
|
181
|
+
- **Test naming**: `test_` prefix with descriptive names:
|
|
182
|
+
```python
|
|
183
|
+
def test_point() -> None:
|
|
184
|
+
def test_displacement() -> None:
|
|
185
|
+
def test_hull() -> None:
|
|
186
|
+
```
|
|
187
|
+
- **Assertions**: Use plain `assert` statements
|
|
188
|
+
- **Fixtures**: Use `conftest.py` for shared test data (random point generation)
|
|
189
|
+
|
|
190
|
+
### Code Organization
|
|
191
|
+
- **Structure**: `src/physdes/` for source, `tests/` for tests
|
|
192
|
+
- **Namespace package**: Use `__init__.py` for version info
|
|
193
|
+
- **Separation of concerns**: Core algorithms in dedicated modules (e.g., `dme_algorithm.py`, `global_router.py`)
|
|
194
|
+
- **Utility functions**: Generic operations in `generic.py` that work with multiple types via `hasattr()` checks:
|
|
195
|
+
```python
|
|
196
|
+
def overlap(lhs: Any, rhs: Any) -> bool:
|
|
197
|
+
if hasattr(lhs, "overlaps"):
|
|
198
|
+
result = lhs.overlaps(rhs)
|
|
199
|
+
elif hasattr(rhs, "overlaps"):
|
|
200
|
+
result = rhs.overlaps(lhs)
|
|
201
|
+
else: # assume scalar
|
|
202
|
+
result = lhs == rhs
|
|
203
|
+
return bool(result)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Pre-commit Hooks
|
|
207
|
+
- **Required**: All code must pass pre-commit checks before committing
|
|
208
|
+
- **Hooks configured**:
|
|
209
|
+
- `trailing-whitespace`
|
|
210
|
+
- `check-added-large-files`
|
|
211
|
+
- `check-ast`
|
|
212
|
+
- `check-merge-conflict`
|
|
213
|
+
- `isort`
|
|
214
|
+
- `black`
|
|
215
|
+
- `flake8`
|
|
216
|
+
|
|
217
|
+
### Development Guidelines
|
|
218
|
+
- **Python version**: Support 3.8+ (based on version checks in `__init__.py`)
|
|
219
|
+
- **Dependencies**: Minimal external deps (mywheel, icecream, lds_gen for testing)
|
|
220
|
+
- **Backward compatibility**: Use conditional imports for Python < 3.9
|
|
221
|
+
- **Documentation**: Docstrings with parameter descriptions and examples
|
|
222
|
+
- **Type safety**: Use type hints throughout, avoid `as any` or `@ts-ignore` equivalent
|
|
223
|
+
|
|
224
|
+
### Example Class Template
|
|
225
|
+
```python
|
|
226
|
+
from typing import Any, Generic, TypeVar, Union
|
|
227
|
+
|
|
228
|
+
T = TypeVar("T", int, float)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class ClassName(Generic[T]):
|
|
232
|
+
"""
|
|
233
|
+
Brief description of the class.
|
|
234
|
+
|
|
235
|
+
This code defines...
|
|
236
|
+
"""
|
|
237
|
+
|
|
238
|
+
__slots__ = ("_attr1", "_attr2")
|
|
239
|
+
|
|
240
|
+
def __init__(self, attr1: T, attr2: T) -> None:
|
|
241
|
+
"""
|
|
242
|
+
Initialize the object.
|
|
243
|
+
|
|
244
|
+
:param attr1: Description of attr1
|
|
245
|
+
:param attr2: Description of attr2
|
|
246
|
+
"""
|
|
247
|
+
self._attr1: T = attr1
|
|
248
|
+
self._attr2: T = attr2
|
|
249
|
+
|
|
250
|
+
@property
|
|
251
|
+
def attr1(self) -> T:
|
|
252
|
+
"""Return attr1 value."""
|
|
253
|
+
return self._attr1
|
|
254
|
+
|
|
255
|
+
def method_name(self, other: Any) -> Any:
|
|
256
|
+
"""
|
|
257
|
+
Method description.
|
|
258
|
+
|
|
259
|
+
:param other: Description of parameter
|
|
260
|
+
:return: Description of return value
|
|
261
|
+
"""
|
|
262
|
+
# Implementation
|
|
263
|
+
pass
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Key Project Context
|
|
267
|
+
|
|
268
|
+
physdes-py implements VLSI physical design algorithms:
|
|
269
|
+
- **Rectilinear polygons**: 2D/3D geometric operations
|
|
270
|
+
- **Clock tree synthesis**: DME (Deferred Merge Embedding) algorithm
|
|
271
|
+
- **Global routing**: Multiple strategies with constraints
|
|
272
|
+
- **Steiner forests**: Grid-based routing algorithms
|
|
273
|
+
- **Key dependencies**: `mywheel` (dllist), `lds_gen` (Halton sequences), `icecream` (debugging)
|
|
@@ -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)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
===========
|
|
3
|
+
|
|
4
|
+
All notable changes to this project will be documented in this file.
|
|
5
|
+
|
|
6
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
7
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
|
+
|
|
9
|
+
This file is managed by towncrier. To add a changelog entry:
|
|
10
|
+
|
|
11
|
+
1. Create a new file in `changelog/` directory:
|
|
12
|
+
- `changelog/<ISSUE_NUMBER>.<TYPE>.rst`
|
|
13
|
+
- Types: `feature`, `bugfix`, `doc`, `removal`, `misc`
|
|
14
|
+
|
|
15
|
+
2. Write your change in markdown format using issue number
|
|
16
|
+
|
|
17
|
+
Example: `changelog/123.feature.rst`
|
|
18
|
+
```rst
|
|
19
|
+
Add automated changelog management (#123)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
3. The changelog will be automatically updated on next release
|
|
23
|
+
|
|
24
|
+
## [Unreleased]
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
### Changed
|
|
28
|
+
### Deprecated
|
|
29
|
+
### Removed
|
|
30
|
+
### Fixed
|
|
31
|
+
### Security
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Version 0.1
|
|
35
|
+
==============
|
|
36
|
+
|
|
37
|
+
- Initial release
|
|
38
|
+
- Feature A added
|
|
39
|
+
- FIX: nasty bug #1729 fixed
|
|
40
|
+
- add your changes here!
|