Skip to content

turtle.dot(size="blue") has a weird behaviour #141062

Open

Description

@adorilson

Bug description:

The turtle.dot's documentation says:

turtle.dot()
turtle.dot(size)
turtle.dot(color, /)
turtle.dot(size, color, /)
turtle.dot(size, r, g, b, /)

    Parameters:

            size – an integer >= 1 (if given)

            color – a colorstring or a numeric color tuple

However, turtle.dot(size="blue") doesn't raise an exception. Instead of this, the color is changed to blue.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Nov 5, 2025
  2. changed the title [-]turtle.dot(size="blue") has a weird behaviuor[/-] [+]turtle.dot(size="blue") has a weird behaviour[/+] on Nov 5, 2025
  3. StanFromIreland commented on Nov 5, 2025

    @StanFromIreland
    Member

    Intentional, however:

    cpython/Lib/turtle.py

    Lines 3501 to 3503 in 4ac16dd

    if isinstance(size, (str, tuple)):
    color = self._colorstr(size)
    size = self._pensize + max(self._pensize, 4)

    So I shall mark this as a feature.

  4. added
    type-featureA feature request or enhancement
    and removed
    type-bugAn unexpected behavior, bug, or error
    on Nov 5, 2025
  5. JanEricNitschke commented on Nov 5, 2025

    @JanEricNitschke
    Contributor

    Yeah, this is the runtime code:

        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)
    
    

    This is the corresponding type hint in typeshed:

        @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: ...
    
    

    And this is what the docs state (https://docs.python.org/3/library/turtle.html#turtle.dot):

    turtle.dot()
    turtle.dot(size)
    turtle.dot(color, /)
    turtle.dot(size, color, /)
    turtle.dot(size, r, g, b, /)
    
    

    I dont think there is a way to achieve the current desired behaviour without this

  6. adorilson commented on Nov 5, 2025

    @adorilson
    ContributorAuthor

    Intentional, however:

    cpython/Lib/turtle.py

    Lines 3501 to 3503 in 4ac16dd
    if isinstance(size, (str, tuple)):
    color = self._colorstr(size)
    size = self._pensize + max(self._pensize, 4)

    So I shall mark this as a feature.

    I saw this. The problem seems to be on 3502 line.

    After, the color variable will be used in

    cpython/Lib/turtle.py

    Lines 3520 to 3523 in 4ac16dd

    self.pendown()
    self.pensize(size)
    self.pencolor(color)
    self.forward(0)

    I think we just need to erase the 3502 line.

  7. JanEricNitschke commented on Nov 5, 2025

    @JanEricNitschke
    Contributor

    If you want to allow all three of these

    turtle.dot(3)
    turtle.dot("blue")
    turtle.dot(size=3)
    

    then i dont think there is a way to NOT have

    turtle.dot(size="blue")
    
  8. adorilson commented on Nov 5, 2025

    @adorilson
    ContributorAuthor

    If you want to allow all three of these

    turtle.dot(3)
    turtle.dot("blue")
    turtle.dot(size=3)
    

    then i dont think there is a way to NOT have

    turtle.dot(size="blue")
    

    I got your point.

    Is it possible to identify if an argument was passed by position or by name?

  9. StanFromIreland commented on Nov 5, 2025

    @StanFromIreland
    Member

    Is it possible to identify if an argument was passed by position or by name?

    In general, no, such information is not preserved. We could convert it to dot(*args, **kwargs) and we could then distinguish positional vs keyword, but implementing it with all of the required additional handling is quite messy, and not worth the additional complexity in this case IMO.

  10. jsbueno commented on Nov 5, 2025

    @jsbueno
    Contributor

    What about having an ad-hoc wrapper which could use *args and **kwargs (and functools.wraps to preserve the original signature), and then error on a non-numeric "size" passed by name?

  11. serhiy-storchaka commented on Nov 6, 2025

    @serhiy-storchaka
    Member

    I think that the simplest way to get rid of such weird behavior is to forbid passing the size argument by keyword. Yes, this is a breaking change, and normally we would need to add a complicated code that emits a deprecation warning. But it is unlikely that many code will be broke -- there is no benefit of passing size by keyword, especially if you cannot pass color by keyword.

    On other hand, if nobody passes the size argument by keyword, this change would fix no code. This would be mostly cosmetic change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-tkintertype-featureA feature request or enhancement

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions