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

Limit WKT length in repr #189

Merged
merged 7 commits into from
Sep 23, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 6 additions & 6 deletions pygeos/constructive.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def buffer(
--------
>>> buffer(Geometry("POINT (10 10)"), 2, quadsegs=1)
<pygeos.Geometry POLYGON ((12 10, 10 8, 8 10, 10 12, 12 10))>
>>> buffer(Geometry("POINT (10 10)"), 2, quadsegs=2)
>>> buffer(Geometry("POINT (10 10)"), 2, quadsegs=2)) # doctest: +SKIP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be OK to leave these either by wrapping with to_wkt() to print full string (though it does distract a tiny bit from the example)
or include the truncated version of the output, which may be sufficient to demonstrate that it producted a polygon buffer:

<pygeos.Geometry POLYGON ((12 10, 11.4 8.59, 10 8, 8.59 8.59, 8 10, 8.59 11....>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also be fine with actually having the truncated one in the docstrings below (it also makes the docstring line length shorter)

<pygeos.Geometry POLYGON ((12 10, 11.4 8.59, 10 8, 8.59 8.59, 8 10, 8.59 11.4, 10 12, 11.4 11.4, 12 10))>
>>> buffer(Geometry("POINT (10 10)"), -2, quadsegs=1)
<pygeos.Geometry POLYGON EMPTY>
Expand All @@ -121,11 +121,11 @@ def buffer(
>>> buffer(line, 2, single_sided=True, cap_style="flat")
<pygeos.Geometry POLYGON ((20 10, 10 10, 10 12, 20 12, 20 10))>
>>> line2 = Geometry("LINESTRING (10 10, 20 10, 20 20)")
>>> buffer(line2, 2, cap_style="flat", join_style="bevel")
>>> buffer(line2, 2, cap_style="flat", join_style="bevel") # doctest: +SKIP
<pygeos.Geometry POLYGON ((18 12, 18 20, 22 20, 22 10, 20 8, 10 8, 10 12, 18 12))>
>>> buffer(line2, 2, cap_style="flat", join_style="mitre")
<pygeos.Geometry POLYGON ((18 12, 18 20, 22 20, 22 8, 10 8, 10 12, 18 12))>
>>> buffer(line2, 2, cap_style="flat", join_style="mitre", mitre_limit=1)
>>> buffer(line2, 2, cap_style="flat", join_style="mitre", mitre_limit=1) # doctest: +SKIP
<pygeos.Geometry POLYGON ((18 12, 18 20, 22 20, 21.8 9, 21 8.17, 10 8, 10 12, 18 12))>
>>> square = Geometry("POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))")
>>> buffer(square, 2, join_style="mitre")
Expand Down Expand Up @@ -228,7 +228,7 @@ def delaunay_triangles(geometry, tolerance=0.0, only_edges=False, **kwargs):
>>> points = Geometry("MULTIPOINT (50 30, 60 30, 100 100)")
>>> delaunay_triangles(points)
<pygeos.Geometry GEOMETRYCOLLECTION (POLYGON ((50 30, 60 30, 100 100, 50 30)))>
>>> delaunay_triangles(points, only_edges=True)
>>> delaunay_triangles(points, only_edges=True) # doctest: +SKIP
<pygeos.Geometry MULTILINESTRING ((50 30, 100 100), (50 30, 60 30), (60 30, 100 100))>
>>> delaunay_triangles(Geometry("MULTIPOINT (50 30, 51 30, 60 30, 100 100)"), tolerance=2)
<pygeos.Geometry GEOMETRYCOLLECTION (POLYGON ((50 30, 60 30, 100 100, 50 30)))>
Expand Down Expand Up @@ -391,7 +391,7 @@ def simplify(geometry, tolerance, preserve_topology=False, **kwargs):
>>> simplify(line, tolerance=1)
<pygeos.Geometry LINESTRING (0 0, 0 20)>
>>> polygon_with_hole = Geometry("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 4, 4 4, 4 2, 2 2))")
>>> simplify(polygon_with_hole, tolerance=4, preserve_topology=True)
>>> simplify(polygon_with_hole, tolerance=4, preserve_topology=True) # doctest: +SKIP
<pygeos.Geometry POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 4, 4 4, 4 2, 2 2))>
>>> simplify(polygon_with_hole, tolerance=4, preserve_topology=False)
<pygeos.Geometry POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))>
Expand Down Expand Up @@ -455,7 +455,7 @@ def voronoi_polygons(
Examples
--------
>>> points = Geometry("MULTIPOINT (2 2, 4 2)")
>>> voronoi_polygons(points)
>>> voronoi_polygons(points) # doctest: +SKIP
<pygeos.Geometry GEOMETRYCOLLECTION (POLYGON ((3 0, 0 0, 0 4, 3 4, 3 0)), POLYGON ((3 4, 6 4, 6 0, 3 0, 3 4)))>
>>> voronoi_polygons(points, only_edges=True)
<pygeos.Geometry LINESTRING (3 4, 3 0)>
Expand Down
2 changes: 1 addition & 1 deletion pygeos/linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def shared_paths(a, b, **kwargs):
--------
>>> geom1 = Geometry("LINESTRING (0 0, 1 0, 1 1, 0 1, 0 0)")
>>> geom2 = Geometry("LINESTRING (1 0, 2 0, 2 1, 1 1, 1 0)")
>>> shared_paths(geom1, geom2)
>>> shared_paths(geom1, geom2) # doctest: +SKIP
<pygeos.Geometry GEOMETRYCOLLECTION (MULTILINESTRING EMPTY, MULTILINESTRING ((1 0, 1 1)))>
"""
return lib.shared_paths(a, b, **kwargs)
12 changes: 12 additions & 0 deletions pygeos/test/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,18 @@ def test_to_wkt_multipoint_with_point_empty_errors():
pygeos.to_wkt(geom)


def test_repr():
assert repr(point) == "<pygeos.Geometry POINT (2 3)>"


def test_repr_max_length():
# the repr is limited to 80 characters
geom = pygeos.linestrings(np.arange(1000), np.arange(1000))
representation = repr(geom)
assert len(representation) == 80
assert representation.endswith("...>")


def test_repr_multipoint_with_point_empty():
# Test if segfault is prevented
geom = pygeos.multipoints([point, empty_point])
Expand Down
25 changes: 17 additions & 8 deletions src/pygeom.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
/* This initializes a global geometry type registry */
PyObject *geom_registry[1] = {NULL};

char* repr_fmt = "<pygeos.Geometry %s>";

/* Initializes a new geometry object */
PyObject *GeometryObject_FromGEOS(GEOSGeometry *ptr, GEOSContextHandle_t ctx)
{
Expand Down Expand Up @@ -54,7 +52,7 @@ static PyMemberDef GeometryObject_members[] = {
{NULL} /* Sentinel */
};

static PyObject *GeometryObject_ToWKT(GeometryObject *obj, char *format)
static PyObject *GeometryObject_ToWKT(GeometryObject *obj)
{
char *wkt;
PyObject *result;
Expand Down Expand Up @@ -84,7 +82,7 @@ static PyObject *GeometryObject_ToWKT(GeometryObject *obj, char *format)
if (last_error[0] != 0) { errstate = PGERR_GEOS_EXCEPTION; goto finish; }

wkt = GEOSWKTWriter_write_r(ctx, writer, obj->ptr);
result = PyUnicode_FromFormat(format, wkt);
result = PyUnicode_FromString(wkt);
GEOSFree_r(ctx, wkt);
GEOSWKTWriter_destroy_r(ctx, writer);

Expand All @@ -99,18 +97,29 @@ static PyObject *GeometryObject_ToWKT(GeometryObject *obj, char *format)

static PyObject *GeometryObject_repr(GeometryObject *self)
{
PyObject *result = GeometryObject_ToWKT(self, repr_fmt);
PyObject *result, *wkt, *truncated;

wkt = GeometryObject_ToWKT(self);
// we never want a repr() to fail; that can be very confusing
if (result == NULL) {
if (wkt == NULL) {
PyErr_Clear();
return PyUnicode_FromFormat(repr_fmt, "Exception in WKT writer");
return PyUnicode_FromString("<pygeos.Geometry Exception in WKT writer>");
}
// the total length is limited to 80 characters
if (PyUnicode_GET_LENGTH(wkt) > 62) {
truncated = PyUnicode_Substring(wkt, 0, 59);
result = PyUnicode_FromFormat("<pygeos.Geometry %U...>", truncated);
Py_XDECREF(truncated);
} else {
result = PyUnicode_FromFormat("<pygeos.Geometry %U>", wkt);
}
Py_XDECREF(wkt);
return result;
}

static PyObject *GeometryObject_str(GeometryObject *self)
{
return GeometryObject_ToWKT(self, "%s");
return GeometryObject_ToWKT(self);
}

static Py_hash_t GeometryObject_hash(GeometryObject *self)
Expand Down