draftwright 0.4.12__tar.gz → 0.4.14__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.
- {draftwright-0.4.12 → draftwright-0.4.14}/CHANGELOG.md +19 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/PKG-INFO +2 -2
- {draftwright-0.4.12 → draftwright-0.4.14}/docs/reference/recogniser-capabilities.md +31 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/pyproject.toml +2 -2
- draftwright-0.4.14/src/draftwright/_build_profile.py +186 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/_core.py +4 -1
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/_geometry.py +9 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/annotations/_common.py +417 -33
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/annotations/from_model.py +149 -470
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/annotations/holes.py +3 -3
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/annotations/leaders.py +74 -16
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/builder.py +67 -26
- draftwright-0.4.14/src/draftwright/linting/ink_overlap.py +745 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/quality.py +1 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/structural.py +161 -13
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/suggest.py +7 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/repair.py +26 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/conftest.py +2 -0
- draftwright-0.4.14/tests/fixtures/grm03_thumbwheel_drive_screw_ap242_pmi.step +32991 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_adr0018_view_selection.py +20 -4
- draftwright-0.4.14/tests/test_build_profile_harness.py +194 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_e2e_standards.py +8 -3
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_import_boundaries.py +3 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1058_wheel_profile.py +4 -1
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1143_hole_completeness.py +61 -33
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1144_transactional_hole_table.py +15 -8
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1166_cross_pass_feature_leaders.py +90 -12
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1176_quality_fidelity.py +5 -1
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1187_unroutable_leaders.py +0 -1
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1204_multiscale_view_issues.py +4 -3
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1215_no_approved_tolerance_is_dropped.py +65 -54
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1216_callout_reservation_measures_ink.py +15 -5
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1276_turned_leader_targets.py +11 -4
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1296_cylindrical_diameter_pmi.py +1 -2
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1298_manufacturing_requirements.py +1 -3
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1299_page_escalation.py +37 -13
- draftwright-0.4.14/tests/test_issue_1308_machined_leader_analytics.py +261 -0
- draftwright-0.4.14/tests/test_issue_1312_engine_costs.py +25 -0
- draftwright-0.4.14/tests/test_issue_1332_overlap_remedy.py +89 -0
- draftwright-0.4.14/tests/test_issue_1332_overlap_remedy_fast.py +106 -0
- draftwright-0.4.14/tests/test_issue_1332_zone_labels.py +49 -0
- draftwright-0.4.14/tests/test_issue_1334_prevent_ink.py +158 -0
- draftwright-0.4.14/tests/test_issue_1336_grm03_ap242_pmi_fixture.py +77 -0
- draftwright-0.4.14/tests/test_issue_1338_scale_before_page_escalation.py +103 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_443_grm03_axial_coverage.py +7 -4
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_740_leader_assignment.py +45 -36
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_798_silhouette_lint.py +1 -1
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_885_prismatic_coverage.py +4 -1
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_915_dense_case.py +62 -2
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_916_pocket_leader.py +29 -1
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_917_open_channel.py +5 -2
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_layout_property.py +4 -4
- draftwright-0.4.14/tests/test_lint_ink_overlap.py +727 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_lint_structural.py +56 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_make_drawing.py +86 -24
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_recogniser_capabilities.py +40 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_sheet_emit.py +65 -33
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_slanted_blind_step.py +12 -5
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_strip_layout.py +10 -2
- {draftwright-0.4.12 → draftwright-0.4.14}/.gitignore +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/LICENSE +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/README.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/docs/adr/README.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/docs/reference/sheet.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/docs/research/1062-repeating-radial-profile-evidence.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/skills/SKILL.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/_pmi_part21.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/_warnings.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/analysis.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/annotate.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/annotations/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/annotations/balloons.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/annotations/gears.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/annotations/orchestrator.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/annotations/sections.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/audit.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/cli.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/compose.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/drawing.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/evaluation/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/evaluation/step_analysis.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/export.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/fits.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/fonts/IBMPlexMono-Regular.ttf +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/fonts/IBMPlexSansCondensed-Regular.ttf +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/fonts/LICENSE-IBMPlexMono-OFL.txt +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/fonts/LICENSE-IBMPlexSansCondensed-OFL.txt +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/fonts/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/intents.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/layout.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/channel_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/evidence.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/flat_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/gear_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/hole_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/issues.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/pmi_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/polygonal_stock_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/profiled_bore_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/linting/slot_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/make_drawing.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/model/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/model/callout.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/model/compiled.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/model/declare.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/model/detect.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/model/ir.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/model/planner.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/model/pmi_lowering.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/pmi.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/projection.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/py.typed +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/recogniser_contract.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/recognition/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/recognition_cache.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/registry.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/score.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/sheet.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/sheet_emit.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/src/draftwright/view_plan.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/_kernel.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/_layout_sig.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/ap242_single_cylinder_diameter.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/evaluation/README.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/evaluation/ambiguous-open-semicircle.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/evaluation/blind-hole.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/evaluation/corpus-v1.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/evaluation/plain-block.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/evaluation/topology-a.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/evaluation/topology-b.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/grm03_thumbwheel_drive_screw.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/grm04_drive_plate.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/if_step_flat_across_cylinder.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/issue_1058_wheel_rh.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/issue_909_basic_part_design_017_body.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/issue_915_case_study_2.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/fixtures/tuner_jig_blind_obround_pockets.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/bracket_section.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/centered_rebate.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/chamfered.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/filleted.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/flange_dense.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/grid_plate.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/grooved_shaft.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/hex_bar.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/holed_slot.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/pocketed.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/prismatic_ladder.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/scattered_plate.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/side_drilled.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/refactor_golden/turned_stepped.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_add_dimension.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_adr0018_arrangement_gate.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_adr0018_view_routing.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_agents_guide.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_api_docs.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_architecture_docs.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_audit_differential.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_balloon_ring_standoff.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_carve_free_position_callers.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_compiled_plan_boundary.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_counting_calls.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_declare.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_declared_recognition_gate.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_dense_sheet_canary.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_deprecation_dates.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_detect_once.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_detect_registry.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_dimension_role_vocabulary.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_drawing_encapsulation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_e2e_slice.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_export_dxf_curves.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_export_dxf_zoom.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_external_recognition_boundary.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_fillets_adjacency.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_fits.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_flat_completeness.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_flat_stock_identity.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_flat_stock_opposition.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_gdt_placement.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_grid_lattice_convention.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_iso_nts_caption_placement.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1000_envelope_reuse.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1073_cross_body_patterns.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1082_polygonal_stock.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1086_declared_gears.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1116_ap242_hole_tolerance_lowering.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1130_view_planning_evidence.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1142_hole_leader_labels.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1146_scale_completeness.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1147_legibility_pair_aggregation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1153_contradictory_dimensions.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1154_one_owner_per_measurement.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1155_grm04_sheet_use.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1177_angular_dimensions.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1188_per_view_assignment.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1190_section_decision.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1196_deterministic_view_names.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1202_observed_drawing_consumer.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1209_linear_pmi_witnesses.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1215_envelope_tolerance.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1216_pairwise_across_scale_groups.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1217_claimed_representations.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1217_the_facility_is_shared.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1219_location_claims_its_own_axis.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1229_ledger_member_keying.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1240_iso_above_strip_visibility.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1254_turned_chamfers.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1260_view_constraints.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_1281_turned_fillets.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_367_leader_ink.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_676_polygonal_boss.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_676_polygonal_boss_declare.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_798_floor_cardinality.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_798_material_field.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_909_sloped_profile.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_924_zero_length_shoulders.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_955_height_contingency.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_issue_958_cross_solid_recognition.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_label_provenance.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_layout.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_layout_cleanliness.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_layout_hypothesis.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_leader_footprint.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_lint_box_cache.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_lint_reconciliation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_linting.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_location_vocabulary.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_note_verb.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_object_aspects.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_occupancy_boxes.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_parameter_id.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_part_model.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_pitch_dim_footprint.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_pmi.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_pmi_datum_lowering.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_pmi_gtol_lowering.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_pmi_part21.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_pocket_pattern.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_pocket_pattern_recognition.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_principal_profile_classifier.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_private_test_attr_reads.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_private_test_imports.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_quality_components.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_recogniser_adoption.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_recogniser_contract.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_recognition.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_recognition_manifest.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_recognition_result.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_refactor_golden.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_registry.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_render_seam.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_repack_geometry_seam.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_score.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_script_detail_parity.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_shared_box_memo.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_sheet_gdt.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_sheet_identity_invariant.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_sheet_notes.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_sheet_of.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_sheet_section.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_sheet_tables.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_slot_completeness.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_slot_pattern.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_slot_pattern_recognition.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_soft_deprecation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_solve_trace.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_step_analysis_evaluation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_suppression_ledger.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_suppression_marks.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_tolerances.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_turned_steps.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_view_plan.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_witness_label_reconciliation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.14}/tests/test_workflows.py +0 -0
|
@@ -2,8 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- New lint code `annotation_ink_overlap`: reports another annotation's line-work —
|
|
8
|
+
a dimension line, an extension line or a leader shaft — drawn through a label's
|
|
9
|
+
text, which `annotation_overlap` cannot see because it compares label boxes to
|
|
10
|
+
each other and to nothing else. Measured as the longest connected stroke path
|
|
11
|
+
crossing the label's exact polygon (or its axis-aligned box), in millimetres,
|
|
12
|
+
with a 0.5 mm floor. It scores on legibility, so
|
|
13
|
+
dense sheets that previously scored clean now score lower — 17 findings on
|
|
14
|
+
NIST CTC-02 AP203 alone, every sampled one confirmed a real defect by rendering.
|
|
15
|
+
Repair does not yet act on it (#1333) and the corridor solve does not yet avoid
|
|
16
|
+
it (#1334) (#1321, #1332).
|
|
17
|
+
|
|
5
18
|
### Changed
|
|
6
19
|
|
|
20
|
+
- `annotation_overlap` now reports the whole defect when the same pair also draws
|
|
21
|
+
line-work through one of the two labels: the message names the crosser, the label
|
|
22
|
+
crossed and the millimetres, and replaces the "use `label_offset_x`" remedy, which
|
|
23
|
+
is the advice that case contradicts. `LintIssue.suggestion` is `None` for those
|
|
24
|
+
issues rather than a snippet that re-places the text (#1321, #1332).
|
|
25
|
+
|
|
7
26
|
- Recogniser integration now uses only the exact `b123d-recognisers` dependency in
|
|
8
27
|
`pyproject.toml` and `uv.lock`. The separate release-evidence record, dependency-bump workflow,
|
|
9
28
|
candidate-checkout harness, and release-time capability-version rewrites have been removed;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: draftwright
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.14
|
|
4
4
|
Summary: Automated technical-drawing generation for build123d
|
|
5
5
|
Project-URL: Homepage, https://github.com/pzfreo/draftwright
|
|
6
6
|
Project-URL: Repository, https://github.com/pzfreo/draftwright
|
|
@@ -685,7 +685,7 @@ Classifier: Topic :: Scientific/Engineering
|
|
|
685
685
|
Requires-Python: <3.15,>=3.10
|
|
686
686
|
Requires-Dist: antlr4-python3-runtime<4.10
|
|
687
687
|
Requires-Dist: b123d-recognisers==0.3.1
|
|
688
|
-
Requires-Dist: build123d-drafting-helpers>=0.14.
|
|
688
|
+
Requires-Dist: build123d-drafting-helpers>=0.14.2
|
|
689
689
|
Requires-Dist: build123d<0.11,>=0.9.0; python_full_version < '3.13'
|
|
690
690
|
Requires-Dist: build123d<0.12,>=0.11; python_full_version >= '3.13'
|
|
691
691
|
Requires-Dist: numpy>=1.24
|
|
@@ -64,3 +64,34 @@ pass.
|
|
|
64
64
|
`bosses` is the fully consumed reference family. `repeating-radial-profiles` is the opposite
|
|
65
65
|
reference: it remains geometry-only critique evidence for a separately authored gear declaration,
|
|
66
66
|
with no inferred gear feature added to fill the table.
|
|
67
|
+
|
|
68
|
+
## Passage compatibility boundary
|
|
69
|
+
|
|
70
|
+
The installed `b123d-recognisers==0.3.1` release already contains the `passages` family introduced
|
|
71
|
+
in 0.2.6. Draftwright declares its schema-v1 `Passage` output exhaustively but deliberately keeps
|
|
72
|
+
the family `unsupported`, with the drafting decision tracked by issue #1245. This is a truthful
|
|
73
|
+
consumer disposition: the geometry remains visible in the aggregate inventory, while Draftwright
|
|
74
|
+
does not invent an IR feature, DSL declaration, generated code, drawing annotation, or completeness
|
|
75
|
+
requirement for it.
|
|
76
|
+
|
|
77
|
+
Draftwright's exact dependency pin must remain on a reviewed released version in the interval
|
|
78
|
+
`>=0.2.6,<0.4.0` until the separately reviewed F4b transition is ready. The lower boundary ensures
|
|
79
|
+
the installed manifest really contains `passages`; the upper boundary prevents accidental adoption
|
|
80
|
+
of the planned 0.4 compatibility change.
|
|
81
|
+
|
|
82
|
+
The reviewed future 0.4 model is a distinct migration, not latent behavior in this declaration:
|
|
83
|
+
|
|
84
|
+
- `SectionPassage` will be the authoritative physical output and aggregate census source;
|
|
85
|
+
- legacy `Passage` values will be an accepted-only compatibility projection;
|
|
86
|
+
- `recognise_passages(..., ledger=...)` will be a fail-loud unavailable compatibility operation;
|
|
87
|
+
- the writer-free `recognise_passages` name will remain public but non-authoritative; and
|
|
88
|
+
- rich split-junction passages can supersede a currently rendered Slot claim, moving ownership to
|
|
89
|
+
the Passage family through `SLOT_SUPERSEDED_BY_PASSAGE`; and
|
|
90
|
+
- the capability contract must represent those API and per-output roles exhaustively before the
|
|
91
|
+
dependency pin can cross 0.4.
|
|
92
|
+
|
|
93
|
+
That migration must update the package release, Draftwright adapter and declaration model,
|
|
94
|
+
validator, tests, exact pin, and lockfile together. The current validator remains unchanged and
|
|
95
|
+
fail closed; there is no forward declaration or stale-manifest exception. Crossing 0.4 also
|
|
96
|
+
requires #1245 to decide what those newly Passage-owned occurrences draw, or an explicit reviewed
|
|
97
|
+
decision to accept the resulting loss of the existing Slot callout.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "draftwright"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.14"
|
|
8
8
|
description = "Automated technical-drawing generation for build123d"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -17,7 +17,7 @@ dependencies = [
|
|
|
17
17
|
# 3.13+. Mirrors pzfreo/build123d-mcp's dependency handling.
|
|
18
18
|
"build123d>=0.9.0,<0.11 ; python_full_version < '3.13'",
|
|
19
19
|
"build123d>=0.11,<0.12 ; python_full_version >= '3.13'",
|
|
20
|
-
"build123d-drafting-helpers>=0.14.
|
|
20
|
+
"build123d-drafting-helpers>=0.14.2",
|
|
21
21
|
"b123d-recognisers==0.3.1",
|
|
22
22
|
"numpy>=1.24",
|
|
23
23
|
# PNG raster export (SVG→PDF→PNG). Both permissively licensed (Pillow HPND; pypdfium2
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""Pytest plugin and runner support for reproducible build-cost profiles (#1307)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import re
|
|
7
|
+
import sys
|
|
8
|
+
from collections import defaultdict
|
|
9
|
+
from collections.abc import Callable
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from functools import wraps
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from time import perf_counter
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
_MIN_REPORT_SECONDS = 0.005
|
|
17
|
+
_STATE: _ProfileState | None = None
|
|
18
|
+
_CURRENT_NODEID = "<collection>"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class _ProfileState:
|
|
23
|
+
output_dir: Path
|
|
24
|
+
worker_id: str
|
|
25
|
+
collected: int | None = None
|
|
26
|
+
calls: dict[tuple[str, str], list[float]] = field(
|
|
27
|
+
default_factory=lambda: defaultdict(lambda: [0, 0.0])
|
|
28
|
+
)
|
|
29
|
+
phases: list[dict[str, Any]] = field(default_factory=list)
|
|
30
|
+
|
|
31
|
+
def record_call(self, seam: str, seconds: float) -> None:
|
|
32
|
+
aggregate = self.calls[(_CURRENT_NODEID, seam)]
|
|
33
|
+
aggregate[0] += 1
|
|
34
|
+
aggregate[1] += seconds
|
|
35
|
+
|
|
36
|
+
def write(self, exitstatus: int) -> Path:
|
|
37
|
+
self.output_dir.mkdir(parents=True, exist_ok=True)
|
|
38
|
+
safe_worker = re.sub(r"[^A-Za-z0-9_.-]", "_", self.worker_id)
|
|
39
|
+
path = self.output_dir / f"profile-{safe_worker}.json"
|
|
40
|
+
payload = {
|
|
41
|
+
"worker_id": self.worker_id,
|
|
42
|
+
"collected": self.collected,
|
|
43
|
+
"exitstatus": exitstatus,
|
|
44
|
+
"calls": [
|
|
45
|
+
{
|
|
46
|
+
"nodeid": nodeid,
|
|
47
|
+
"seam": seam,
|
|
48
|
+
"count": int(values[0]),
|
|
49
|
+
"seconds": values[1],
|
|
50
|
+
}
|
|
51
|
+
for (nodeid, seam), values in sorted(self.calls.items())
|
|
52
|
+
],
|
|
53
|
+
"phases": self.phases,
|
|
54
|
+
}
|
|
55
|
+
path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
56
|
+
return path
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _timed(seam: str, function: Callable[..., Any]) -> Callable[..., Any]:
|
|
60
|
+
@wraps(function)
|
|
61
|
+
def wrapper(*args, **kwargs):
|
|
62
|
+
started = perf_counter()
|
|
63
|
+
try:
|
|
64
|
+
return function(*args, **kwargs)
|
|
65
|
+
finally:
|
|
66
|
+
assert _STATE is not None
|
|
67
|
+
_STATE.record_call(seam, perf_counter() - started)
|
|
68
|
+
|
|
69
|
+
return wrapper
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def pytest_addoption(parser) -> None:
|
|
73
|
+
group = parser.getgroup("draftwright-build-profile")
|
|
74
|
+
group.addoption(
|
|
75
|
+
"--build-profile-dir",
|
|
76
|
+
help="write one Draftwright build profile JSON file per pytest-xdist worker",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def pytest_configure(config) -> None:
|
|
81
|
+
global _STATE
|
|
82
|
+
output = config.getoption("--build-profile-dir")
|
|
83
|
+
if not output:
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
worker_input = getattr(config, "workerinput", None)
|
|
87
|
+
# Under xdist the controller executes no tests; worker processes write the useful files.
|
|
88
|
+
if worker_input is None and getattr(config.option, "numprocesses", None):
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
worker_id = worker_input.get("workerid", "worker") if worker_input else "main"
|
|
92
|
+
_STATE = _ProfileState(Path(output).resolve(), worker_id)
|
|
93
|
+
|
|
94
|
+
import draftwright.builder as builder
|
|
95
|
+
import draftwright.sheet as sheet
|
|
96
|
+
|
|
97
|
+
draftwright = sys.modules["draftwright"]
|
|
98
|
+
builder_public = _timed("builder.build_drawing", builder.build_drawing)
|
|
99
|
+
builder.build_drawing = builder_public
|
|
100
|
+
# The public lazy package attribute and Sheet's import-time binding otherwise bypass a
|
|
101
|
+
# patch installed only on builder.py. That omission made the first #1307 census a lower
|
|
102
|
+
# bound, so all three bindings are explicit here.
|
|
103
|
+
setattr(draftwright, "build_drawing", builder_public)
|
|
104
|
+
sheet.build_drawing = _timed("sheet.build_drawing", sheet.build_drawing)
|
|
105
|
+
builder._build_drawing_once = _timed(
|
|
106
|
+
"builder._build_drawing_once", builder._build_drawing_once
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def pytest_collection_finish(session) -> None:
|
|
111
|
+
if _STATE is not None:
|
|
112
|
+
_STATE.collected = len(session.items)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def pytest_runtest_logstart(nodeid, location) -> None:
|
|
116
|
+
del location
|
|
117
|
+
global _CURRENT_NODEID
|
|
118
|
+
_CURRENT_NODEID = nodeid
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def pytest_runtest_logfinish(nodeid, location) -> None:
|
|
122
|
+
del nodeid, location
|
|
123
|
+
global _CURRENT_NODEID
|
|
124
|
+
_CURRENT_NODEID = "<between-tests>"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def pytest_runtest_logreport(report) -> None:
|
|
128
|
+
if _STATE is not None and report.duration >= _MIN_REPORT_SECONDS:
|
|
129
|
+
_STATE.phases.append(
|
|
130
|
+
{
|
|
131
|
+
"nodeid": report.nodeid,
|
|
132
|
+
"phase": report.when,
|
|
133
|
+
"seconds": report.duration,
|
|
134
|
+
"outcome": report.outcome,
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def pytest_sessionfinish(session, exitstatus) -> None:
|
|
140
|
+
del session
|
|
141
|
+
if _STATE is not None:
|
|
142
|
+
_STATE.write(int(exitstatus))
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def build_pytest_command(output_dir: Path, pytest_args: list[str]) -> list[str]:
|
|
146
|
+
"""Return argv without joining *pytest_args* into a shell-expanded module string."""
|
|
147
|
+
return [
|
|
148
|
+
"uv",
|
|
149
|
+
"run",
|
|
150
|
+
"pytest",
|
|
151
|
+
"-p",
|
|
152
|
+
"draftwright._build_profile",
|
|
153
|
+
f"--build-profile-dir={output_dir}",
|
|
154
|
+
*pytest_args,
|
|
155
|
+
]
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def summarise_profiles(output_dir: Path, expected_collected: int) -> dict[str, Any]:
|
|
159
|
+
paths = sorted(output_dir.glob("profile-*.json"))
|
|
160
|
+
if not paths:
|
|
161
|
+
raise ValueError(f"no worker profiles were written to {output_dir}")
|
|
162
|
+
|
|
163
|
+
by_seam: dict[str, list[float]] = defaultdict(lambda: [0, 0.0])
|
|
164
|
+
workers = []
|
|
165
|
+
for path in paths:
|
|
166
|
+
payload = json.loads(path.read_text(encoding="utf-8"))
|
|
167
|
+
collected = payload.get("collected")
|
|
168
|
+
if collected != expected_collected:
|
|
169
|
+
raise ValueError(
|
|
170
|
+
f"{path.name} collected {collected!r}, expected {expected_collected}; "
|
|
171
|
+
"refusing to report a successful empty or partial profile"
|
|
172
|
+
)
|
|
173
|
+
workers.append(payload["worker_id"])
|
|
174
|
+
for call in payload["calls"]:
|
|
175
|
+
aggregate = by_seam[call["seam"]]
|
|
176
|
+
aggregate[0] += call["count"]
|
|
177
|
+
aggregate[1] += call["seconds"]
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
"expected_collected": expected_collected,
|
|
181
|
+
"workers": workers,
|
|
182
|
+
"seams": {
|
|
183
|
+
seam: {"count": int(values[0]), "seconds": values[1]}
|
|
184
|
+
for seam, values in sorted(by_seam.items())
|
|
185
|
+
},
|
|
186
|
+
}
|
|
@@ -358,7 +358,10 @@ _QUOTED_RE = re.compile(r"'([^']*)'")
|
|
|
358
358
|
|
|
359
359
|
@functools.lru_cache(maxsize=512)
|
|
360
360
|
def _text_size(
|
|
361
|
-
text: str,
|
|
361
|
+
text: str,
|
|
362
|
+
font_size: float,
|
|
363
|
+
font_path: str | None = PLEX_MONO,
|
|
364
|
+
font: str = "Arial",
|
|
362
365
|
) -> tuple[float, float]:
|
|
363
366
|
"""Measured rendered (width, height) (page-mm) of *text* at *font_size*.
|
|
364
367
|
|
|
@@ -456,6 +456,15 @@ def _convex_polygons_overlap(left, right) -> bool:
|
|
|
456
456
|
|
|
457
457
|
if len(left) < 3 or len(right) < 3:
|
|
458
458
|
return False
|
|
459
|
+
left_x, left_y = zip(*left, strict=True)
|
|
460
|
+
right_x, right_y = zip(*right, strict=True)
|
|
461
|
+
if (
|
|
462
|
+
max(left_x) <= min(right_x)
|
|
463
|
+
or max(right_x) <= min(left_x)
|
|
464
|
+
or max(left_y) <= min(right_y)
|
|
465
|
+
or max(right_y) <= min(left_y)
|
|
466
|
+
):
|
|
467
|
+
return False
|
|
459
468
|
axes: list[tuple[float, float]] = []
|
|
460
469
|
for points in (left, right):
|
|
461
470
|
axes.extend(
|