Skip to content

Name the bad point when a draw function gets malformed points - #2972

Merged
pvcraven merged 1 commit into
developmentfrom
point-list-validation
Oct 9, 2026
Merged

pvcraven merged 1 commit into
developmentfrom
point-list-validation

Conversation

@pvcraven

@pvcraven pvcraven commented Oct 9, 2026

Copy link
Copy Markdown
Member

Closes #2215

draw_lines, draw_points, draw_line_strip, draw_polygon_filled and draw_polygon_outline now raise a ValueError naming the first bad point:

ValueError: point_list[2] is 7, but each point must be 2 numbers, such as (x, y)

Before:

  • A bad point raised 'int' object is not iterable, 'int' object is not subscriptable, or Value after * must be an iterable, not int, depending on the function.
  • In draw_lines, draw_points and thin draw_line_strip, a point with 1 or 3 numbers (such as a Vec3) didn't raise anything. It shifted every number after it, so the drawing came out scrambled.

No cost to drawing speed

  • _flatten_points() in arcade/draw/helpers.py wraps the existing conversion in try, then compares the array's length with twice the number of points. That's one comparison per call, however many points there are, and it catches 1- and 3-number points. The scan that finds which point is bad only runs after something went wrong.
  • The thick-line and polygon paths already loop over the points in Python. They only call the same scan when an error is raised.
  • Points are now flattened with array.array("f", tuple(chain.from_iterable(point_list))), which is about twice as fast as the generator draw_lines and draw_points used. So drawing got faster.

Measured in a hidden window, µs per call (best of 5 × 300 calls; draw_line_strip is the median of 15 runs, from two rounds):

development this PR
draw_lines, 4 points 51 50
draw_lines, 1,000 points 137–140 89–91
draw_points, 1,000 points 137–139 93–94
draw_line_strip, 100 points 76–83 60–78
draw_line_strip, 1,000 points 190–220 155–161

Most of a small call is fixed GPU overhead (about 50 µs), so the speedup shows with many points.

Notes

  • The thick-line paths (draw_line_strip with a width other than 1, draw_polygon_outline) and draw_polygon_filled read point[0] and point[1], so a 3-number point still works there by ignoring z, as before. They only raise for points that aren't at least 2 numbers. draw_polygon_outline used to fail on a Vec3 with an argument-count error. It now raises the clear error, because the polygon loop unpacks the whole point.
  • The exception type changes from TypeError to ValueError, as the issue asked.
  • The shape list functions (arcade.shape_list.create_lines and so on) aren't changed.

Tests

tests/unit/draw/test_point_validation.py:

  • _flatten_points with tuples, Vec2, an empty list, and the bad cases (a non-point, 1 number, 3 numbers, a string).
  • All 5 draw functions (both draw_line_strip paths) with good tuples, good Vec2s, and a bad point.
  • On development the 6 draw-function tests fail with the old TypeErrors.

The full test suite (1851), ruff, mypy and pyright pass.

🤖 Generated with Claude Code

draw_lines, draw_points, draw_line_strip, draw_polygon_filled and
draw_polygon_outline raise a ValueError naming the first point that
isn't 2 numbers. Before, a bad point raised errors like "'int' object
is not iterable", and a point with 1 or 3 numbers silently shifted the
rest of the data.

The check is one length comparison per call; the slow scan only runs
after something went wrong. Points are now flattened with
tuple(chain.from_iterable(...)), which is about twice as fast as the
generator it replaces, so drawing 1,000 lines or points got faster.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pvcraven
pvcraven merged commit a392f25 into development Oct 9, 2026
7 checks passed
@pvcraven
pvcraven deleted the point-list-validation branch October 9, 2026 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add clearer 2D point validation for 2D drawing functions

1 participant