# How to create a shapely polygon with a hole?

Sounds like a simple question, and the Shapely doc says all I need to do to create a simple polygon with a hole is to pass two lists of coordinate tuples:

``````exterior = [(2, 8), (7, 8), (7, 3), (2, 3), (2, 8)]
interior = [(4, 7), (4, 5), (6, 5), (6, 7), (4, 7)]
pgn = Polygon(exterior, holes=interior)
``````

However, I get the following error:

``````AttributeError: 'tuple' object has no attribute '_ndim'
``````

I also tried passing a Polygon as the interior ring.

``````interior=Polygon([(4, 7), (4, 5), (6, 5), (6, 7), (4, 7)])
pgn = Polygon(exterior, holes=interior)

>>> TypeError: object of type 'Polygon' has no len()
``````

What is the correct way to use this constructor? Looks like the `holes` parameter should not be a tuple or a `Polygon`, so what should it be?

A polygon can have multiple holes in it, so the `holes` argument is a list of list of coordinate tuples:

``````>>> exterior = [(2, 8), (7, 8), (7, 3), (2, 3), (2, 8)]
>>> interior = [(4, 7), (4, 5), (6, 5), (6, 7), (4, 7)]
``````

This fails:

``````>>> pgn = Polygon(exterior, holes=interior)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/rowlings/.local/lib/python2.7/site-packages/shapely/geometry/polygon.py", line 240, in __init__
ret = geos_polygon_from_py(shell, holes)
File "/home/rowlings/.local/lib/python2.7/site-packages/shapely/geometry/polygon.py", line 506, in geos_polygon_from_py
N = exemplar._ndim
AttributeError: 'tuple' object has no attribute '_ndim'
``````

because `interior` isn't a list of interior polygons, its just one. So make it a list with one member:

``````>>> pgn = Polygon(exterior, holes=[interior])
>>> pgn
<shapely.geometry.polygon.Polygon object at 0x7fb3639bc250>
``````

Docs:

``````The second is an optional unordered sequence of ring-like sequences specifying the interior boundaries or “holes” of the feature.
``````

The "source code" links are great working examples of the shapely API, eg this:

``````ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)]
int = [(1, 0), (0.5, 0.5), (1, 1), (1.5, 0.5), (1, 0)][::-1]
polygon = Polygon(ext, [int])
``````
• Ah, that's it! Knew I would be missing something simple. I might suggest adding an example to their docs to make it easier for the next person who has this problem. Mar 5, 2020 at 15:03
• The reason why you need `[::-1]` at the end of the `interior` sequence is because ring coordinate pairs should be ordered counter-clockwise while hole sequences should be clockwise. Jan 19, 2023 at 19:46