Skip to content
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

Bug with line joints #4579

Closed
LeonLenclos opened this issue Apr 23, 2020 · 5 comments · Fixed by #4580
Closed

Bug with line joints #4579

LeonLenclos opened this issue Apr 23, 2020 · 5 comments · Fixed by #4580
Labels
Bug Any unexpected behavior, until confirmed feature.

Comments

@LeonLenclos
Copy link

LeonLenclos commented Apr 23, 2020

What did you do?

When I use the joint='curve' attribute on the line method with a sequence of numeric value, I get an error.

What did you expect to happen?

The documentation say that you can pass Sequence of either 2-tuples or numeric values.

So, this should work:

>>> from PIL import Image, ImageDraw
>>> im = Image.new('RGB', (800, 600))
>>> draw = ImageDraw.Draw(im)
>>> draw.line((400, 200, 300, 280, 100, 280), 0, 50, joint='curve')

What actually happened?

Sequence of 2-tuples and joint='curve' works fine :

>>> draw.line(((400, 200), (300, 280), (100, 280)), 0, 50, joint='curve')

Sequence of numeric values, but no joint='curve' works fine :

>>> draw.line((400,200,300,280,100,280), 0, 50)

Sequence of numeric values and joint='curve' doesn't work :

>>> draw.line((400,200,300,280,100,280), 0, 50, joint='curve')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/leon/virtualenvs/ogn/lib/python3.5/site-packages/PIL/ImageDraw.py", line 165, in line
    for start, end in ((xy[i-1], point), (point, xy[i+1]))
  File "/home/leon/virtualenvs/ogn/lib/python3.5/site-packages/PIL/ImageDraw.py", line 165, in <listcomp>
    for start, end in ((xy[i-1], point), (point, xy[i+1]))
TypeError: 'int' object is not subscriptable

What are your OS, Python and Pillow versions?

  • OS: Debian Linux
  • Python: 3.5.3
  • Pillow: '5.4.1'
@radarhere
Copy link
Member

Thanks for reporting this bug. I've created PR #4580 to resolve it.

@radarhere radarhere added the Bug Any unexpected behavior, until confirmed feature. label Apr 24, 2020
@hugovk
Copy link
Member

hugovk commented Jun 1, 2020

The documentation say that you can pass Sequence of either 2-tuples or numeric values.

Hmm, the docs in full give examples of each:

  • xy – Sequence of either 2-tuples like [(x, y), (x, y), ...] or numeric values like [x, y, x, y, ...].

The examples are a list of tuples and a list. In #3738 we decided not to support a list of lists.

All combinations:

[(x, y), (x, y), ...]  # list of tuples ✅
[[x, y], [x, y], ...]  # list of lists ❌
((x, y), (x, y), ...)  # tuple of tuples ❓
([x, y], [x, y], ...)  # tuple of lists ❌
[x, y, x, y, ...]  # list ✅
(x, y, x, y, ...)  # tuple ❓

I know it works for tuples (of values) when there's no joint="curve", but I'm wondering if we should explicitly support it? Does it work by design or by accident?

Do we also support them for all other xy sequence parameters in ImageDraw? Should we?

@radarhere
Copy link
Member

The key argument in #3738 for me is #3738 (comment)

Also, tuples and lists are for slightly different things (immutable/mutable, structure/order). Does that really matter? I think maybe it does: semantically you know a coordinate like (100, 200) can't have a third value; but [100, 200] looks like it could. So I'm tending towards keeping it as is.

This is now the opposite situation. Instead of clarifying that a coordinate is immutable, this is about clarifying that a list of coordinates is mutable. Whereas it's harder to imagine a scenario where a user has a mutable (x, y) coordinate, I think it's easier to imagine a user having a list of coordinates that, for the purposes of their code, they would like to be seen as immutable. As in the other issue though, no strong feelings.

Tuples of values seem to work for the other ImageDraw methods.

@LeonLenclos
Copy link
Author

My opinion isn't worth much. But I tend to think that any iterable (that contains points or tuples of points) should be accepted. (under the principle of duck typing).

@hugovk
Copy link
Member

hugovk commented Jun 3, 2020

Sounds reasonable, thanks both!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Any unexpected behavior, until confirmed feature.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants