draftwright 0.4.26__tar.gz → 0.4.27__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (596) hide show
  1. {draftwright-0.4.26 → draftwright-0.4.27}/PKG-INFO +1 -1
  2. {draftwright-0.4.26 → draftwright-0.4.27}/docs/reference/sheet.md +4 -1
  3. {draftwright-0.4.26 → draftwright-0.4.27}/pyproject.toml +1 -1
  4. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/_core.py +10 -4
  5. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/analysis.py +2 -0
  6. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/annotations/orchestrator.py +1 -2
  7. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/builder.py +12 -5
  8. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/cli.py +9 -1
  9. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/sheet.py +3 -1
  10. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/sheet_emit.py +8 -1
  11. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/view_plan.py +4 -2
  12. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_add_dimension.py +1 -1
  13. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_compiled_plan_boundary.py +1 -0
  14. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1144_transactional_hole_table.py +1 -1
  15. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1217_the_facility_is_shared.py +12 -5
  16. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1308_machined_leader_analytics.py +4 -1
  17. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1514_projection_safeguard.py +1 -1
  18. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_make_drawing.py +7 -5
  19. draftwright-0.4.27/tests/test_projection_symbol_default.py +164 -0
  20. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_sheet_emit.py +12 -3
  21. {draftwright-0.4.26 → draftwright-0.4.27}/.gitignore +0 -0
  22. {draftwright-0.4.26 → draftwright-0.4.27}/CHANGELOG.md +0 -0
  23. {draftwright-0.4.26 → draftwright-0.4.27}/LICENSE +0 -0
  24. {draftwright-0.4.26 → draftwright-0.4.27}/README.md +0 -0
  25. {draftwright-0.4.26 → draftwright-0.4.27}/docs/adr/README.md +0 -0
  26. {draftwright-0.4.26 → draftwright-0.4.27}/docs/reference/recogniser-capabilities.md +0 -0
  27. {draftwright-0.4.26 → draftwright-0.4.27}/docs/research/1062-repeating-radial-profile-evidence.md +0 -0
  28. {draftwright-0.4.26 → draftwright-0.4.27}/skills/SKILL.md +0 -0
  29. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/__init__.py +0 -0
  30. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/_build_profile.py +0 -0
  31. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/_geometry.py +0 -0
  32. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/_pmi_part21.py +0 -0
  33. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/_warnings.py +0 -0
  34. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/angular_geometry.py +0 -0
  35. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/annotate.py +0 -0
  36. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/annotations/__init__.py +0 -0
  37. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/annotations/_common.py +0 -0
  38. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/annotations/angular.py +0 -0
  39. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/annotations/balloons.py +0 -0
  40. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/annotations/from_model.py +0 -0
  41. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/annotations/gears.py +0 -0
  42. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/annotations/holes.py +0 -0
  43. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/annotations/leaders.py +0 -0
  44. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/annotations/sections.py +0 -0
  45. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/audit.py +0 -0
  46. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/blend_contract.py +0 -0
  47. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/compose.py +0 -0
  48. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/document.py +0 -0
  49. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/document_evidence.py +0 -0
  50. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/document_input.py +0 -0
  51. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/drawing.py +0 -0
  52. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/evaluation/__init__.py +0 -0
  53. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/evaluation/step_analysis.py +0 -0
  54. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/export.py +0 -0
  55. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/feature_identity.py +0 -0
  56. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/fits.py +0 -0
  57. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/fonts/IBMPlexMono-Regular.ttf +0 -0
  58. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/fonts/IBMPlexSansCondensed-Regular.ttf +0 -0
  59. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/fonts/LICENSE-IBMPlexMono-OFL.txt +0 -0
  60. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/fonts/LICENSE-IBMPlexSansCondensed-OFL.txt +0 -0
  61. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/fonts/__init__.py +0 -0
  62. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/inspection.py +0 -0
  63. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/inspection_contract.py +0 -0
  64. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/intents.py +0 -0
  65. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/layout.py +0 -0
  66. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/__init__.py +0 -0
  67. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/_registry.py +0 -0
  68. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/angled_step_coverage.py +0 -0
  69. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/angular.py +0 -0
  70. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/blend_coverage.py +0 -0
  71. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/chamfer_coverage.py +0 -0
  72. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/channel_coverage.py +0 -0
  73. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/circular_blind_step_coverage.py +0 -0
  74. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/coverage.py +0 -0
  75. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/evidence.py +0 -0
  76. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/fillet_coverage.py +0 -0
  77. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/flat_coverage.py +0 -0
  78. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/gear_coverage.py +0 -0
  79. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/groove_coverage.py +0 -0
  80. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/hole_coverage.py +0 -0
  81. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/ink_overlap.py +0 -0
  82. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/issues.py +0 -0
  83. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/oriented_slot_coverage.py +0 -0
  84. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/pad_coverage.py +0 -0
  85. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/paired_ramp_step_coverage.py +0 -0
  86. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/passage_coverage.py +0 -0
  87. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/plate_coverage.py +0 -0
  88. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/pmi_coverage.py +0 -0
  89. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/pocket_coverage.py +0 -0
  90. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/pocket_pattern_coverage.py +0 -0
  91. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/polygonal_boss_coverage.py +0 -0
  92. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/polygonal_stock_coverage.py +0 -0
  93. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/prismatic_pocket_coverage.py +0 -0
  94. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/profiled_bore_coverage.py +0 -0
  95. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/quality.py +0 -0
  96. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/rectangular_blind_slot_coverage.py +0 -0
  97. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/requirements.py +0 -0
  98. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/round_bottom_blind_slot_coverage.py +0 -0
  99. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/schedule_evidence.py +0 -0
  100. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/section_recess_coverage.py +0 -0
  101. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/slot_coverage.py +0 -0
  102. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/structural.py +0 -0
  103. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/suggest.py +0 -0
  104. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/through_step_coverage.py +0 -0
  105. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/linting/turned_step_coverage.py +0 -0
  106. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/location_contract.py +0 -0
  107. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/make_drawing.py +0 -0
  108. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/measurement_support.py +0 -0
  109. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/model/__init__.py +0 -0
  110. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/model/callout.py +0 -0
  111. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/model/compiled.py +0 -0
  112. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/model/declare.py +0 -0
  113. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/model/detect.py +0 -0
  114. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/model/ir.py +0 -0
  115. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/model/planner.py +0 -0
  116. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/model/pmi_lowering.py +0 -0
  117. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/oriented_slot_contract.py +0 -0
  118. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/plate_correspondence.py +0 -0
  119. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/pmi.py +0 -0
  120. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/profile_angles.py +0 -0
  121. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/progress.py +0 -0
  122. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/projection.py +0 -0
  123. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/py.typed +0 -0
  124. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/recogniser_contract.py +0 -0
  125. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/recogniser_policy.py +0 -0
  126. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/recogniser_schema.py +0 -0
  127. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/recognition/__init__.py +0 -0
  128. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/recognition_cache.py +0 -0
  129. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/recognition_frame.py +0 -0
  130. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/recognition_ownership.py +0 -0
  131. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/registry.py +0 -0
  132. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/repair.py +0 -0
  133. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/reporting.py +0 -0
  134. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/score.py +0 -0
  135. {draftwright-0.4.26 → draftwright-0.4.27}/src/draftwright/section_recess_contract.py +0 -0
  136. {draftwright-0.4.26 → draftwright-0.4.27}/tests/_evidence_contract.py +0 -0
  137. {draftwright-0.4.26 → draftwright-0.4.27}/tests/_kernel.py +0 -0
  138. {draftwright-0.4.26 → draftwright-0.4.27}/tests/_layout_sig.py +0 -0
  139. {draftwright-0.4.26 → draftwright-0.4.27}/tests/_mutation_corpus.py +0 -0
  140. {draftwright-0.4.26 → draftwright-0.4.27}/tests/_recogniser_public_contract.py +0 -0
  141. {draftwright-0.4.26 → draftwright-0.4.27}/tests/_section_recess_cases.py +0 -0
  142. {draftwright-0.4.26 → draftwright-0.4.27}/tests/conftest.py +0 -0
  143. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/ap242_single_cylinder_diameter.step +0 -0
  144. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/README.md +0 -0
  145. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/ambiguous-open-semicircle.step +0 -0
  146. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/blind-hole.step +0 -0
  147. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/chamfer-asymmetric.step +0 -0
  148. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/chamfer-compound.step +0 -0
  149. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/chamfer-overlap.step +0 -0
  150. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/chamfer-plain.step +0 -0
  151. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/chamfer-planar-x.step +0 -0
  152. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/chamfer-planar-y.step +0 -0
  153. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/chamfer-planar-z.step +0 -0
  154. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/chamfer-topology-a.step +0 -0
  155. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/chamfer-topology-b.step +0 -0
  156. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/chamfer-turned.step +0 -0
  157. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-chamfers-v1.json +0 -0
  158. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-countersinks-v1.json +0 -0
  159. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-double-d-bores-v1.json +0 -0
  160. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-fillets-v1.json +0 -0
  161. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-flats-v1.json +0 -0
  162. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-grooves-v1.json +0 -0
  163. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-hole-patterns-v1.json +0 -0
  164. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-plates-v1.json +0 -0
  165. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-pocket-patterns-v1.json +0 -0
  166. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-pockets-v1.json +0 -0
  167. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-polygonal-bosses-v1.json +0 -0
  168. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-polygonal-stock-v1.json +0 -0
  169. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-rectangular-pads-v1.json +0 -0
  170. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-turned-steps-v1.json +0 -0
  171. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/corpus-v1.json +0 -0
  172. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/countersink-deburr.step +0 -0
  173. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/countersink-external-cone.step +0 -0
  174. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/countersink-mixed-pair.step +0 -0
  175. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/countersink-single.step +0 -0
  176. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/countersink-topology-a.step +0 -0
  177. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/countersink-topology-b.step +0 -0
  178. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/double-d-axis-x.step +0 -0
  179. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/double-d-axis-y.step +0 -0
  180. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/double-d-blind.step +0 -0
  181. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/double-d-coaxial-compound.step +0 -0
  182. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/double-d-opposed-blind.step +0 -0
  183. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/double-d-roll-30.step +0 -0
  184. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/double-d-round-bore.step +0 -0
  185. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/double-d-single-z.step +0 -0
  186. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/double-d-topology-a.step +0 -0
  187. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/double-d-topology-b.step +0 -0
  188. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/fillet-compound.step +0 -0
  189. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/fillet-overlap.step +0 -0
  190. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/fillet-plain.step +0 -0
  191. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/fillet-planar-x.step +0 -0
  192. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/fillet-planar-y.step +0 -0
  193. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/fillet-planar-z.step +0 -0
  194. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/fillet-repeated.step +0 -0
  195. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/fillet-topology-a.step +0 -0
  196. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/fillet-topology-b.step +0 -0
  197. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/fillet-turned.step +0 -0
  198. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/flat-coaxial.step +0 -0
  199. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/flat-double-d.step +0 -0
  200. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/flat-lone-d.step +0 -0
  201. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/flat-nonround.step +0 -0
  202. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/flat-slanted-double-d.step +0 -0
  203. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/flat-topology-a.step +0 -0
  204. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/flat-topology-b.step +0 -0
  205. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/groove-compound.step +0 -0
  206. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/groove-lone-x.step +0 -0
  207. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/groove-lone-y.step +0 -0
  208. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/groove-lone-z.step +0 -0
  209. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/groove-monotonic-negative.step +0 -0
  210. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/groove-narrow.step +0 -0
  211. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/groove-topology-a.step +0 -0
  212. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/groove-topology-b.step +0 -0
  213. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-compound-equal.step +0 -0
  214. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-detached-body-negative.step +0 -0
  215. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-full-span-ledge-negative.step +0 -0
  216. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-nested-staircase-negative.step +0 -0
  217. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-topology-a.step +0 -0
  218. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-topology-b.step +0 -0
  219. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-x-negative.step +0 -0
  220. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-x-positive.step +0 -0
  221. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-y-negative.step +0 -0
  222. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-y-positive.step +0 -0
  223. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-z-negative.step +0 -0
  224. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pad-z-positive.step +0 -0
  225. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pattern-ambiguous.step +0 -0
  226. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pattern-grid.step +0 -0
  227. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pattern-topology-a.step +0 -0
  228. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pattern-topology-b.step +0 -0
  229. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plain-block.step +0 -0
  230. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plate-compound-equal.step +0 -0
  231. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plate-cross-topology-a.step +0 -0
  232. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plate-cross-topology-b.step +0 -0
  233. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plate-detached-negative.step +0 -0
  234. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plate-rotational-negative.step +0 -0
  235. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plate-single-negative.step +0 -0
  236. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plate-t-xz.step +0 -0
  237. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plate-t-yz.step +0 -0
  238. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plate-thick-negative.step +0 -0
  239. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plate-u-additive.step +0 -0
  240. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/plate-u-cut.step +0 -0
  241. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-compound.step +0 -0
  242. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-edge-anchored.step +0 -0
  243. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-lone.step +0 -0
  244. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-opposed.step +0 -0
  245. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-pattern-ambiguous.step +0 -0
  246. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-pattern-grid.step +0 -0
  247. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-pattern-linear.step +0 -0
  248. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-pattern-pair.step +0 -0
  249. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-pattern-topology-a.step +0 -0
  250. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-pattern-topology-b.step +0 -0
  251. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-prismatic-negative.step +0 -0
  252. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-side.step +0 -0
  253. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-through-negative.step +0 -0
  254. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-topology-a.step +0 -0
  255. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-topology-b.step +0 -0
  256. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/pocket-two-equal.step +0 -0
  257. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-boss-compound-equal.step +0 -0
  258. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-boss-detached-negative.step +0 -0
  259. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-boss-in-plane-rotated.step +0 -0
  260. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-boss-other-protrusions-negative.step +0 -0
  261. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-boss-recess-negative.step +0 -0
  262. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-boss-stock-negative.step +0 -0
  263. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-boss-topology-a.step +0 -0
  264. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-boss-topology-b.step +0 -0
  265. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-boss-x.step +0 -0
  266. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-boss-y.step +0 -0
  267. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-boss-z.step +0 -0
  268. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-stock-compound-negative.step +0 -0
  269. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-stock-cylinder-negative.step +0 -0
  270. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-stock-irregular-negative.step +0 -0
  271. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-stock-octagon-negative.step +0 -0
  272. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-stock-recess-negative.step +0 -0
  273. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-stock-roll17.step +0 -0
  274. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-stock-topology-a.step +0 -0
  275. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-stock-topology-b.step +0 -0
  276. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-stock-translated.step +0 -0
  277. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-stock-x.step +0 -0
  278. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/polygonal-stock-y.step +0 -0
  279. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/topology-a.step +0 -0
  280. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/topology-b.step +0 -0
  281. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/turned-step-axis-x.step +0 -0
  282. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/turned-step-axis-y.step +0 -0
  283. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/turned-step-axis-z.step +0 -0
  284. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/turned-step-compound.step +0 -0
  285. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/turned-step-repeated-lengths.step +0 -0
  286. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/turned-step-through-bore.step +0 -0
  287. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/turned-step-topology-a.step +0 -0
  288. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/turned-step-topology-b.step +0 -0
  289. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/evaluation/turned-step-translated-blind-bore.step +0 -0
  290. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/grm03_thumbwheel_drive_screw.step +0 -0
  291. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/grm03_thumbwheel_drive_screw_ap242_pmi.step +0 -0
  292. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/grm04_drive_plate.step +0 -0
  293. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/if_step_flat_across_cylinder.step +0 -0
  294. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/issue_1058_wheel_rh.step +0 -0
  295. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/issue_1247_angled_blind_step.step +0 -0
  296. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/issue_909_basic_part_design_017_body.step +0 -0
  297. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/issue_915_case_study_2.step +0 -0
  298. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
  299. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
  300. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
  301. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
  302. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
  303. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
  304. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
  305. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
  306. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
  307. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
  308. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/tuner_jig_blind_obround_pockets.step +0 -0
  309. {draftwright-0.4.26 → draftwright-0.4.27}/tests/fixtures/whistle_frame_reference.step +0 -0
  310. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/bracket_section.json +0 -0
  311. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/centered_rebate.json +0 -0
  312. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/chamfered.json +0 -0
  313. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/filleted.json +0 -0
  314. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/flange_dense.json +0 -0
  315. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/grid_plate.json +0 -0
  316. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/grooved_shaft.json +0 -0
  317. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/hex_bar.json +0 -0
  318. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/holed_slot.json +0 -0
  319. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/pocketed.json +0 -0
  320. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/prismatic_ladder.json +0 -0
  321. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/scattered_plate.json +0 -0
  322. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/side_drilled.json +0 -0
  323. {draftwright-0.4.26 → draftwright-0.4.27}/tests/refactor_golden/turned_stepped.json +0 -0
  324. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_adr0018_arrangement_gate.py +0 -0
  325. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_adr0018_view_routing.py +0 -0
  326. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_adr0018_view_selection.py +0 -0
  327. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_adr_corpus.py +0 -0
  328. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_agents_guide.py +0 -0
  329. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_api_docs.py +0 -0
  330. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_architecture_docs.py +0 -0
  331. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_audit_differential.py +0 -0
  332. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_balloon_ring_standoff.py +0 -0
  333. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_build_profile_harness.py +0 -0
  334. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_carve_free_position_callers.py +0 -0
  335. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_clone_budget.py +0 -0
  336. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_counting_calls.py +0 -0
  337. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_declare.py +0 -0
  338. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_declared_recognition_gate.py +0 -0
  339. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_dense_sheet_canary.py +0 -0
  340. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_deprecation_dates.py +0 -0
  341. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_detect_once.py +0 -0
  342. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_detect_registry.py +0 -0
  343. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_dimension_role_vocabulary.py +0 -0
  344. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_drawing_encapsulation.py +0 -0
  345. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_e2e_slice.py +0 -0
  346. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_e2e_standards.py +0 -0
  347. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_export_dxf_curves.py +0 -0
  348. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_export_dxf_zoom.py +0 -0
  349. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_export_reproducible.py +0 -0
  350. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_external_recognition_boundary.py +0 -0
  351. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_fillets_adjacency.py +0 -0
  352. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_fits.py +0 -0
  353. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_flat_completeness.py +0 -0
  354. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_flat_stock_identity.py +0 -0
  355. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_flat_stock_opposition.py +0 -0
  356. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_gdt_placement.py +0 -0
  357. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_geometry_graph_spike.py +0 -0
  358. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_grid_lattice_convention.py +0 -0
  359. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_import_boundaries.py +0 -0
  360. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_inspection_contract.py +0 -0
  361. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_iso_nts_caption_placement.py +0 -0
  362. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1000_envelope_reuse.py +0 -0
  363. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1006_measurement_comparison.py +0 -0
  364. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1058_wheel_profile.py +0 -0
  365. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1073_cross_body_patterns.py +0 -0
  366. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1082_polygonal_stock.py +0 -0
  367. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1086_declared_gears.py +0 -0
  368. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1116_ap242_hole_tolerance_lowering.py +0 -0
  369. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1130_view_planning_evidence.py +0 -0
  370. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1142_hole_leader_labels.py +0 -0
  371. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1143_hole_completeness.py +0 -0
  372. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1146_scale_completeness.py +0 -0
  373. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1147_legibility_pair_aggregation.py +0 -0
  374. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1153_contradictory_dimensions.py +0 -0
  375. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1154_one_owner_per_measurement.py +0 -0
  376. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1155_grm04_sheet_use.py +0 -0
  377. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1166_cross_pass_feature_leaders.py +0 -0
  378. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1176_quality_fidelity.py +0 -0
  379. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1177_angular_dimensions.py +0 -0
  380. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1187_unroutable_leaders.py +0 -0
  381. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1188_per_view_assignment.py +0 -0
  382. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1190_section_decision.py +0 -0
  383. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1196_deterministic_view_names.py +0 -0
  384. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1202_observed_drawing_consumer.py +0 -0
  385. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1204_multiscale_view_issues.py +0 -0
  386. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1209_linear_pmi_witnesses.py +0 -0
  387. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1215_envelope_tolerance.py +0 -0
  388. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1215_no_approved_tolerance_is_dropped.py +0 -0
  389. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1216_callout_reservation_measures_ink.py +0 -0
  390. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1216_pairwise_across_scale_groups.py +0 -0
  391. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1217_claimed_representations.py +0 -0
  392. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1219_location_claims_its_own_axis.py +0 -0
  393. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1229_ledger_member_keying.py +0 -0
  394. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1240_iso_above_strip_visibility.py +0 -0
  395. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1245_passage_disposition.py +0 -0
  396. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1246_prismatic_pocket_disposition.py +0 -0
  397. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1247_angled_step_disposition.py +0 -0
  398. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1254_turned_chamfers.py +0 -0
  399. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1260_view_constraints.py +0 -0
  400. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1262_automatic_turned_views.py +0 -0
  401. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1276_turned_leader_targets.py +0 -0
  402. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1281_turned_fillets.py +0 -0
  403. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1296_cylindrical_diameter_pmi.py +0 -0
  404. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1298_manufacturing_requirements.py +0 -0
  405. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1299_page_escalation.py +0 -0
  406. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1312_engine_costs.py +0 -0
  407. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1325_nominal_agreement.py +0 -0
  408. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1332_overlap_remedy.py +0 -0
  409. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1332_zone_labels.py +0 -0
  410. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1333_bounded_ink_repair.py +0 -0
  411. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1334_prevent_ink.py +0 -0
  412. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1336_grm03_ap242_pmi_fixture.py +0 -0
  413. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1338_scale_before_page_escalation.py +0 -0
  414. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1349_precision_display.py +0 -0
  415. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1350_detected_takeover.py +0 -0
  416. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1351_structured_note_coverage.py +0 -0
  417. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1352_searchable_pdf_text.py +0 -0
  418. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1353_cnc_authoritative_workflow.py +0 -0
  419. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1357_framed_activation.py +0 -0
  420. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1357_framed_boundary.py +0 -0
  421. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1357_plural_turned_profiles.py +0 -0
  422. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1357_pmi_frame.py +0 -0
  423. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1360_thread_depth.py +0 -0
  424. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1369_hole_completeness_evidence.py +0 -0
  425. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1370_countersink_completeness_evidence.py +0 -0
  426. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1370_double_d_completeness_evidence.py +0 -0
  427. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1370_hole_pattern_completeness_evidence.py +0 -0
  428. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1371_flat_completeness_evidence.py +0 -0
  429. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1371_polygonal_stock_completeness_evidence.py +0 -0
  430. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1372_groove_completeness_evidence.py +0 -0
  431. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1372_pad_completeness_evidence.py +0 -0
  432. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1372_pocket_completeness_evidence.py +0 -0
  433. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1372_pocket_pattern_completeness_evidence.py +0 -0
  434. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1372_polygonal_boss_completeness_evidence.py +0 -0
  435. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1373_plate_completeness_evidence.py +0 -0
  436. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1374_chamfer_completeness_evidence.py +0 -0
  437. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1374_fillet_completeness_evidence.py +0 -0
  438. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1374_turned_step_completeness_evidence.py +0 -0
  439. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1378_diameter_leader_targets.py +0 -0
  440. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1382_046_step_inventory.py +0 -0
  441. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1382_circular_blind_step_semantics.py +0 -0
  442. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1382_framed_step_family_evidence.py +0 -0
  443. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1382_paired_ramp_semantics.py +0 -0
  444. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1382_through_step_semantics.py +0 -0
  445. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1390_sheet_registration.py +0 -0
  446. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1392_recognisers_048.py +0 -0
  447. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1395_degenerate_iso_region.py +0 -0
  448. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1396_layout_advisories.py +0 -0
  449. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1397_unverifiable_requirement_message.py +0 -0
  450. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1421_rectangular_blind_slot_completeness.py +0 -0
  451. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1421_rectangular_blind_slot_semantics.py +0 -0
  452. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1421_round_bottom_blind_slot_completeness.py +0 -0
  453. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1421_round_bottom_blind_slot_semantics.py +0 -0
  454. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1432_adoption.py +0 -0
  455. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1432_boundary_failures.py +0 -0
  456. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1432_oriented_slot_semantics.py +0 -0
  457. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1433_blend_semantics.py +0 -0
  458. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_boss_ownership.py +0 -0
  459. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_channel_ownership.py +0 -0
  460. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_cli_report_sidecar.py +0 -0
  461. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_generation_snapshot.py +0 -0
  462. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_nested_ownership.py +0 -0
  463. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_occurrence_ownership.py +0 -0
  464. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_pattern_ownership.py +0 -0
  465. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_plate_ownership.py +0 -0
  466. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_policy_dispositions.py +0 -0
  467. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_report_projection.py +0 -0
  468. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_report_writer.py +0 -0
  469. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_through_step_ownership.py +0 -0
  470. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1438_turned_step_ownership.py +0 -0
  471. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1450_boss_blend_ownership.py +0 -0
  472. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1460_step_inspection.py +0 -0
  473. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1466_dimension_options.py +0 -0
  474. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1466_semantic_sides.py +0 -0
  475. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1471_boundary_failures.py +0 -0
  476. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1471_evidence_schema.py +0 -0
  477. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1471_groove_profile.py +0 -0
  478. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1471_section_recess_contract.py +0 -0
  479. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1471_section_recess_pockets.py +0 -0
  480. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1479_radius_leader_targets.py +0 -0
  481. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1485_curved_pockets.py +0 -0
  482. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1485_quiddity_024_boundary.py +0 -0
  483. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1485_rounded_pockets.py +0 -0
  484. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1504_angle_patterns.py +0 -0
  485. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1504_angular_references.py +0 -0
  486. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1504_angular_rendering.py +0 -0
  487. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1504_canonical_angles.py +0 -0
  488. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1504_profile_angles.py +0 -0
  489. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1505_diameter_coverage.py +0 -0
  490. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1505_short_axial_chains.py +0 -0
  491. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1511_turned_boss_heights.py +0 -0
  492. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1515_first_angle.py +0 -0
  493. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1516_dimension_text.py +0 -0
  494. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1517_through_indicator.py +0 -0
  495. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1518_explicit_rear.py +0 -0
  496. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1524_tolerance_magnitude.py +0 -0
  497. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1530_section_provenance.py +0 -0
  498. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1531_semantic_hole_counts.py +0 -0
  499. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1532_authored_section_examples.py +0 -0
  500. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1533_review_diagnostics.py +0 -0
  501. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1534_build_progress.py +0 -0
  502. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1536_title_overflow.py +0 -0
  503. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1542_applicability.py +0 -0
  504. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1542_catalog.py +0 -0
  505. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1542_catalog_families.py +0 -0
  506. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1542_claim_authority.py +0 -0
  507. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1542_document.py +0 -0
  508. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1542_document_claims.py +0 -0
  509. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1542_document_coverage.py +0 -0
  510. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1542_document_report.py +0 -0
  511. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1542_report_authority.py +0 -0
  512. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1542_requirement_carriers.py +0 -0
  513. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1543_feature_schedules.py +0 -0
  514. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1543_schedule_requirements.py +0 -0
  515. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_1544_frame_document_canary.py +0 -0
  516. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_367_leader_ink.py +0 -0
  517. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_443_grm03_axial_coverage.py +0 -0
  518. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_563_placement_intent.py +0 -0
  519. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_676_polygonal_boss.py +0 -0
  520. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_676_polygonal_boss_declare.py +0 -0
  521. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_740_leader_assignment.py +0 -0
  522. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_798_floor_cardinality.py +0 -0
  523. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_798_material_field.py +0 -0
  524. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_798_silhouette_lint.py +0 -0
  525. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_827_real_part_canary.py +0 -0
  526. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_883_location_identity.py +0 -0
  527. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_885_prismatic_coverage.py +0 -0
  528. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_909_sloped_profile.py +0 -0
  529. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_915_dense_case.py +0 -0
  530. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_916_pocket_leader.py +0 -0
  531. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_917_open_channel.py +0 -0
  532. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_924_zero_length_shoulders.py +0 -0
  533. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_955_height_contingency.py +0 -0
  534. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_issue_958_cross_solid_recognition.py +0 -0
  535. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_label_provenance.py +0 -0
  536. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_layout.py +0 -0
  537. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_layout_cleanliness.py +0 -0
  538. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_layout_hypothesis.py +0 -0
  539. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_layout_property.py +0 -0
  540. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_leader_footprint.py +0 -0
  541. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_lint_box_cache.py +0 -0
  542. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_lint_ink_overlap.py +0 -0
  543. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_lint_reconciliation.py +0 -0
  544. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_lint_structural.py +0 -0
  545. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_linting.py +0 -0
  546. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_location_vocabulary.py +0 -0
  547. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_note_verb.py +0 -0
  548. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_object_aspects.py +0 -0
  549. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_occupancy_boxes.py +0 -0
  550. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_overall_height_coverage.py +0 -0
  551. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_parameter_id.py +0 -0
  552. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_part_model.py +0 -0
  553. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_pitch_dim_footprint.py +0 -0
  554. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_pmi.py +0 -0
  555. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_pmi_datum_lowering.py +0 -0
  556. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_pmi_gtol_lowering.py +0 -0
  557. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_pmi_part21.py +0 -0
  558. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_pocket_pattern.py +0 -0
  559. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_pocket_pattern_recognition.py +0 -0
  560. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_principal_profile_classifier.py +0 -0
  561. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_private_test_attr_reads.py +0 -0
  562. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_private_test_imports.py +0 -0
  563. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_quality_components.py +0 -0
  564. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_recogniser_adoption.py +0 -0
  565. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_recogniser_capabilities.py +0 -0
  566. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_recogniser_contract.py +0 -0
  567. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_recognition_result.py +0 -0
  568. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_refactor_golden.py +0 -0
  569. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_registry.py +0 -0
  570. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_render_seam.py +0 -0
  571. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_repack_geometry_seam.py +0 -0
  572. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_score.py +0 -0
  573. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_script_detail_parity.py +0 -0
  574. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_shared_box_memo.py +0 -0
  575. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_sheet_gdt.py +0 -0
  576. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_sheet_identity_invariant.py +0 -0
  577. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_sheet_notes.py +0 -0
  578. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_sheet_of.py +0 -0
  579. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_sheet_section.py +0 -0
  580. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_sheet_tables.py +0 -0
  581. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_slanted_blind_step.py +0 -0
  582. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_slot_completeness.py +0 -0
  583. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_slot_pattern.py +0 -0
  584. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_slot_pattern_recognition.py +0 -0
  585. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_soft_deprecation.py +0 -0
  586. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_solve_trace.py +0 -0
  587. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_step_analysis_evaluation.py +0 -0
  588. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_strip_layout.py +0 -0
  589. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_suppression_ledger.py +0 -0
  590. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_suppression_marks.py +0 -0
  591. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_tolerances.py +0 -0
  592. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_turned_steps.py +0 -0
  593. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_version_bump_ci.py +0 -0
  594. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_view_plan.py +0 -0
  595. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_witness_label_reconciliation.py +0 -0
  596. {draftwright-0.4.26 → draftwright-0.4.27}/tests/test_workflows.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: draftwright
3
- Version: 0.4.26
3
+ Version: 0.4.27
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
@@ -9,7 +9,10 @@ with an underscore.
9
9
  Use `Sheet(part, projection="first")` or `build_drawing(part, projection="first")`
10
10
  for first-angle layout and its matching projection symbol. The CLI equivalent is
11
11
  `--projection first`. Explicit `"third"` selects third-angle layout and its symbol;
12
- omitting `projection` keeps third-angle layout without a symbol.
12
+ omitting `projection` uses third-angle layout and its symbol. Use
13
+ `projection_symbol=False` (CLI: `--no-projection-symbol`) to omit the symbol for an
14
+ embedded illustration; this does not change the projection convention or view layout.
15
+ The visibility choice also survives generated-script replay.
13
16
 
14
17
  View names retain their physical viewing directions in the working part frame. Changing
15
18
  convention changes sheet relationships, not which side of the part a name shows:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "draftwright"
7
- version = "0.4.26"
7
+ version = "0.4.27"
8
8
  description = "Automated technical-drawing generation for build123d"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -1260,9 +1260,10 @@ class Analysis:
1260
1260
  # Draw a sheet border/frame (#767). When True, `margin` is already the reserved content
1261
1261
  # margin (`_content_margin(True)`), so content clears the frame drawn at `_MARGIN`.
1262
1262
  frame: bool = False
1263
- # Projection-method symbol (#769): "third" / "first" (ISO 5456-2) or None (omit).
1263
+ # Requested convention; None resolves to third-angle. Symbol visibility is independent.
1264
1264
  projection: str | None = None
1265
1265
  projection_convention: str = "third"
1266
+ projection_symbol: bool = True
1266
1267
  text_position: str = "inline"
1267
1268
  text_orientation: str = "aligned"
1268
1269
  # Draw the ISO 5457 zone-grid border ruler (#768). Implies a frame (the ticks sit on it).
@@ -1481,11 +1482,15 @@ def _add_projection_symbol(dwg, a: Analysis):
1481
1482
  just above the drawn title block (deterministic empty space — the block reserves _TB_H but
1482
1483
  draws shorter). Registered ``projection_symbol`` with an ``is_projection_symbol`` identity
1483
1484
  rider. Unlike the page-spanning frame it is NOT lint-exempt: it's a small, well-placed glyph,
1484
- so lint covers it and a future mispositioning is caught. Gated on ``a.projection``."""
1485
+ so lint covers it and a future mispositioning is caught. Suppressed only by
1486
+ ``projection_symbol=False``."""
1487
+ if not a.projection_symbol:
1488
+ return
1489
+
1485
1490
  from build123d_drafting import ProjectionSymbol
1486
1491
 
1487
1492
  sym = ProjectionSymbol(
1488
- a.projection,
1493
+ a.projection_convention,
1489
1494
  draft=draft_preset(
1490
1495
  font_size=dwg.draft.font_size,
1491
1496
  decimal_precision=dwg.draft.decimal_precision,
@@ -1496,7 +1501,8 @@ def _add_projection_symbol(dwg, a: Analysis):
1496
1501
  bx, by = (b.min.X + b.max.X) / 2, (b.min.Y + b.max.Y) / 2
1497
1502
  w, h = b.max.X - b.min.X, b.max.Y - b.min.Y
1498
1503
  # Right side of the title-block column, near the top of its reserved band.
1499
- cx = a.PAGE_W - _TB_CLEAR - w / 2 - 3
1504
+ # Sheet frames reserve an inner content margin; keep furniture inside it too.
1505
+ cx = a.PAGE_W - max(_TB_CLEAR + 3, a.margin) - w / 2
1500
1506
  cy = _TB_CLEAR + _TB_H - h / 2 - 2
1501
1507
  sym = sym.locate(Location((cx - bx, cy - by, 0)))
1502
1508
  sym.is_projection_symbol = True
@@ -781,6 +781,7 @@ def _analyse(
781
781
  company="",
782
782
  frame: bool = False,
783
783
  projection: str | None = None,
784
+ projection_symbol: bool = True,
784
785
  text_position: str = "inline",
785
786
  text_orientation: str = "aligned",
786
787
  zones: bool = False,
@@ -1442,6 +1443,7 @@ def _analyse(
1442
1443
  company=company,
1443
1444
  frame=frame,
1444
1445
  projection=projection,
1446
+ projection_symbol=projection_symbol,
1445
1447
  text_position=text_position,
1446
1448
  text_orientation=text_orientation,
1447
1449
  projection_convention=convention,
@@ -900,8 +900,7 @@ def _auto_annotate(dwg, a: Analysis, *, detail_view: bool = False):
900
900
 
901
901
  def _s_projection_symbol():
902
902
  # ISO 5456-2 projection-method glyph (#769) in the reserved title-block band.
903
- if a.projection:
904
- _add_projection_symbol(dwg, a)
903
+ _add_projection_symbol(dwg, a)
905
904
 
906
905
  def _s_tabulate():
907
906
  # Escalate to a hole table when the plan view is too dense to dimension
@@ -787,8 +787,7 @@ def _assemble(
787
787
  _add_sheet_frame(dwg, a)
788
788
  if a.zones: # zone-grid ruler (#768), on the frame
789
789
  _add_zone_grid(dwg, a)
790
- if a.projection: # projection-method glyph (#769) — auto path adds it via the orchestrator
791
- _add_projection_symbol(dwg, a)
790
+ _add_projection_symbol(dwg, a)
792
791
 
793
792
  # The NTS caption is post-fit late furniture too, and goes FIRST: it is tied to the
794
793
  # iso block it labels, whereas a table may sit anywhere the sheet has room. Placing
@@ -1196,6 +1195,7 @@ def _build_drawing_once(
1196
1195
  company: str = "",
1197
1196
  frame: bool = False,
1198
1197
  projection: str | None = None,
1198
+ projection_symbol: bool = True,
1199
1199
  zones: bool = False,
1200
1200
  reproducible: bool = False,
1201
1201
  framed_recognition: bool = False,
@@ -1336,6 +1336,7 @@ def _build_drawing_once(
1336
1336
  company=company,
1337
1337
  frame=frame,
1338
1338
  projection=projection,
1339
+ projection_symbol=projection_symbol,
1339
1340
  text_position=text_position,
1340
1341
  text_orientation=text_orientation,
1341
1342
  zones=zones,
@@ -1912,6 +1913,8 @@ def build_drawing(
1912
1913
  _include_iso: bool = True,
1913
1914
  _view_constraints=None,
1914
1915
  _document_input=None,
1916
+ *,
1917
+ projection_symbol: bool = True,
1915
1918
  ) -> Drawing:
1916
1919
  """Build a drawing, protecting required annotations under an explicit scale.
1917
1920
 
@@ -1926,14 +1929,14 @@ def build_drawing(
1926
1929
  recognition frame. Raw remains the default. Other arguments and return semantics are
1927
1930
  unchanged from the one-pass builder.
1928
1931
 
1929
- ``projection='third'`` adds the matching projection symbol. The default omits the
1930
- symbol but uses the same third-angle layout. ``projection='first'`` places plan below
1932
+ Third-angle layout and its matching projection symbol are the default.
1933
+ ``projection_symbol=False`` suppresses only the symbol. ``projection='first'`` places plan below
1931
1934
  front and side to its left, keeping the physical viewing directions unchanged.
1932
1935
 
1933
1936
  ``text_position="inline"|"above"`` and ``text_orientation="aligned"|"horizontal"``
1934
1937
  independently select dimension typography. Defaults preserve existing appearance.
1935
1938
  """
1936
- validate_projection(projection)
1939
+ validate_projection(projection, projection_symbol=projection_symbol)
1937
1940
  _dimension_draft(text_position, text_orientation)
1938
1941
  if scale_policy not in {"strict", "fallback", "permissive"}:
1939
1942
  raise ValueError(
@@ -1964,6 +1967,7 @@ def build_drawing(
1964
1967
  company=company,
1965
1968
  frame=frame,
1966
1969
  projection=projection,
1970
+ projection_symbol=projection_symbol,
1967
1971
  text_position=text_position,
1968
1972
  text_orientation=text_orientation,
1969
1973
  zones=zones,
@@ -2855,6 +2859,8 @@ def make_drawing(
2855
2859
  framed_recognition: bool = False,
2856
2860
  text_position: str = "inline",
2857
2861
  text_orientation: str = "aligned",
2862
+ *,
2863
+ projection_symbol: bool = True,
2858
2864
  ) -> tuple[str, str]:
2859
2865
  """Generate a 4-view technical drawing from a STEP file or build123d object.
2860
2866
 
@@ -2919,6 +2925,7 @@ def make_drawing(
2919
2925
  company=company,
2920
2926
  frame=frame,
2921
2927
  projection=projection,
2928
+ projection_symbol=projection_symbol,
2922
2929
  text_position=text_position,
2923
2930
  text_orientation=text_orientation,
2924
2931
  zones=zones,
@@ -171,7 +171,12 @@ def main(
171
171
  projection: str = typer.Option(
172
172
  "",
173
173
  "--projection",
174
- help="Projection convention: 'first' or 'third' (default: third-angle, no symbol)",
174
+ help="Projection convention: 'first' or 'third' (default: third-angle)",
175
+ ),
176
+ projection_symbol: bool = typer.Option(
177
+ True,
178
+ "--projection-symbol/--no-projection-symbol",
179
+ help="Show the symbol for the selected projection convention",
175
180
  ),
176
181
  text_position: str = typer.Option("inline", help="Dimension text position: inline or above"),
177
182
  text_orientation: str = typer.Option(
@@ -294,6 +299,7 @@ def main(
294
299
  frame=frame,
295
300
  zones=zones,
296
301
  projection=projection or None,
302
+ projection_symbol=projection_symbol,
297
303
  text_position=text_position,
298
304
  text_orientation=text_orientation,
299
305
  part_expr=source.seam,
@@ -320,6 +326,7 @@ def main(
320
326
  frame=frame,
321
327
  zones=zones,
322
328
  projection=projection or None,
329
+ projection_symbol=projection_symbol,
323
330
  text_position=text_position,
324
331
  text_orientation=text_orientation,
325
332
  pmi=pmi.value if pmi is not None else "off",
@@ -355,6 +362,7 @@ def main(
355
362
  company=company,
356
363
  frame=frame,
357
364
  projection=projection or None,
365
+ projection_symbol=projection_symbol,
358
366
  text_position=text_position,
359
367
  text_orientation=text_orientation,
360
368
  zones=zones,
@@ -1110,12 +1110,13 @@ class Sheet:
1110
1110
  company=None,
1111
1111
  frame=None,
1112
1112
  projection=None,
1113
+ projection_symbol=True,
1113
1114
  text_position="inline",
1114
1115
  text_orientation="aligned",
1115
1116
  zones=None,
1116
1117
  detail_view=None,
1117
1118
  ):
1118
- validate_projection(projection)
1119
+ validate_projection(projection, projection_symbol=projection_symbol)
1119
1120
  _dimension_draft(text_position, text_orientation)
1120
1121
  self._part = part
1121
1122
  # (token, feature) entries — identity, not position (#908). `_features` is the
@@ -1201,6 +1202,7 @@ class Sheet:
1201
1202
  ("company", company),
1202
1203
  ("frame", frame),
1203
1204
  ("projection", projection),
1205
+ ("projection_symbol", projection_symbol),
1204
1206
  ("text_position", text_position),
1205
1207
  ("text_orientation", text_orientation),
1206
1208
  ("zones", zones),
@@ -2084,6 +2084,7 @@ def emit_sheet_script(
2084
2084
  frame: bool = False,
2085
2085
  zones: bool = False,
2086
2086
  projection: str | None = None,
2087
+ projection_symbol: bool = True,
2087
2088
  text_position: str = "inline",
2088
2089
  text_orientation: str = "aligned",
2089
2090
  object_ref: bool = False,
@@ -2130,6 +2131,7 @@ def emit_sheet_script(
2130
2131
  declaration a person edits; evidence about the run that produced it belongs in the sidecar
2131
2132
  document beside it, where a reader can diff or re-read it without parsing Python (#1460)."""
2132
2133
  _validate_scale_policy(scale, scale_policy)
2134
+ validate_projection(projection, projection_symbol=projection_symbol)
2133
2135
  _dimension_draft(text_position, text_orientation)
2134
2136
  # The script declares this model — `model` plus an envelope when the overall height would
2135
2137
  # otherwise be unnameable under the mirrored (authored) set. BEFORE the import scan, since
@@ -2216,6 +2218,8 @@ def emit_sheet_script(
2216
2218
  ctor.append("zones=True")
2217
2219
  if projection:
2218
2220
  ctor.append(f"projection={projection!r}")
2221
+ if not projection_symbol:
2222
+ ctor.append("projection_symbol=False")
2219
2223
  if text_position != "inline":
2220
2224
  ctor.append(f"text_position={text_position!r}")
2221
2225
  if text_orientation != "aligned":
@@ -2480,6 +2484,7 @@ def generate_sheet_script(
2480
2484
  frame: bool = False,
2481
2485
  zones: bool = False,
2482
2486
  projection: str | None = None,
2487
+ projection_symbol: bool = True,
2483
2488
  text_position: str = "inline",
2484
2489
  text_orientation: str = "aligned",
2485
2490
  pmi: Literal["off", "report", "annotate"] = "off",
@@ -2500,7 +2505,7 @@ def generate_sheet_script(
2500
2505
  surface (flagged inline).
2501
2506
  *part_expr*, when given, overrides the ``part = …`` seam — e.g. the import seam from
2502
2507
  :func:`resolve_object_spec` so the script references a live module (#469)."""
2503
- validate_projection(projection)
2508
+ validate_projection(projection, projection_symbol=projection_symbol)
2504
2509
  _validate_scale_policy(scale, scale_policy)
2505
2510
  _dimension_draft(text_position, text_orientation)
2506
2511
  is_shape = isinstance(step_file, Shape)
@@ -2578,6 +2583,7 @@ def generate_sheet_script(
2578
2583
  frame=frame,
2579
2584
  zones=zones,
2580
2585
  projection=projection,
2586
+ projection_symbol=projection_symbol,
2581
2587
  text_position=text_position,
2582
2588
  text_orientation=text_orientation,
2583
2589
  pmi=pmi,
@@ -2607,6 +2613,7 @@ def generate_sheet_script(
2607
2613
  frame=frame,
2608
2614
  zones=zones,
2609
2615
  projection=projection,
2616
+ projection_symbol=projection_symbol,
2610
2617
  text_position=text_position,
2611
2618
  text_orientation=text_orientation,
2612
2619
  object_ref=is_shape,
@@ -32,8 +32,10 @@ from types import MappingProxyType
32
32
  from typing import Any
33
33
 
34
34
 
35
- def validate_projection(projection: str | None) -> None:
36
- """Validate the supported convention names before loading drawing input."""
35
+ def validate_projection(projection: str | None, *, projection_symbol: bool = True) -> None:
36
+ """Validate projection convention and symbol visibility before loading drawing input."""
37
+ if not isinstance(projection_symbol, bool):
38
+ raise ValueError("projection_symbol must be a boolean")
37
39
  if projection not in (None, "", "first", "third"):
38
40
  raise ValueError(f"unknown projection {projection!r}; expected 'first' or 'third'")
39
41
 
@@ -1151,7 +1151,7 @@ class TestOmittedDimensionsDoNotRender:
1151
1151
 
1152
1152
  drawn = _names(sheet.build())
1153
1153
  assert "m_env_width" in drawn, "the one authored measurement"
1154
- furniture = ("m_cm", "m_locx", "m_locy", "note_", "title_block")
1154
+ furniture = ("m_cm", "m_locx", "m_locy", "note_", "title_block", "projection_symbol")
1155
1155
  assert not [n for n in drawn if n != "m_env_width" and not n.startswith(furniture)], (
1156
1156
  f"an unauthored dimension reached the page: {sorted(drawn)}"
1157
1157
  )
@@ -43,6 +43,7 @@ _VALUE_FREE = (
43
43
  "m_cm", # centre marks — sized off the hole they mark (#875)
44
44
  "note_", # the ISO NTS note
45
45
  "title_block",
46
+ "projection_symbol", # identifies the view convention; no feature measurement
46
47
  "section_", # cutting-plane arrows and label
47
48
  "hatch",
48
49
  "detail_marker",
@@ -1901,7 +1901,7 @@ def test_automatic_table_preserves_authored_through_wording(indicator, projectio
1901
1901
  for feature in model.features
1902
1902
  ]
1903
1903
  drawing = build_drawing(part, model=model, page="A3", projection=projection)
1904
- assert ("projection_symbol" in drawing.annotations()) is (projection is not None)
1904
+ assert drawing.get_annotation("projection_symbol").method == (projection or "third")
1905
1905
  assert "hole_table_plan" in drawing.annotations()
1906
1906
  table = drawing.get_annotation("hole_table_plan")
1907
1907
  depth_column = table.table_rows[0].index("DEPTH")
@@ -375,9 +375,10 @@ class TestNoMeasuredAnnotationEscapesUnclaimed:
375
375
 
376
376
  @pytest.mark.slow
377
377
  def test_the_furniture_really_is_silent(self):
378
- # The other side of the same claim: on nist_ctc_02 the 89 unclaimed annotations are
379
- # centre marks, bolt circles, notes and the title block. The allow-list is exactly the
380
- # four types measured there — a wider set asserts nothing about types that never occur
378
+ # The other side of the same claim: on nist_ctc_02 the silent annotations are
379
+ # centre marks, bolt circles, notes, the projection symbol and the title block.
380
+ # The allow-list is exactly the types observed — a wider set asserts nothing about
381
+ # types that never occur
381
382
  # (#1225 review, finding 7).
382
383
  #
383
384
  # "Silent" here means silent TO THE READER, and the title block is the honest edge of
@@ -387,7 +388,7 @@ class TestNoMeasuredAnnotationEscapesUnclaimed:
387
388
  # exactly the limit `evidence.py` now states rather than the stronger one it claimed.
388
389
  #
389
390
  # Built with a title on purpose: without `title=`/`number=` no TitleBlock is placed at
390
- # all (88 silent annotations, not 89), and the test would then characterise a sheet the
391
+ # all, and the test would then characterise a sheet the
391
392
  # ratchet never sweeps.
392
393
  drawing = _drawing(
393
394
  "tests/fixtures/nist_ctc_02_asme1_ap203.stp",
@@ -400,4 +401,10 @@ class TestNoMeasuredAnnotationEscapesUnclaimed:
400
401
  and not rendered_numbers(drawing.registry.named(n))
401
402
  ]
402
403
  assert len(silent) > 50, f"too little furniture to characterise: {len(silent)}"
403
- assert set(silent) == {"CenterMark", "CenterlineCircle", "Note", "TitleBlock"}, set(silent)
404
+ assert set(silent) == {
405
+ "CenterMark",
406
+ "CenterlineCircle",
407
+ "Note",
408
+ "ProjectionSymbol",
409
+ "TitleBlock",
410
+ }, set(silent)
@@ -225,7 +225,10 @@ def test_analytical_machined_leaders_preserve_the_occ_measured_drawing(fixture,
225
225
  # This golden isolates analytical-vs-OCC leader lowering. Keep the established principal
226
226
  # topology explicit so automatic redundant-view selection is not mistaken for a leader
227
227
  # geometry change (and so the recorded page coordinates remain meaningful).
228
- drawing = build_drawing(FIXTURES / fixture, _views=("front", "plan", "side"))
228
+ # Keep the original furniture policy explicit in this leader-geometry comparison.
229
+ drawing = build_drawing(
230
+ FIXTURES / fixture, _views=("front", "plan", "side"), projection_symbol=False
231
+ )
229
232
  actual = {}
230
233
  for name, annotation in drawing.iter_annotations():
231
234
  box = annotation.bounding_box()
@@ -39,7 +39,7 @@ def test_supported_layout_retains_third_angle_relationships(asymmetric_plate, pr
39
39
  front, plan, side = (drawing.view_bounds(v) for v in ("front", "plan", "side"))
40
40
  assert plan[1] > front[3]
41
41
  assert side[0] > front[2]
42
- assert ("projection_symbol" in drawing.annotations()) == (projection == "third")
42
+ assert drawing.get_annotation("projection_symbol").method == "third"
43
43
 
44
44
 
45
45
  @pytest.mark.parametrize("script", [False, True])
@@ -3318,13 +3318,15 @@ def test_make_drawing_module_entrypoint_runs_cli_help():
3318
3318
  capture_output=True,
3319
3319
  env=env,
3320
3320
  text=True,
3321
+ encoding="cp1252", # match the child's explicit PYTHONIOENCODING
3321
3322
  )
3322
3323
 
3323
3324
  assert result.returncode == 0, f"stdout:\n{result.stdout}\nstderr:\n{result.stderr}"
3324
3325
  assert "Usage:" in result.stdout # Typer/rich help capitalises (was argparse "usage:")
3325
3326
  assert "step_file" in result.stdout
3326
- # rich degrades its box-drawing to ASCII on a cp1252 stream, so help stays safe.
3327
- assert result.stdout.isascii()
3327
+ # Rich degrades unsupported box drawing on cp1252 streams. Long flag names may
3328
+ # use a representable ellipsis, so safe cp1252 output need not be entirely ASCII.
3329
+ assert not any(glyph in result.stdout for glyph in "╭╮╰╯│─")
3328
3330
 
3329
3331
 
3330
3332
  def test_cli_version_reports_installed_version():
@@ -3765,7 +3767,7 @@ def test_build_drawing_auto_dims_false():
3765
3767
  # cylinder's iso is rescaled off sheet scale — the truthful "ISO VIEW (NTS)" note. The
3766
3768
  # note is furniture, not a dimension, so it belongs here (script↔CLI parity); auto_dims
3767
3769
  # still suppresses every *dimension*.
3768
- assert set(dwg.annotations()) == {"title_block", "note_iso_nts"}
3770
+ assert set(dwg.annotations()) == {"title_block", "note_iso_nts", "projection_symbol"}
3769
3771
 
3770
3772
 
3771
3773
  @pytest.mark.timeout(60)
@@ -11256,9 +11258,9 @@ class TestProjectionSymbol:
11256
11258
  """#769: the ISO 5456-2 projection-method glyph (third/first-angle) in the reserved
11257
11259
  title-block band, from the helpers 0.14.1 ProjectionSymbol primitive."""
11258
11260
 
11259
- def test_off_by_default(self):
11261
+ def test_third_angle_symbol_by_default(self):
11260
11262
  dwg = build_drawing(Box(80, 60, 20))
11261
- assert "projection_symbol" not in dwg.annotations()
11263
+ assert dwg.get_annotation("projection_symbol").method == "third"
11262
11264
  assert dwg._analysis.projection is None
11263
11265
 
11264
11266
  def test_third_renders_in_the_title_block_band(self):
@@ -0,0 +1,164 @@
1
+ """Projection furniture identifies the resolved layout, including implicit defaults."""
2
+
3
+ from inspect import Parameter, signature
4
+ from pathlib import Path
5
+
6
+ import pytest
7
+ from build123d import Box, Cylinder, Pos, export_step
8
+ from typer.testing import CliRunner
9
+
10
+ from draftwright import Drawing, Sheet, build_drawing, make_drawing
11
+ from draftwright.audit import compare_measurements
12
+ from draftwright.sheet_emit import emit_sheet_script, generate_sheet_script
13
+
14
+
15
+ @pytest.fixture(scope="module")
16
+ def plate():
17
+ part = Box(50, 35, 12) - Pos(-13, -8, 0) * Cylinder(3, 20)
18
+ model = Sheet.from_part(part).model()
19
+ assert len([f for f in model.features if f.kind == "hole"]) == 1
20
+ return part, model
21
+
22
+
23
+ @pytest.mark.parametrize("projection", [None, "first", "third"])
24
+ @pytest.mark.parametrize("auto_dims", [True, False])
25
+ def test_visibility_changes_only_furniture(plate, projection, auto_dims):
26
+ part, model = plate
27
+ options = dict(model=model, projection=projection, auto_dims=auto_dims, page="A3", scale=1)
28
+ shown = build_drawing(part, **options)
29
+ hidden = build_drawing(part, projection_symbol=False, **options)
30
+ symbol = shown.get_annotation("projection_symbol")
31
+ assert symbol.method == shown.view_plan.convention == (projection or "third")
32
+ assert symbol.edges()
33
+ assert set(shown.annotations()) - set(hidden.annotations()) == {"projection_symbol"}
34
+ assert not set(hidden.annotations()) - set(shown.annotations())
35
+ assert shown.view_plan == hidden.view_plan
36
+ assert all(shown.view_bounds(v) == hidden.view_bounds(v) for v in shown.views)
37
+ if auto_dims:
38
+ assert compare_measurements(shown, hidden)["status"] == "preserved"
39
+ assert not [i for i in shown.lint() if i.severity == "error"]
40
+
41
+
42
+ @pytest.mark.parametrize("projection", [None, "first", "third"])
43
+ @pytest.mark.parametrize("visible", [True, False])
44
+ def test_generated_script_replays_symbol_policy(plate, projection, visible, tmp_path, monkeypatch):
45
+ part, model = plate
46
+ script = emit_sheet_script(
47
+ model,
48
+ "part = supplied_part",
49
+ str(tmp_path / "drawing"),
50
+ title="PROJECTION",
51
+ number="PROJECTION-1",
52
+ projection=projection,
53
+ projection_symbol=visible,
54
+ page="A3",
55
+ scale=1,
56
+ )
57
+ assert ("projection_symbol=False" in script) is (not visible)
58
+ captured = []
59
+ monkeypatch.setattr(Drawing, "export", lambda self, *a, **kw: captured.append(self))
60
+ exec(compile(script, "projection-example.py", "exec"), {"supplied_part": part})
61
+ (drawing,) = captured
62
+ assert drawing.view_plan.convention == (projection or "third")
63
+ assert ("projection_symbol" in drawing.annotations()) is visible
64
+ if visible:
65
+ assert drawing.get_annotation("projection_symbol").method == drawing.view_plan.convention
66
+
67
+
68
+ @pytest.mark.parametrize("entry", [build_drawing, make_drawing, Sheet, generate_sheet_script])
69
+ @pytest.mark.parametrize("invalid", [None, "false", 0])
70
+ def test_invalid_visibility_refused_before_loading_input(entry, invalid, tmp_path):
71
+ with pytest.raises(ValueError, match="projection_symbol must be a boolean"):
72
+ entry(str(tmp_path / "missing.step"), projection_symbol=invalid)
73
+ assert not list(tmp_path.iterdir())
74
+
75
+
76
+ @pytest.mark.parametrize("route", ["direct", "step_script", "object_script"])
77
+ @pytest.mark.parametrize("visible", [True, False])
78
+ def test_cli_policy_reaches_rendered_exports(route, visible, plate, tmp_path, monkeypatch):
79
+ from draftwright import cli
80
+
81
+ part, _ = plate
82
+ source = tmp_path / "plate.step"
83
+ export_step(part, source)
84
+ if route == "object_script":
85
+ source = tmp_path / "plate_source.py"
86
+ source.write_text("from build123d import Box\npart = Box(50, 35, 12)\n")
87
+ source = f"{source}:part"
88
+ drawings = []
89
+ original_export = Drawing.export
90
+
91
+ def capture(self, *args, **kwargs):
92
+ drawings.append(self)
93
+ return original_export(self, *args, **kwargs)
94
+
95
+ monkeypatch.setattr(Drawing, "export", capture)
96
+ stem = tmp_path / "result"
97
+ args = [str(source), "--out", str(stem), "--no-report", "--format", "svg,pdf,dxf"]
98
+ if not visible:
99
+ args.append("--no-projection-symbol")
100
+ if route != "direct":
101
+ args.append("--script")
102
+ result = CliRunner().invoke(cli.app, args)
103
+ assert result.exit_code == 0, result.output
104
+ if route != "direct":
105
+ script = stem.with_suffix(".py").read_text()
106
+ assert ("projection_symbol=False" in script) is (not visible)
107
+ exec(compile(script, str(stem.with_suffix(".py")), "exec"), {})
108
+ assert drawings
109
+ for drawing in drawings:
110
+ assert drawing.view_plan.convention == "third"
111
+ assert ("projection_symbol" in drawing.annotations()) is visible
112
+ for suffix in ("svg", "pdf", "dxf"):
113
+ assert Path(f"{stem}.{suffix}").stat().st_size > 100
114
+
115
+
116
+ @pytest.mark.parametrize(
117
+ ("entry", "previous"),
118
+ [
119
+ (
120
+ build_drawing,
121
+ "step_file out title number tolerance drawn_by scale page auto_dims "
122
+ "detail_view pmi repair assembly model decorations requested authored trace material "
123
+ "date revision company frame projection zones scale_policy reproducible "
124
+ "framed_recognition text_position text_orientation _post_build _required_tables "
125
+ "_views _include_iso _view_constraints _document_input",
126
+ ),
127
+ (
128
+ make_drawing,
129
+ "step_file out title number tolerance drawn_by scale page auto_dims "
130
+ "detail_view pmi assembly material date revision company frame projection zones "
131
+ "scale_policy reproducible framed_recognition text_position text_orientation",
132
+ ),
133
+ ],
134
+ )
135
+ def test_existing_positional_arguments_keep_their_bindings(entry, previous):
136
+ names = previous.split()
137
+ sentinels = [object() for _ in names]
138
+ bound = signature(entry).bind(*sentinels)
139
+ assert bound.arguments == dict(zip(names, sentinels, strict=True))
140
+ assert signature(entry).parameters["projection_symbol"].kind is Parameter.KEYWORD_ONLY
141
+
142
+
143
+ @pytest.mark.parametrize("projection", ["first", "third"])
144
+ @pytest.mark.parametrize("border", [{"frame": True}, {"zones": True}])
145
+ def test_symbol_clears_framed_content_margin(plate, projection, border):
146
+ part, model = plate
147
+ drawing = build_drawing(part, model=model, projection=projection, **border)
148
+ symbol = drawing.get_annotation("projection_symbol")
149
+ assert symbol.method == projection
150
+ # The drawn frame is 10 mm in; content reserves another 6 mm inside it.
151
+ frame = drawing.get_annotation("sheet_frame").bounding_box()
152
+ box = symbol.bounding_box()
153
+ assert box.min.X >= frame.min.X + 6 - 0.1
154
+ assert box.max.X <= frame.max.X - 6 + 0.1
155
+ assert box.min.Y >= frame.min.Y + 6 - 0.1
156
+ assert box.max.Y <= frame.max.Y - 6 + 0.1
157
+ hidden = build_drawing(
158
+ part, model=model, projection=projection, projection_symbol=False, **border
159
+ )
160
+ # A frame can already trigger label/centreline critique. Enabling its projection
161
+ # symbol must not add a finding; do not pretend the whole fixture was lint-clean.
162
+ assert [(i.severity, i.code, i.message) for i in drawing.lint()] == [
163
+ (i.severity, i.code, i.message) for i in hidden.lint()
164
+ ]
@@ -2359,7 +2359,11 @@ class TestAuthoredSetRoundTrips:
2359
2359
  regenerated = self._run(src, part)["sheet"].build()
2360
2360
 
2361
2361
  def dims(dwg):
2362
- return {n for n, _ in dwg.iter_annotations() if not n.startswith(("note_", "title"))}
2362
+ return {
2363
+ n
2364
+ for n, _ in dwg.iter_annotations()
2365
+ if not n.startswith(("note_", "title", "projection_symbol"))
2366
+ }
2363
2367
 
2364
2368
  assert dims(regenerated) == dims(direct), (
2365
2369
  "the regenerated script draws a different set from the model it came from"
@@ -2454,7 +2458,11 @@ class TestAuthoredSetRoundTrips:
2454
2458
  regenerated = self._run(src, part)["sheet"].build()
2455
2459
 
2456
2460
  def dims(dwg):
2457
- return {n for n, _ in dwg.iter_annotations() if not n.startswith(("note_", "title"))}
2461
+ return {
2462
+ n
2463
+ for n, _ in dwg.iter_annotations()
2464
+ if not n.startswith(("note_", "title", "projection_symbol"))
2465
+ }
2458
2466
 
2459
2467
  assert dims(regenerated) == dims(direct) == set(), (
2460
2468
  "an empty authored set draws no generated dimensions, on both paths"
@@ -2861,6 +2869,7 @@ class TestTheDimensionMirror:
2861
2869
  #: purpose: adding one fails loudly, and whoever adds it names the annotation with the real
2862
2870
  #: name in front of them.
2863
2871
  _SCRIPT_FURNITURE = {
2872
+ "projection_symbol": "projection convention; no feature measurement",
2864
2873
  "m_cm": "centre marks — sized off the hole they mark, not a printed value (#875)",
2865
2874
  "centerline_front": "shows where the front view's axis is; no measurement",
2866
2875
  "centerline_plan": "shows where the plan view's axis is; no measurement",
@@ -4315,7 +4324,7 @@ def test_the_object_reference_doc_example_actually_runs(tmp_path):
4315
4324
  assert f"`{view}`" in section, view
4316
4325
 
4317
4326
  names = sorted(ast.literal_eval(out["ANNOT"]))
4318
- assert len(names) == 11 and "Eleven annotations" in section, names
4327
+ assert len(names) == 12 and "Twelve annotations" in section, names
4319
4328
  for name in names:
4320
4329
  assert f"`{name}`" in section, f"{name} is on the sheet but the doc does not list it"
4321
4330
 
File without changes
File without changes
File without changes