We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
xrange vs python 3
Searching the networkx code for `xrange` I see it's used in some "Shapefile" related code and tests.  Should this be updated for python 3 compatibility, and is it not tested in the TravisCI testing?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `networkx/readwrite/nx_shp.py`
Content:
```
1 """
2 *********
3 Shapefile
4 *********
5 
6 Generates a networkx.DiGraph from point and line shapefiles.
7 
8 "The Esri Shapefile or simply a shapefile is a popular geospatial vector
9 data format for geographic information systems software. It is developed
10 and regulated by Esri as a (mostly) open specification for data
11 interoperability among Esri and other software products."
12 See http://en.wikipedia.org/wiki/Shapefile for additional information.
13 """
14 #    Copyright (C) 2004-2010 by
15 #    Ben Reilly <benwreilly@gmail.com>
16 #    Aric Hagberg <hagberg@lanl.gov>
17 #    Dan Schult <dschult@colgate.edu>
18 #    Pieter Swart <swart@lanl.gov>
19 #    All rights reserved.
20 #    BSD license.
21 import networkx as nx
22 __author__ = """Ben Reilly (benwreilly@gmail.com)"""
23 __all__ = ['read_shp', 'write_shp']
24 
25 
26 def read_shp(path):
27     """Generates a networkx.DiGraph from shapefiles. Point geometries are
28     translated into nodes, lines into edges. Coordinate tuples are used as
29     keys. Attributes are preserved, line geometries are simplified into start
30     and end coordinates. Accepts a single shapefile or directory of many
31     shapefiles.
32 
33     "The Esri Shapefile or simply a shapefile is a popular geospatial vector
34     data format for geographic information systems software [1]_."
35 
36     Parameters
37     ----------
38     path : file or string
39        File, directory, or filename to read.
40 
41     Returns
42     -------
43     G : NetworkX graph
44 
45     Examples
46     --------
47     >>> G=nx.read_shp('test.shp') # doctest: +SKIP
48 
49     References
50     ----------
51     .. [1] http://en.wikipedia.org/wiki/Shapefile
52     """
53     try:
54         from osgeo import ogr
55     except ImportError:
56         raise ImportError("read_shp requires OGR: http://www.gdal.org/")
57 
58     net = nx.DiGraph()
59 
60     def getfieldinfo(lyr, feature, flds):
61             f = feature
62             return [f.GetField(f.GetFieldIndex(x)) for x in flds]
63 
64     def addlyr(lyr, fields):
65         for findex in range(lyr.GetFeatureCount()):
66             f = lyr.GetFeature(findex)
67             flddata = getfieldinfo(lyr, f, fields)
68             g = f.geometry()
69             attributes = dict(zip(fields, flddata))
70             attributes["ShpName"] = lyr.GetName()
71             if g.GetGeometryType() == 1:  # point
72                 net.add_node((g.GetPoint_2D(0)), attributes)
73             if g.GetGeometryType() == 2:  # linestring
74                 attributes["Wkb"] = g.ExportToWkb()
75                 attributes["Wkt"] = g.ExportToWkt()
76                 attributes["Json"] = g.ExportToJson()
77                 last = g.GetPointCount() - 1
78                 net.add_edge(g.GetPoint_2D(0), g.GetPoint_2D(last), attributes)
79 
80     if isinstance(path, str):
81         shp = ogr.Open(path)
82         lyrcount = shp.GetLayerCount()  # multiple layers indicate a directory
83         for lyrindex in range(lyrcount):
84             lyr = shp.GetLayerByIndex(lyrindex)
85             flds = [x.GetName() for x in lyr.schema]
86             addlyr(lyr, flds)
87     return net
88 
89 
90 def write_shp(G, outdir):
91     """Writes a networkx.DiGraph to two shapefiles, edges and nodes.
92     Nodes and edges are expected to have a Well Known Binary (Wkb) or
93     Well Known Text (Wkt) key in order to generate geometries. Also
94     acceptable are nodes with a numeric tuple key (x,y).
95 
96     "The Esri Shapefile or simply a shapefile is a popular geospatial vector
97     data format for geographic information systems software [1]_."
98 
99     Parameters
100     ----------
101     outdir : directory path
102        Output directory for the two shapefiles.
103 
104     Returns
105     -------
106     None
107 
108     Examples
109     --------
110     nx.write_shp(digraph, '/shapefiles') # doctest +SKIP
111 
112     References
113     ----------
114     .. [1] http://en.wikipedia.org/wiki/Shapefile
115     """
116     try:
117         from osgeo import ogr
118     except ImportError:
119         raise ImportError("write_shp requires OGR: http://www.gdal.org/")
120     # easier to debug in python if ogr throws exceptions
121     ogr.UseExceptions()
122 
123     def netgeometry(key, data):
124         if 'Wkb' in data:
125             geom = ogr.CreateGeometryFromWkb(data['Wkb'])
126         elif 'Wkt' in data:
127             geom = ogr.CreateGeometryFromWkt(data['Wkt'])
128         elif type(key[0]).__name__ == 'tuple':  # edge keys are packed tuples
129             geom = ogr.Geometry(ogr.wkbLineString)
130             _from, _to = key[0], key[1]
131             try:
132                 geom.SetPoint(0, *_from)
133                 geom.SetPoint(1, *_to)
134             except TypeError:
135                 # assume user used tuple of int and choked ogr
136                 _ffrom = [float(x) for x in _from]
137                 _fto = [float(x) for x in _to]
138                 geom.SetPoint(0, *_ffrom)
139                 geom.SetPoint(1, *_fto)
140         else:
141             geom = ogr.Geometry(ogr.wkbPoint)
142             try:
143                 geom.SetPoint(0, *key)
144             except TypeError:
145                 # assume user used tuple of int and choked ogr
146                 fkey = [float(x) for x in key]
147                 geom.SetPoint(0, *fkey)
148 
149         return geom
150 
151     # Create_feature with new optional attributes arg (should be dict type)
152     def create_feature(geometry, lyr, attributes=None):
153         feature = ogr.Feature(lyr.GetLayerDefn())
154         feature.SetGeometry(g)
155         if attributes != None:
156             # Loop through attributes, assigning data to each field
157             for field, data in attributes.items():
158                 feature.SetField(field, data)
159         lyr.CreateFeature(feature)
160         feature.Destroy()
161 
162     drv = ogr.GetDriverByName("ESRI Shapefile")
163     shpdir = drv.CreateDataSource(outdir)
164     # delete pre-existing output first otherwise ogr chokes
165     try:
166         shpdir.DeleteLayer("nodes")
167     except:
168         pass
169     nodes = shpdir.CreateLayer("nodes", None, ogr.wkbPoint)
170     for n in G:
171         data = G.node[n] or {}
172         g = netgeometry(n, data)
173         create_feature(g, nodes)
174     try:
175         shpdir.DeleteLayer("edges")
176     except:
177         pass
178     edges = shpdir.CreateLayer("edges", None, ogr.wkbLineString)
179 
180     # New edge attribute write support merged into edge loop
181     fields = {}      # storage for field names and their data types
182     attributes = {}  # storage for attribute data (indexed by field names)
183 
184     # Conversion dict between python and ogr types
185     OGRTypes = {int: ogr.OFTInteger, str: ogr.OFTString, float: ogr.OFTReal}
186 
187     # Edge loop
188     for e in G.edges(data=True):
189         data = G.get_edge_data(*e)
190         g = netgeometry(e, data)
191         # Loop through attribute data in edges
192         for key, data in e[2].items():
193             # Reject spatial data not required for attribute table
194             if (key != 'Json' and key != 'Wkt' and key != 'Wkb'
195                 and key != 'ShpName'):
196                   # For all edges check/add field and data type to fields dict
197                     if key not in fields:
198                   # Field not in previous edges so add to dict
199                         if type(data) in OGRTypes:
200                             fields[key] = OGRTypes[type(data)]
201                         else:
202                             # Data type not supported, default to string (char 80)
203                             fields[key] = ogr.OFTString
204                         # Create the new field
205                         newfield = ogr.FieldDefn(key, fields[key])
206                         edges.CreateField(newfield)
207                         # Store the data from new field to dict for CreateLayer()
208                         attributes[key] = data
209                     else:
210                      # Field already exists, add data to dict for CreateLayer()
211                         attributes[key] = data
212         # Create the feature with, passing new attribute data
213         create_feature(g, edges, attributes)
214 
215     nodes, edges = None, None
216 
217 
218 # fixture for nose tests
219 def setup_module(module):
220     from nose import SkipTest
221     try:
222         import ogr
223     except:
224         raise SkipTest("OGR not available")
225
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/networkx/readwrite/nx_shp.py b/networkx/readwrite/nx_shp.py
--- a/networkx/readwrite/nx_shp.py
+++ b/networkx/readwrite/nx_shp.py
@@ -55,16 +55,15 @@
     except ImportError:
         raise ImportError("read_shp requires OGR: http://www.gdal.org/")
 
-    net = nx.DiGraph()
-
-    def getfieldinfo(lyr, feature, flds):
-            f = feature
-            return [f.GetField(f.GetFieldIndex(x)) for x in flds]
+    if not isinstance(path, str):
+        return
 
-    def addlyr(lyr, fields):
-        for findex in range(lyr.GetFeatureCount()):
-            f = lyr.GetFeature(findex)
-            flddata = getfieldinfo(lyr, f, fields)
+    net = nx.DiGraph()
+    shp = ogr.Open(path)
+    for lyr in shp:
+        fields = [x.GetName() for x in lyr.schema]
+        for f in lyr:
+            flddata = [f.GetField(f.GetFieldIndex(x)) for x in fields]
             g = f.geometry()
             attributes = dict(zip(fields, flddata))
             attributes["ShpName"] = lyr.GetName()
@@ -76,14 +75,6 @@
                 attributes["Json"] = g.ExportToJson()
                 last = g.GetPointCount() - 1
                 net.add_edge(g.GetPoint_2D(0), g.GetPoint_2D(last), attributes)
-
-    if isinstance(path, str):
-        shp = ogr.Open(path)
-        lyrcount = shp.GetLayerCount()  # multiple layers indicate a directory
-        for lyrindex in range(lyrcount):
-            lyr = shp.GetLayerByIndex(lyrindex)
-            flds = [x.GetName() for x in lyr.schema]
-            addlyr(lyr, flds)
     return net
 
 
@@ -168,7 +159,7 @@
         pass
     nodes = shpdir.CreateLayer("nodes", None, ogr.wkbPoint)
     for n in G:
-        data = G.node[n] or {}
+        data = G.node[n]
         g = netgeometry(n, data)
         create_feature(g, nodes)
     try:

{"golden_diff": "diff --git a/networkx/readwrite/nx_shp.py b/networkx/readwrite/nx_shp.py\n--- a/networkx/readwrite/nx_shp.py\n+++ b/networkx/readwrite/nx_shp.py\n@@ -55,16 +55,15 @@\n     except ImportError:\n         raise ImportError(\"read_shp requires OGR: http://www.gdal.org/\")\n \n-    net = nx.DiGraph()\n-\n-    def getfieldinfo(lyr, feature, flds):\n-            f = feature\n-            return [f.GetField(f.GetFieldIndex(x)) for x in flds]\n+    if not isinstance(path, str):\n+        return\n \n-    def addlyr(lyr, fields):\n-        for findex in range(lyr.GetFeatureCount()):\n-            f = lyr.GetFeature(findex)\n-            flddata = getfieldinfo(lyr, f, fields)\n+    net = nx.DiGraph()\n+    shp = ogr.Open(path)\n+    for lyr in shp:\n+        fields = [x.GetName() for x in lyr.schema]\n+        for f in lyr:\n+            flddata = [f.GetField(f.GetFieldIndex(x)) for x in fields]\n             g = f.geometry()\n             attributes = dict(zip(fields, flddata))\n             attributes[\"ShpName\"] = lyr.GetName()\n@@ -76,14 +75,6 @@\n                 attributes[\"Json\"] = g.ExportToJson()\n                 last = g.GetPointCount() - 1\n                 net.add_edge(g.GetPoint_2D(0), g.GetPoint_2D(last), attributes)\n-\n-    if isinstance(path, str):\n-        shp = ogr.Open(path)\n-        lyrcount = shp.GetLayerCount()  # multiple layers indicate a directory\n-        for lyrindex in range(lyrcount):\n-            lyr = shp.GetLayerByIndex(lyrindex)\n-            flds = [x.GetName() for x in lyr.schema]\n-            addlyr(lyr, flds)\n     return net\n \n \n@@ -168,7 +159,7 @@\n         pass\n     nodes = shpdir.CreateLayer(\"nodes\", None, ogr.wkbPoint)\n     for n in G:\n-        data = G.node[n] or {}\n+        data = G.node[n]\n         g = netgeometry(n, data)\n         create_feature(g, nodes)\n     try:\n", "issue": "xrange vs python 3\nSearching the networkx code for `xrange` I see it's used in some \"Shapefile\" related code and tests.  Should this be updated for python 3 compatibility, and is it not tested in the TravisCI testing?\n\n", "before_files": [{"content": "\"\"\"\n*********\nShapefile\n*********\n\nGenerates a networkx.DiGraph from point and line shapefiles.\n\n\"The Esri Shapefile or simply a shapefile is a popular geospatial vector\ndata format for geographic information systems software. It is developed\nand regulated by Esri as a (mostly) open specification for data\ninteroperability among Esri and other software products.\"\nSee http://en.wikipedia.org/wiki/Shapefile for additional information.\n\"\"\"\n#    Copyright (C) 2004-2010 by\n#    Ben Reilly <benwreilly@gmail.com>\n#    Aric Hagberg <hagberg@lanl.gov>\n#    Dan Schult <dschult@colgate.edu>\n#    Pieter Swart <swart@lanl.gov>\n#    All rights reserved.\n#    BSD license.\nimport networkx as nx\n__author__ = \"\"\"Ben Reilly (benwreilly@gmail.com)\"\"\"\n__all__ = ['read_shp', 'write_shp']\n\n\ndef read_shp(path):\n    \"\"\"Generates a networkx.DiGraph from shapefiles. Point geometries are\n    translated into nodes, lines into edges. Coordinate tuples are used as\n    keys. Attributes are preserved, line geometries are simplified into start\n    and end coordinates. Accepts a single shapefile or directory of many\n    shapefiles.\n\n    \"The Esri Shapefile or simply a shapefile is a popular geospatial vector\n    data format for geographic information systems software [1]_.\"\n\n    Parameters\n    ----------\n    path : file or string\n       File, directory, or filename to read.\n\n    Returns\n    -------\n    G : NetworkX graph\n\n    Examples\n    --------\n    >>> G=nx.read_shp('test.shp') # doctest: +SKIP\n\n    References\n    ----------\n    .. [1] http://en.wikipedia.org/wiki/Shapefile\n    \"\"\"\n    try:\n        from osgeo import ogr\n    except ImportError:\n        raise ImportError(\"read_shp requires OGR: http://www.gdal.org/\")\n\n    net = nx.DiGraph()\n\n    def getfieldinfo(lyr, feature, flds):\n            f = feature\n            return [f.GetField(f.GetFieldIndex(x)) for x in flds]\n\n    def addlyr(lyr, fields):\n        for findex in range(lyr.GetFeatureCount()):\n            f = lyr.GetFeature(findex)\n            flddata = getfieldinfo(lyr, f, fields)\n            g = f.geometry()\n            attributes = dict(zip(fields, flddata))\n            attributes[\"ShpName\"] = lyr.GetName()\n            if g.GetGeometryType() == 1:  # point\n                net.add_node((g.GetPoint_2D(0)), attributes)\n            if g.GetGeometryType() == 2:  # linestring\n                attributes[\"Wkb\"] = g.ExportToWkb()\n                attributes[\"Wkt\"] = g.ExportToWkt()\n                attributes[\"Json\"] = g.ExportToJson()\n                last = g.GetPointCount() - 1\n                net.add_edge(g.GetPoint_2D(0), g.GetPoint_2D(last), attributes)\n\n    if isinstance(path, str):\n        shp = ogr.Open(path)\n        lyrcount = shp.GetLayerCount()  # multiple layers indicate a directory\n        for lyrindex in range(lyrcount):\n            lyr = shp.GetLayerByIndex(lyrindex)\n            flds = [x.GetName() for x in lyr.schema]\n            addlyr(lyr, flds)\n    return net\n\n\ndef write_shp(G, outdir):\n    \"\"\"Writes a networkx.DiGraph to two shapefiles, edges and nodes.\n    Nodes and edges are expected to have a Well Known Binary (Wkb) or\n    Well Known Text (Wkt) key in order to generate geometries. Also\n    acceptable are nodes with a numeric tuple key (x,y).\n\n    \"The Esri Shapefile or simply a shapefile is a popular geospatial vector\n    data format for geographic information systems software [1]_.\"\n\n    Parameters\n    ----------\n    outdir : directory path\n       Output directory for the two shapefiles.\n\n    Returns\n    -------\n    None\n\n    Examples\n    --------\n    nx.write_shp(digraph, '/shapefiles') # doctest +SKIP\n\n    References\n    ----------\n    .. [1] http://en.wikipedia.org/wiki/Shapefile\n    \"\"\"\n    try:\n        from osgeo import ogr\n    except ImportError:\n        raise ImportError(\"write_shp requires OGR: http://www.gdal.org/\")\n    # easier to debug in python if ogr throws exceptions\n    ogr.UseExceptions()\n\n    def netgeometry(key, data):\n        if 'Wkb' in data:\n            geom = ogr.CreateGeometryFromWkb(data['Wkb'])\n        elif 'Wkt' in data:\n            geom = ogr.CreateGeometryFromWkt(data['Wkt'])\n        elif type(key[0]).__name__ == 'tuple':  # edge keys are packed tuples\n            geom = ogr.Geometry(ogr.wkbLineString)\n            _from, _to = key[0], key[1]\n            try:\n                geom.SetPoint(0, *_from)\n                geom.SetPoint(1, *_to)\n            except TypeError:\n                # assume user used tuple of int and choked ogr\n                _ffrom = [float(x) for x in _from]\n                _fto = [float(x) for x in _to]\n                geom.SetPoint(0, *_ffrom)\n                geom.SetPoint(1, *_fto)\n        else:\n            geom = ogr.Geometry(ogr.wkbPoint)\n            try:\n                geom.SetPoint(0, *key)\n            except TypeError:\n                # assume user used tuple of int and choked ogr\n                fkey = [float(x) for x in key]\n                geom.SetPoint(0, *fkey)\n\n        return geom\n\n    # Create_feature with new optional attributes arg (should be dict type)\n    def create_feature(geometry, lyr, attributes=None):\n        feature = ogr.Feature(lyr.GetLayerDefn())\n        feature.SetGeometry(g)\n        if attributes != None:\n            # Loop through attributes, assigning data to each field\n            for field, data in attributes.items():\n                feature.SetField(field, data)\n        lyr.CreateFeature(feature)\n        feature.Destroy()\n\n    drv = ogr.GetDriverByName(\"ESRI Shapefile\")\n    shpdir = drv.CreateDataSource(outdir)\n    # delete pre-existing output first otherwise ogr chokes\n    try:\n        shpdir.DeleteLayer(\"nodes\")\n    except:\n        pass\n    nodes = shpdir.CreateLayer(\"nodes\", None, ogr.wkbPoint)\n    for n in G:\n        data = G.node[n] or {}\n        g = netgeometry(n, data)\n        create_feature(g, nodes)\n    try:\n        shpdir.DeleteLayer(\"edges\")\n    except:\n        pass\n    edges = shpdir.CreateLayer(\"edges\", None, ogr.wkbLineString)\n\n    # New edge attribute write support merged into edge loop\n    fields = {}      # storage for field names and their data types\n    attributes = {}  # storage for attribute data (indexed by field names)\n\n    # Conversion dict between python and ogr types\n    OGRTypes = {int: ogr.OFTInteger, str: ogr.OFTString, float: ogr.OFTReal}\n\n    # Edge loop\n    for e in G.edges(data=True):\n        data = G.get_edge_data(*e)\n        g = netgeometry(e, data)\n        # Loop through attribute data in edges\n        for key, data in e[2].items():\n            # Reject spatial data not required for attribute table\n            if (key != 'Json' and key != 'Wkt' and key != 'Wkb'\n                and key != 'ShpName'):\n                  # For all edges check/add field and data type to fields dict\n                    if key not in fields:\n                  # Field not in previous edges so add to dict\n                        if type(data) in OGRTypes:\n                            fields[key] = OGRTypes[type(data)]\n                        else:\n                            # Data type not supported, default to string (char 80)\n                            fields[key] = ogr.OFTString\n                        # Create the new field\n                        newfield = ogr.FieldDefn(key, fields[key])\n                        edges.CreateField(newfield)\n                        # Store the data from new field to dict for CreateLayer()\n                        attributes[key] = data\n                    else:\n                     # Field already exists, add data to dict for CreateLayer()\n                        attributes[key] = data\n        # Create the feature with, passing new attribute data\n        create_feature(g, edges, attributes)\n\n    nodes, edges = None, None\n\n\n# fixture for nose tests\ndef setup_module(module):\n    from nose import SkipTest\n    try:\n        import ogr\n    except:\n        raise SkipTest(\"OGR not available\")\n", "path": "networkx/readwrite/nx_shp.py"}], "after_files": [{"content": "\"\"\"\n*********\nShapefile\n*********\n\nGenerates a networkx.DiGraph from point and line shapefiles.\n\n\"The Esri Shapefile or simply a shapefile is a popular geospatial vector\ndata format for geographic information systems software. It is developed\nand regulated by Esri as a (mostly) open specification for data\ninteroperability among Esri and other software products.\"\nSee http://en.wikipedia.org/wiki/Shapefile for additional information.\n\"\"\"\n#    Copyright (C) 2004-2010 by\n#    Ben Reilly <benwreilly@gmail.com>\n#    Aric Hagberg <hagberg@lanl.gov>\n#    Dan Schult <dschult@colgate.edu>\n#    Pieter Swart <swart@lanl.gov>\n#    All rights reserved.\n#    BSD license.\nimport networkx as nx\n__author__ = \"\"\"Ben Reilly (benwreilly@gmail.com)\"\"\"\n__all__ = ['read_shp', 'write_shp']\n\n\ndef read_shp(path):\n    \"\"\"Generates a networkx.DiGraph from shapefiles. Point geometries are\n    translated into nodes, lines into edges. Coordinate tuples are used as\n    keys. Attributes are preserved, line geometries are simplified into start\n    and end coordinates. Accepts a single shapefile or directory of many\n    shapefiles.\n\n    \"The Esri Shapefile or simply a shapefile is a popular geospatial vector\n    data format for geographic information systems software [1]_.\"\n\n    Parameters\n    ----------\n    path : file or string\n       File, directory, or filename to read.\n\n    Returns\n    -------\n    G : NetworkX graph\n\n    Examples\n    --------\n    >>> G=nx.read_shp('test.shp') # doctest: +SKIP\n\n    References\n    ----------\n    .. [1] http://en.wikipedia.org/wiki/Shapefile\n    \"\"\"\n    try:\n        from osgeo import ogr\n    except ImportError:\n        raise ImportError(\"read_shp requires OGR: http://www.gdal.org/\")\n\n    if not isinstance(path, str):\n        return\n\n    net = nx.DiGraph()\n    shp = ogr.Open(path)\n    for lyr in shp:\n        fields = [x.GetName() for x in lyr.schema]\n        for f in lyr:\n            flddata = [f.GetField(f.GetFieldIndex(x)) for x in fields]\n            g = f.geometry()\n            attributes = dict(zip(fields, flddata))\n            attributes[\"ShpName\"] = lyr.GetName()\n            if g.GetGeometryType() == 1:  # point\n                net.add_node((g.GetPoint_2D(0)), attributes)\n            if g.GetGeometryType() == 2:  # linestring\n                attributes[\"Wkb\"] = g.ExportToWkb()\n                attributes[\"Wkt\"] = g.ExportToWkt()\n                attributes[\"Json\"] = g.ExportToJson()\n                last = g.GetPointCount() - 1\n                net.add_edge(g.GetPoint_2D(0), g.GetPoint_2D(last), attributes)\n    return net\n\n\ndef write_shp(G, outdir):\n    \"\"\"Writes a networkx.DiGraph to two shapefiles, edges and nodes.\n    Nodes and edges are expected to have a Well Known Binary (Wkb) or\n    Well Known Text (Wkt) key in order to generate geometries. Also\n    acceptable are nodes with a numeric tuple key (x,y).\n\n    \"The Esri Shapefile or simply a shapefile is a popular geospatial vector\n    data format for geographic information systems software [1]_.\"\n\n    Parameters\n    ----------\n    outdir : directory path\n       Output directory for the two shapefiles.\n\n    Returns\n    -------\n    None\n\n    Examples\n    --------\n    nx.write_shp(digraph, '/shapefiles') # doctest +SKIP\n\n    References\n    ----------\n    .. [1] http://en.wikipedia.org/wiki/Shapefile\n    \"\"\"\n    try:\n        from osgeo import ogr\n    except ImportError:\n        raise ImportError(\"write_shp requires OGR: http://www.gdal.org/\")\n    # easier to debug in python if ogr throws exceptions\n    ogr.UseExceptions()\n\n    def netgeometry(key, data):\n        if 'Wkb' in data:\n            geom = ogr.CreateGeometryFromWkb(data['Wkb'])\n        elif 'Wkt' in data:\n            geom = ogr.CreateGeometryFromWkt(data['Wkt'])\n        elif type(key[0]).__name__ == 'tuple':  # edge keys are packed tuples\n            geom = ogr.Geometry(ogr.wkbLineString)\n            _from, _to = key[0], key[1]\n            try:\n                geom.SetPoint(0, *_from)\n                geom.SetPoint(1, *_to)\n            except TypeError:\n                # assume user used tuple of int and choked ogr\n                _ffrom = [float(x) for x in _from]\n                _fto = [float(x) for x in _to]\n                geom.SetPoint(0, *_ffrom)\n                geom.SetPoint(1, *_fto)\n        else:\n            geom = ogr.Geometry(ogr.wkbPoint)\n            try:\n                geom.SetPoint(0, *key)\n            except TypeError:\n                # assume user used tuple of int and choked ogr\n                fkey = [float(x) for x in key]\n                geom.SetPoint(0, *fkey)\n\n        return geom\n\n    # Create_feature with new optional attributes arg (should be dict type)\n    def create_feature(geometry, lyr, attributes=None):\n        feature = ogr.Feature(lyr.GetLayerDefn())\n        feature.SetGeometry(g)\n        if attributes != None:\n            # Loop through attributes, assigning data to each field\n            for field, data in attributes.items():\n                feature.SetField(field, data)\n        lyr.CreateFeature(feature)\n        feature.Destroy()\n\n    drv = ogr.GetDriverByName(\"ESRI Shapefile\")\n    shpdir = drv.CreateDataSource(outdir)\n    # delete pre-existing output first otherwise ogr chokes\n    try:\n        shpdir.DeleteLayer(\"nodes\")\n    except:\n        pass\n    nodes = shpdir.CreateLayer(\"nodes\", None, ogr.wkbPoint)\n    for n in G:\n        data = G.node[n]\n        g = netgeometry(n, data)\n        create_feature(g, nodes)\n    try:\n        shpdir.DeleteLayer(\"edges\")\n    except:\n        pass\n    edges = shpdir.CreateLayer(\"edges\", None, ogr.wkbLineString)\n\n    # New edge attribute write support merged into edge loop\n    fields = {}      # storage for field names and their data types\n    attributes = {}  # storage for attribute data (indexed by field names)\n\n    # Conversion dict between python and ogr types\n    OGRTypes = {int: ogr.OFTInteger, str: ogr.OFTString, float: ogr.OFTReal}\n\n    # Edge loop\n    for e in G.edges(data=True):\n        data = G.get_edge_data(*e)\n        g = netgeometry(e, data)\n        # Loop through attribute data in edges\n        for key, data in e[2].items():\n            # Reject spatial data not required for attribute table\n            if (key != 'Json' and key != 'Wkt' and key != 'Wkb'\n                and key != 'ShpName'):\n                  # For all edges check/add field and data type to fields dict\n                    if key not in fields:\n                  # Field not in previous edges so add to dict\n                        if type(data) in OGRTypes:\n                            fields[key] = OGRTypes[type(data)]\n                        else:\n                            # Data type not supported, default to string (char 80)\n                            fields[key] = ogr.OFTString\n                        # Create the new field\n                        newfield = ogr.FieldDefn(key, fields[key])\n                        edges.CreateField(newfield)\n                        # Store the data from new field to dict for CreateLayer()\n                        attributes[key] = data\n                    else:\n                     # Field already exists, add data to dict for CreateLayer()\n                        attributes[key] = data\n        # Create the feature with, passing new attribute data\n        create_feature(g, edges, attributes)\n\n    nodes, edges = None, None\n\n\n# fixture for nose tests\ndef setup_module(module):\n    from nose import SkipTest\n    try:\n        import ogr\n    except:\n        raise SkipTest(\"OGR not available\")\n", "path": "networkx/readwrite/nx_shp.py"}]}