-
-
Notifications
You must be signed in to change notification settings - Fork 33.3k
[3.13] gh-138772: Add tests for Turtle.dot() signature (GH-138773) #140992
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
b20464e
142507e
05d6bb6
d19be39
7f7d4d3
4630023
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| import pickle | ||
| import unittest | ||
| from unittest.mock import MagicMock, patch | ||
| from test import support | ||
| from test.support import import_helper | ||
| from test.support import os_helper | ||
|
|
@@ -50,6 +51,34 @@ | |
| """ | ||
|
|
||
|
|
||
| def patch_screen(): | ||
| """Patch turtle._Screen for testing without a display. | ||
|
|
||
| We must patch the _Screen class itself instead of the _Screen | ||
| instance because instantiating it requires a display. | ||
| """ | ||
| # Create a mock screen that delegates color validation to the real TurtleScreen methods | ||
| mock_screen = MagicMock() | ||
JanEricNitschke marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| mock_screen.__class__ = turtle._Screen | ||
| mock_screen.mode.return_value = "standard" | ||
| mock_screen._colormode = 1.0 | ||
|
|
||
| def mock_iscolorstring(color): | ||
| valid_colors = {'red', 'green', 'blue', 'black', 'white', 'yellow', | ||
| 'orange', 'purple', 'pink', 'brown', 'gray', 'grey', | ||
| 'cyan', 'magenta'} | ||
|
|
||
| return color in valid_colors or (isinstance(color, str) and color.startswith('#')) | ||
|
|
||
| mock_screen._iscolorstring = mock_iscolorstring | ||
| mock_screen._colorstr = turtle._Screen._colorstr.__get__(mock_screen) | ||
|
|
||
| return patch( | ||
JanEricNitschke marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| "turtle._Screen.__new__", | ||
| return_value=mock_screen | ||
| ) | ||
|
|
||
|
|
||
| class TurtleConfigTest(unittest.TestCase): | ||
|
|
||
| def get_cfg_file(self, cfg_str): | ||
|
|
@@ -461,6 +490,38 @@ def test_teleport(self): | |
| self.assertTrue(tpen.isdown()) | ||
|
|
||
|
|
||
| class TestTurtle(unittest.TestCase): | ||
| def setUp(self): | ||
| with patch_screen(): | ||
| self.turtle = turtle.Turtle() | ||
|
|
||
| # Reset the Screen singleton to avoid reference leaks | ||
| self.addCleanup(setattr, turtle.Turtle, '_screen', None) | ||
|
|
||
| def test_dot_signature(self): | ||
| self.turtle.dot() | ||
| self.turtle.dot(10) | ||
| self.turtle.dot(size=10) | ||
| self.turtle.dot((0, 0, 0)) | ||
| self.turtle.dot(size=(0, 0, 0)) | ||
| self.turtle.dot("blue") | ||
| self.turtle.dot("") | ||
| self.turtle.dot(size="blue") | ||
| self.turtle.dot(20, "blue") | ||
| self.turtle.dot(20, "blue") | ||
| self.turtle.dot(20, (0, 0, 0)) | ||
| self.turtle.dot(20, 0, 0, 0) | ||
| with self.assertRaises(TypeError): | ||
| self.turtle.dot(color="blue") | ||
|
Comment on lines
+509
to
+515
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These lines self.turtle.dot(size="blue")and with self.assertRaises(TypeError):
self.turtle.dot(color="blue")are surprising. I've tested these and it worked as here, but it doesn't make sense. (just checked before open a new issue)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it is a bit weird, but the actual logic is: def dot(self, size=None, *color):
"""Draw a dot with diameter size, using color.
Optional arguments:
size -- an integer >= 1 (if given)
color -- a colorstring or a numeric color tuple
Draw a circular dot with diameter size, using color.
If size is not given, the maximum of pensize+4 and 2*pensize is used.
Example (for a Turtle instance named turtle):
>>> turtle.dot()
>>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
"""
if not color:
if isinstance(size, (str, tuple)):
color = self._colorstr(size)
size = self._pensize + max(self._pensize, 4)
else:
color = self._pencolor
if not size:
size = self._pensize + max(self._pensize, 4)
else:
if size is None:
size = self._pensize + max(self._pensize, 4)
color = self._colorstr(color)And the correct matching typehint is @overload
def dot(self, size: int | _Color | None = None) -> None: ...
@overload
def dot(self, size: int | None, color: _Color, /) -> None: ...
@overload
def dot(self, size: int | None, r: float, g: float, b: float, /) -> None: ...The signature from the docs is turtle.dot()
turtle.dot(size)
turtle.dot(color, /)
turtle.dot(size, color, /)
turtle.dot(size, r, g, b, /)This makes it pretty clear the "color" is not a keyword arg, so
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've opened an issue concerning |
||
| self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, "_not_a_color_") | ||
| self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, (0, 0, 0, 0)) | ||
| self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, 0, 0, 0, 0) | ||
| self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, (-1, 0, 0)) | ||
| self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, -1, 0, 0) | ||
| self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, (0, 257, 0)) | ||
| self.assertRaises(turtle.TurtleGraphicsError, self.turtle.dot, 0, 0, 257, 0) | ||
|
|
||
|
|
||
| class TestModuleLevel(unittest.TestCase): | ||
| def test_all_signatures(self): | ||
| import inspect | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.