draftwright 0.4.12__tar.gz → 0.4.13__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.13}/PKG-INFO +1 -1
- {draftwright-0.4.12 → draftwright-0.4.13}/pyproject.toml +1 -1
- draftwright-0.4.13/src/draftwright/_build_profile.py +186 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/_geometry.py +9 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/annotations/_common.py +31 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/annotations/from_model.py +133 -469
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/annotations/holes.py +3 -3
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/annotations/leaders.py +74 -16
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_adr0018_view_selection.py +20 -4
- draftwright-0.4.13/tests/test_build_profile_harness.py +194 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_e2e_standards.py +8 -3
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_import_boundaries.py +3 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1058_wheel_profile.py +4 -1
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1143_hole_completeness.py +61 -33
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1144_transactional_hole_table.py +15 -8
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1166_cross_pass_feature_leaders.py +83 -11
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1176_quality_fidelity.py +5 -1
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1187_unroutable_leaders.py +0 -1
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1204_multiscale_view_issues.py +4 -3
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1215_no_approved_tolerance_is_dropped.py +65 -54
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1216_callout_reservation_measures_ink.py +15 -5
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1276_turned_leader_targets.py +11 -4
- draftwright-0.4.13/tests/test_issue_1308_machined_leader_analytics.py +253 -0
- draftwright-0.4.13/tests/test_issue_1312_engine_costs.py +25 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_740_leader_assignment.py +45 -36
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_798_silhouette_lint.py +1 -1
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_885_prismatic_coverage.py +4 -1
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_917_open_channel.py +5 -2
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_layout_property.py +4 -4
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_make_drawing.py +14 -20
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_sheet_emit.py +65 -33
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_slanted_blind_step.py +12 -5
- {draftwright-0.4.12 → draftwright-0.4.13}/.gitignore +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/CHANGELOG.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/LICENSE +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/README.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/docs/adr/README.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/docs/reference/recogniser-capabilities.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/docs/reference/sheet.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/docs/research/1062-repeating-radial-profile-evidence.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/skills/SKILL.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/_core.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/_pmi_part21.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/_warnings.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/analysis.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/annotate.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/annotations/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/annotations/balloons.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/annotations/gears.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/annotations/orchestrator.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/annotations/sections.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/audit.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/builder.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/cli.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/compose.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/drawing.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/evaluation/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/evaluation/step_analysis.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/export.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/fits.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/fonts/IBMPlexMono-Regular.ttf +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/fonts/IBMPlexSansCondensed-Regular.ttf +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/fonts/LICENSE-IBMPlexMono-OFL.txt +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/fonts/LICENSE-IBMPlexSansCondensed-OFL.txt +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/fonts/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/intents.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/layout.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/channel_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/evidence.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/flat_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/gear_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/hole_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/issues.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/pmi_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/polygonal_stock_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/profiled_bore_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/quality.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/slot_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/structural.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/linting/suggest.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/make_drawing.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/model/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/model/callout.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/model/compiled.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/model/declare.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/model/detect.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/model/ir.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/model/planner.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/model/pmi_lowering.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/pmi.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/projection.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/py.typed +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/recogniser_contract.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/recognition/__init__.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/recognition_cache.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/registry.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/repair.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/score.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/sheet.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/sheet_emit.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/src/draftwright/view_plan.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/_kernel.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/_layout_sig.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/conftest.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/ap242_single_cylinder_diameter.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/evaluation/README.md +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/evaluation/ambiguous-open-semicircle.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/evaluation/blind-hole.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/evaluation/corpus-v1.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/evaluation/plain-block.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/evaluation/topology-a.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/evaluation/topology-b.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/grm03_thumbwheel_drive_screw.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/grm04_drive_plate.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/if_step_flat_across_cylinder.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/issue_1058_wheel_rh.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/issue_909_basic_part_design_017_body.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/issue_915_case_study_2.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/fixtures/tuner_jig_blind_obround_pockets.step +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/bracket_section.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/centered_rebate.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/chamfered.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/filleted.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/flange_dense.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/grid_plate.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/grooved_shaft.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/hex_bar.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/holed_slot.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/pocketed.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/prismatic_ladder.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/scattered_plate.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/side_drilled.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/refactor_golden/turned_stepped.json +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_add_dimension.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_adr0018_arrangement_gate.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_adr0018_view_routing.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_agents_guide.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_api_docs.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_architecture_docs.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_audit_differential.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_balloon_ring_standoff.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_carve_free_position_callers.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_compiled_plan_boundary.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_counting_calls.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_declare.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_declared_recognition_gate.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_dense_sheet_canary.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_deprecation_dates.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_detect_once.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_detect_registry.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_dimension_role_vocabulary.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_drawing_encapsulation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_e2e_slice.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_export_dxf_curves.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_export_dxf_zoom.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_external_recognition_boundary.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_fillets_adjacency.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_fits.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_flat_completeness.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_flat_stock_identity.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_flat_stock_opposition.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_gdt_placement.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_grid_lattice_convention.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_iso_nts_caption_placement.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1000_envelope_reuse.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1073_cross_body_patterns.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1082_polygonal_stock.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1086_declared_gears.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1116_ap242_hole_tolerance_lowering.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1130_view_planning_evidence.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1142_hole_leader_labels.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1146_scale_completeness.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1147_legibility_pair_aggregation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1153_contradictory_dimensions.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1154_one_owner_per_measurement.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1155_grm04_sheet_use.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1177_angular_dimensions.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1188_per_view_assignment.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1190_section_decision.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1196_deterministic_view_names.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1202_observed_drawing_consumer.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1209_linear_pmi_witnesses.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1215_envelope_tolerance.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1216_pairwise_across_scale_groups.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1217_claimed_representations.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1217_the_facility_is_shared.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1219_location_claims_its_own_axis.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1229_ledger_member_keying.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1240_iso_above_strip_visibility.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1254_turned_chamfers.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1260_view_constraints.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1281_turned_fillets.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1296_cylindrical_diameter_pmi.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1298_manufacturing_requirements.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_1299_page_escalation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_367_leader_ink.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_443_grm03_axial_coverage.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_676_polygonal_boss.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_676_polygonal_boss_declare.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_798_floor_cardinality.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_798_material_field.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_909_sloped_profile.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_915_dense_case.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_916_pocket_leader.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_924_zero_length_shoulders.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_955_height_contingency.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_issue_958_cross_solid_recognition.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_label_provenance.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_layout.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_layout_cleanliness.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_layout_hypothesis.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_leader_footprint.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_lint_box_cache.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_lint_reconciliation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_lint_structural.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_linting.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_location_vocabulary.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_note_verb.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_object_aspects.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_occupancy_boxes.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_parameter_id.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_part_model.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_pitch_dim_footprint.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_pmi.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_pmi_datum_lowering.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_pmi_gtol_lowering.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_pmi_part21.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_pocket_pattern.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_pocket_pattern_recognition.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_principal_profile_classifier.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_private_test_attr_reads.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_private_test_imports.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_quality_components.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_recogniser_adoption.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_recogniser_capabilities.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_recogniser_contract.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_recognition.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_recognition_manifest.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_recognition_result.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_refactor_golden.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_registry.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_render_seam.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_repack_geometry_seam.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_score.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_script_detail_parity.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_shared_box_memo.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_sheet_gdt.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_sheet_identity_invariant.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_sheet_notes.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_sheet_of.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_sheet_section.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_sheet_tables.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_slot_completeness.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_slot_pattern.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_slot_pattern_recognition.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_soft_deprecation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_solve_trace.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_step_analysis_evaluation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_strip_layout.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_suppression_ledger.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_suppression_marks.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_tolerances.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_turned_steps.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_view_plan.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_witness_label_reconciliation.py +0 -0
- {draftwright-0.4.12 → draftwright-0.4.13}/tests/test_workflows.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: draftwright
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.13
|
|
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
|
|
@@ -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
|
+
}
|
|
@@ -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(
|
|
@@ -830,6 +830,37 @@ def leader_callout_geometry(tip, elbow, draft, *, text_side="auto", callout_box=
|
|
|
830
830
|
return label_box, segments
|
|
831
831
|
|
|
832
832
|
|
|
833
|
+
def analytical_leader_lands_clear(
|
|
834
|
+
candidate,
|
|
835
|
+
obstacles,
|
|
836
|
+
silhouette,
|
|
837
|
+
page,
|
|
838
|
+
*,
|
|
839
|
+
label,
|
|
840
|
+
geom_clear=False,
|
|
841
|
+
) -> bool:
|
|
842
|
+
"""Apply the producer's label/full-ink clearance floor to an unbuilt leader."""
|
|
843
|
+
label_box = candidate.label_box
|
|
844
|
+
if not label or label_box is None:
|
|
845
|
+
return False
|
|
846
|
+
check_box = label_box
|
|
847
|
+
if geom_clear:
|
|
848
|
+
xs = [label_box[0], label_box[2]]
|
|
849
|
+
ys = [label_box[1], label_box[3]]
|
|
850
|
+
for polygon in candidate.ink_polygons:
|
|
851
|
+
xs.extend(point[0] for point in polygon)
|
|
852
|
+
ys.extend(point[1] for point in polygon)
|
|
853
|
+
check_box = (min(xs), min(ys), max(xs), max(ys))
|
|
854
|
+
return not (
|
|
855
|
+
_box_hits(check_box, obstacles)
|
|
856
|
+
or _box_hits(label_box, [silhouette])
|
|
857
|
+
or label_box[0] < page[0]
|
|
858
|
+
or label_box[1] < page[1]
|
|
859
|
+
or label_box[2] > page[2]
|
|
860
|
+
or label_box[3] > page[3]
|
|
861
|
+
)
|
|
862
|
+
|
|
863
|
+
|
|
833
864
|
def leader_footprint(tip, elbow, draft, *, text_side="auto", callout_box=None):
|
|
834
865
|
"""Analytical page-mm AABB ``(x0, y0, x1, y1)`` of the :class:`Leader` that
|
|
835
866
|
``Leader(tip, elbow, label="", draft, text_side=…, callout=…)`` would build —
|