# Buggy code
def __init__(self, dll):
    super(LGEOS310, self).__init__(dll)
    self.geos_handle = self._lgeos.initGEOS_r(notice_h, error_h)
    keys = list(self._lgeos.__dict__.keys())
    for key in [x for x in keys if not x.endswith("_r")]:
        if key + "_r" in keys:
            reentr_func = getattr(self._lgeos, key + "_r")
            attr = ftools.partial(reentr_func, self.geos_handle)
            attr.__name__ = reentr_func.__name__
            setattr(self, key, attr)
        else:
            setattr(self, key, getattr(self._lgeos, key))
    if not hasattr(self, "GEOSFree"):
        # GEOS < 3.1.1
        self.GEOSFree = self._lgeos.free
    # Deprecated
    self.GEOSGeomToWKB_buf.func.errcheck = errcheck_wkb
    self.GEOSGeomToWKT.func.errcheck = errcheck_just_free
    self.GEOSRelate.func.errcheck = errcheck_just_free
    for pred in (
        self.GEOSDisjoint,
        self.GEOSTouches,
        self.GEOSIntersects,
        self.GEOSCrosses,
        self.GEOSWithin,
        self.GEOSContains,
        self.GEOSOverlaps,
        self.GEOSEquals,
        self.GEOSEqualsExact,
        self.GEOSisEmpty,
        self.GEOSisValid,
        self.GEOSisSimple,
        self.GEOSisRing,
        self.GEOSisClosed,
        self.GEOSHasZ,
    ):
        pred.func.errcheck = errcheck_predicate

    self.GEOSisValidReason.func.errcheck = errcheck_just_free

    self.methods["area"] = self.GEOSArea
    self.methods["boundary"] = self.GEOSBoundary
    self.methods["buffer"] = self.GEOSBuffer
    self.methods["centroid"] = self.GEOSGetCentroid
    self.methods["representative_point"] = self.GEOSPointOnSurface
    self.methods["convex_hull"] = self.GEOSConvexHull
    self.methods["distance"] = self.GEOSDistance
    self.methods["envelope"] = self.GEOSEnvelope
    self.methods["length"] = self.GEOSLength
    self.methods["has_z"] = self.GEOSHasZ
    self.methods["is_empty"] = self.GEOSisEmpty
    self.methods["is_ring"] = self.GEOSisRing
    self.methods["is_closed"] = self.GEOSisClosed
    self.methods["is_simple"] = self.GEOSisSimple
    self.methods["is_valid"] = self.GEOSisValid
    self.methods["disjoint"] = self.GEOSDisjoint
    self.methods["touches"] = self.GEOSTouches
    self.methods["intersects"] = self.GEOSIntersects
    self.methods["crosses"] = self.GEOSCrosses
    self.methods["within"] = self.GEOSWithin
    self.methods["contains"] = self.GEOSContains
    self.methods["overlaps"] = self.GEOSOverlaps
    self.methods["equals"] = self.GEOSEquals
    self.methods["equals_exact"] = self.GEOSEqualsExact
    self.methods["relate"] = self.GEOSRelate
    self.methods["difference"] = self.GEOSDifference
    self.methods["symmetric_difference"] = self.GEOSSymDifference
    self.methods["union"] = self.GEOSUnion
    self.methods["intersection"] = self.GEOSIntersection
    self.methods["prepared_intersects"] = self.GEOSPreparedIntersects
    self.methods["prepared_contains"] = self.GEOSPreparedContains
    self.methods["prepared_contains_properly"] = self.GEOSPreparedContainsProperly
    self.methods["prepared_covers"] = self.GEOSPreparedCovers
    self.methods["simplify"] = self.GEOSSimplify
    self.methods["topology_preserve_simplify"] = self.GEOSTopologyPreserveSimplify
    self.methods["cascaded_union"] = self.GEOSUnionCascaded


# Traceback (AttributeError)
$ python -c "import shapely.geos"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/openerp/europortetest/railfleetng/ve/local/lib/python2.7/site-packages/shapely/geos.py", line 133, in <module>
prototype(_lgeos, geos_version)
File "/home/openerp/europortetest/railfleetng/ve/local/lib/python2.7/site-packages/shapely/ctypes_declarations.py", line 279, in prototype
lgeos.GEOSisClosed.restype = c_byte
File "/usr/lib/python2.7/ctypes/__init__.py", line 378, in __getattr__
func = self.__getitem__(name)
File "/usr/lib/python2.7/ctypes/__init__.py", line 383, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /usr/lib/libgeos_c.so.1: undefined symbol: GEOSisClosed

# Fixed code
def __init__(self, dll):
    super(LGEOS310, self).__init__(dll)
    self.geos_handle = self._lgeos.initGEOS_r(notice_h, error_h)
    keys = list(self._lgeos.__dict__.keys())
    for key in [x for x in keys if not x.endswith("_r")]:
        if key + "_r" in keys:
            reentr_func = getattr(self._lgeos, key + "_r")
            attr = ftools.partial(reentr_func, self.geos_handle)
            attr.__name__ = reentr_func.__name__
            setattr(self, key, attr)
        else:
            setattr(self, key, getattr(self._lgeos, key))
    if not hasattr(self, "GEOSFree"):
        # GEOS < 3.1.1
        self.GEOSFree = self._lgeos.free
    # Deprecated
    self.GEOSGeomToWKB_buf.func.errcheck = errcheck_wkb
    self.GEOSGeomToWKT.func.errcheck = errcheck_just_free
    self.GEOSRelate.func.errcheck = errcheck_just_free
    for pred in (
        self.GEOSDisjoint,
        self.GEOSTouches,
        self.GEOSIntersects,
        self.GEOSCrosses,
        self.GEOSWithin,
        self.GEOSContains,
        self.GEOSOverlaps,
        self.GEOSEquals,
        self.GEOSEqualsExact,
        self.GEOSisEmpty,
        self.GEOSisValid,
        self.GEOSisSimple,
        self.GEOSisRing,
        self.GEOSisClosed,
        self.GEOSHasZ,
    ):
        pred.func.errcheck = errcheck_predicate

    self.GEOSisValidReason.func.errcheck = errcheck_just_free

    self.methods["area"] = self.GEOSArea
    self.methods["boundary"] = self.GEOSBoundary
    self.methods["buffer"] = self.GEOSBuffer
    self.methods["centroid"] = self.GEOSGetCentroid
    self.methods["representative_point"] = self.GEOSPointOnSurface
    self.methods["convex_hull"] = self.GEOSConvexHull
    self.methods["distance"] = self.GEOSDistance
    self.methods["envelope"] = self.GEOSEnvelope
    self.methods["length"] = self.GEOSLength
    self.methods["has_z"] = self.GEOSHasZ
    self.methods["is_empty"] = self.GEOSisEmpty
    self.methods["is_ring"] = self.GEOSisRing
    self.methods["is_simple"] = self.GEOSisSimple
    self.methods["is_valid"] = self.GEOSisValid
    self.methods["disjoint"] = self.GEOSDisjoint
    self.methods["touches"] = self.GEOSTouches
    self.methods["intersects"] = self.GEOSIntersects
    self.methods["crosses"] = self.GEOSCrosses
    self.methods["within"] = self.GEOSWithin
    self.methods["contains"] = self.GEOSContains
    self.methods["overlaps"] = self.GEOSOverlaps
    self.methods["equals"] = self.GEOSEquals
    self.methods["equals_exact"] = self.GEOSEqualsExact
    self.methods["relate"] = self.GEOSRelate
    self.methods["difference"] = self.GEOSDifference
    self.methods["symmetric_difference"] = self.GEOSSymDifference
    self.methods["union"] = self.GEOSUnion
    self.methods["intersection"] = self.GEOSIntersection
    self.methods["prepared_intersects"] = self.GEOSPreparedIntersects
    self.methods["prepared_contains"] = self.GEOSPreparedContains
    self.methods["prepared_contains_properly"] = self.GEOSPreparedContainsProperly
    self.methods["prepared_covers"] = self.GEOSPreparedCovers
    self.methods["simplify"] = self.GEOSSimplify
    self.methods["topology_preserve_simplify"] = self.GEOSTopologyPreserveSimplify
    self.methods["cascaded_union"] = self.GEOSUnionCascaded