Repository: networkx/networkx

Issue:
Deprecate `Ordered` graph classes
Since the next NetworkX release will drop support for Python 3.6, dictionaries should be ordered by default in all supported Python implementations moving forward (though it's worth double-checking that this is true for PyPy). Thus the `Ordered` graph classes will be redundant moving forward and can be deprecated for 2.6 in preparation for removal in 3.0.

This [SO post](https://stackoverflow.com/questions/39980323/are-dictionaries-ordered-in-python-3-6) compiles a lot of useful links re: the status of guaranteed insertion order for various Python versions. The conclusion is that insertion-order preservation is guaranteed for dictionaries from Python 3.7 onward.


Discussion:
The [What's New in Python 3.6 docs](https://docs.python.org/3.6/whatsnew/3.6.html#new-dict-implementation) documentation has a paragraph about ordered dicts. It states that this feature was pioneered by Pypy.
A [post on Pypy documentation](https://morepypy.blogspot.com/2015/01/faster-more-memory-efficient-and-more.html) announces this way back in 2015. So pypy started the whole ordered dict thing and will continue it.
I read the linked post more carefully as well, and realized that though Python dictionaries now preserve insertion order, there are still some differences between default dictionaries and `OrderedDict`. The [OrdredDict docs](https://docs.python.org/3/library/collections.html#ordereddict-objects) provide a convenient list.

AFAICT, none of those differences directly impacts networkx, but I wanted to mention it just in case.

Resolving patch:
diff --git a/networkx/classes/ordered.py b/networkx/classes/ordered.py
--- a/networkx/classes/ordered.py
+++ b/networkx/classes/ordered.py
@@ -1,4 +1,10 @@
 """
+
+.. deprecated:: 2.6
+
+   The ordered variants of graph classes in this module are deprecated and
+   will be removed in version 3.0.
+
 Consistently ordered variants of the default base classes.
 Note that if you are using Python 3.6+, you shouldn't need these classes
 because the dicts in Python 3.6+ are ordered.
@@ -28,6 +34,7 @@
 
 """
 from collections import OrderedDict
+import warnings
 
 from .graph import Graph
 from .multigraph import MultiGraph
@@ -42,25 +49,70 @@
 
 
 class OrderedGraph(Graph):
-    """Consistently ordered variant of :class:`~networkx.Graph`."""
+    """Consistently ordered variant of :class:`~networkx.Graph`.
+
+    .. deprecated:: 2.6
+
+       OrderedGraph is deprecated and will be removed in version 3.0.
+       Use `Graph` instead, which guarantees order is preserved for
+       Python >= 3.7
+    """
 
     node_dict_factory = OrderedDict
     adjlist_outer_dict_factory = OrderedDict
     adjlist_inner_dict_factory = OrderedDict
     edge_attr_dict_factory = OrderedDict
 
+    def __init__(self, incoming_graph_data=None, **attr):
+        warnings.warn(
+            (
+                "OrderedGraph is deprecated and will be removed in version 3.0.\n"
+                "Use `Graph` instead, which guarantees order is preserved for\n"
+                "Python >= 3.7\n"
+            ),
+            DeprecationWarning,
+            stacklevel=2,
+        )
+        super(OrderedGraph, self).__init__(incoming_graph_data, **attr)
+
 
 class OrderedDiGraph(DiGraph):
-    """Consistently ordered variant of :class:`~networkx.DiGraph`."""
+    """Consistently ordered variant of :class:`~networkx.DiGraph`.
+
+    .. deprecated:: 2.6
+
+       OrderedDiGraph is deprecated and will be removed in version 3.0.
+       Use `DiGraph` instead, which guarantees order is preserved for
+       Python >= 3.7
+    """
 
     node_dict_factory = OrderedDict
     adjlist_outer_dict_factory = OrderedDict
     adjlist_inner_dict_factory = OrderedDict
     edge_attr_dict_factory = OrderedDict
 
+    def __init__(self, incoming_graph_data=None, **attr):
+        warnings.warn(
+            (
+                "OrderedDiGraph is deprecated and will be removed in version 3.0.\n"
+                "Use `DiGraph` instead, which guarantees order is preserved for\n"
+                "Python >= 3.7\n"
+            ),
+            DeprecationWarning,
+            stacklevel=2,
+        )
+        super(OrderedDiGraph, self).__init__(incoming_graph_data, **attr)
+
 
 class OrderedMultiGraph(MultiGraph):
-    """Consistently ordered variant of :class:`~networkx.MultiGraph`."""
+    """Consistently ordered variant of :class:`~networkx.MultiGraph`.
+
+    .. deprecated:: 2.6
+
+       OrderedMultiGraph is deprecated and will be removed in version 3.0.
+       Use `MultiGraph` instead, which guarantees order is preserved for
+       Python >= 3.7
+    """
 
     node_dict_factory = OrderedDict
     adjlist_outer_dict_factory = OrderedDict
@@ -68,12 +120,43 @@ class OrderedMultiGraph(MultiGraph):
     edge_key_dict_factory = OrderedDict
     edge_attr_dict_factory = OrderedDict
 
+    def __init__(self, incoming_graph_data=None, **attr):
+        warnings.warn(
+            (
+                "OrderedMultiGraph is deprecated and will be removed in version 3.0.\n"
+                "Use `MultiGraph` instead, which guarantees order is preserved for\n"
+                "Python >= 3.7\n"
+            ),
+            DeprecationWarning,
+            stacklevel=2,
+        )
+        super(OrderedMultiGraph, self).__init__(incoming_graph_data, **attr)
+
 
 class OrderedMultiDiGraph(MultiDiGraph):
-    """Consistently ordered variant of :class:`~networkx.MultiDiGraph`."""
+    """Consistently ordered variant of :class:`~networkx.MultiDiGraph`.
+
+    .. deprecated:: 2.6
+
+       OrderedMultiDiGraph is deprecated and will be removed in version 3.0.
+       Use `MultiDiGraph` instead, which guarantees order is preserved for
+       Python >= 3.7
+    """
 
     node_dict_factory = OrderedDict
     adjlist_outer_dict_factory = OrderedDict
     adjlist_inner_dict_factory = OrderedDict
     edge_key_dict_factory = OrderedDict
     edge_attr_dict_factory = OrderedDict
+
+    def __init__(self, incoming_graph_data=None, **attr):
+        warnings.warn(
+            (
+                "OrderedMultiDiGraph is deprecated and will be removed in version 3.0.\n"
+                "Use `MultiDiGraph` instead, which guarantees order is preserved for\n"
+                "Python >= 3.7\n"
+            ),
+            DeprecationWarning,
+            stacklevel=2,
+        )
+        super(OrderedMultiDiGraph, self).__init__(incoming_graph_data, **attr)
diff --git a/networkx/conftest.py b/networkx/conftest.py
--- a/networkx/conftest.py
+++ b/networkx/conftest.py
@@ -27,6 +27,9 @@ def pytest_collection_modifyitems(config, items):
 # TODO: The warnings below need to be dealt with, but for now we silence them.
 @pytest.fixture(autouse=True)
 def set_warnings():
+    warnings.filterwarnings(
+        "ignore", category=DeprecationWarning, message=r"Ordered.* is deprecated"
+    )
     warnings.filterwarnings(
         "ignore",
         category=DeprecationWarning,


Test patch: