
    h                       S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSKJ	r	  SSK
rSSKJrJrJr  SSKJr  S/r\R&                  " \5      rS	 rS
S.S jr\" S5      r0 r0 r0 rS rS rS rS r " S S5      r S r!S r"SSS.S jr#SS.S jr$ " S S5      r%\RL                  RO                  S5      (       a  \ r(SS jr \(RR                  R                   \ l         \RT                  " \(RR                  5      r+\+RY                  \+RZ                  R]                  5        V Vs/ s H  u  pU S:w  d  M  UPM     snn S9\ l/        ggs  snn f ) a\  
Docs for backend users
~~~~~~~~~~~~~~~~~~~~~~
NetworkX utilizes a plugin-dispatch architecture. A valid NetworkX backend
specifies `entry points
<https://packaging.python.org/en/latest/specifications/entry-points>`_, named
``networkx.backends`` and an optional ``networkx.backend_info`` when it is
installed (not imported). This allows NetworkX to dispatch (redirect) function
calls to the backend so the execution flows to the designated backend
implementation. This design enhances flexibility and integration, making
NetworkX more adaptable and efficient.

NetworkX can dispatch to backends **explicitly** (this requires changing code)
or **automatically** (this requires setting configuration or environment
variables). The best way to use a backend depends on the backend, your use
case, and whether you want to automatically convert to or from backend
graphs. Automatic conversions of graphs is always opt-in.

To explicitly dispatch to a backend, use the `backend=` keyword argument in a
dispatchable function. This will convert (and cache by default) input NetworkX
graphs to backend graphs and call the backend implementation. Another explicit
way to use a backend is to create a backend graph directly--for example,
perhaps the backend has its own functions for loading data and creating
graphs--and pass that graph to a dispatchable function, which will then call
the backend implementation without converting.

Using automatic dispatch requires setting configuration options. Every NetworkX
configuration may also be set from an environment variable and are processed at
the time networkx is imported.  The following configuration variables are
supported:

* ``nx.config.backend_priority`` (``NETWORKX_BACKEND_PRIORITY`` env var), a
  list of backends, controls dispatchable functions that don't return graphs
  such as e.g. ``nx.pagerank``. When one of these functions is called with
  NetworkX graphs as input, the dispatcher iterates over the backends listed in
  this backend_priority config and will use the first backend that implements
  this function. The input NetworkX graphs are converted (and cached by
  default) to backend graphs. Using this configuration can allow you to use the
  full flexibility of NetworkX graphs and the performance of backend
  implementations, but possible downsides are that creating NetworkX graphs,
  converting to backend graphs, and caching backend graphs may all be
  expensive.

* ``nx.config.backend_priority.algos`` (``NETWORKX_BACKEND_PRIORITY_ALGOS`` env
  var), can be used instead of ``nx.config.backend_priority``
  (``NETWORKX_BACKEND_PRIORITY`` env var) to emphasize that the setting only
  affects the dispatching of algorithm functions as described above.

* ``nx.config.backend_priority.generators``
  (``NETWORKX_BACKEND_PRIORITY_GENERATORS`` env var), a list of backends,
  controls dispatchable functions that return graphs such as
  nx.from_pandas_edgelist and nx.empty_graph. When one of these functions is
  called, the first backend listed in this backend_priority config that
  implements this function will be used and will return a backend graph. When
  this backend graph is passed to other dispatchable NetworkX functions, it
  will use the backend implementation if it exists or raise by default unless
  nx.config.fallback_to_nx is True (default is False). Using this configuration
  avoids creating NetworkX graphs, which subsequently avoids the need to
  convert to and cache backend graphs as when using
  nx.config.backend_priority.algos, but possible downsides are that the backend
  graph may not behave the same as a NetworkX graph and the backend may not
  implement all algorithms that you use, which may break your workflow.

* ``nx.config.fallback_to_nx`` (``NETWORKX_FALLBACK_TO_NX`` env var), a boolean
  (default False), controls what happens when a backend graph is passed to a
  dispatchable function that is not implemented by that backend. The default
  behavior when False is to raise. If True, then the backend graph will be
  converted (and cached by default) to a NetworkX graph and will run with the
  default NetworkX implementation. Enabling this configuration can allow
  workflows to complete if the backend does not implement all algorithms used
  by the workflow, but a possible downside is that it may require converting
  the input backend graph to a NetworkX graph, which may be expensive. If a
  backend graph is duck-type compatible as a NetworkX graph, then the backend
  may choose not to convert to a NetworkX graph and use the incoming graph
  as-is.

* ``nx.config.cache_converted_graphs`` (``NETWORKX_CACHE_CONVERTED_GRAPHS`` env
  var), a boolean (default True), controls whether graph conversions are cached
  to G.__networkx_cache__ or not. Caching can improve performance by avoiding
  repeated conversions, but it uses more memory.

.. note:: Backends *should* follow the NetworkX backend naming convention. For
   example, if a backend is named ``parallel`` and specified using
   ``backend=parallel`` or ``NETWORKX_BACKEND_PRIORITY=parallel``, the package
   installed is ``nx-parallel``, and we would use ``import nx_parallel`` if we
   were to import the backend package directly.

Backends are encouraged to document how they recommend to be used and whether
their graph types are duck-type compatible as NetworkX graphs. If backend
graphs are NetworkX-compatible and you want your workflow to automatically
"just work" with a backend--converting and caching if necessary--then use all
of the above configurations. Automatically converting graphs is opt-in, and
configuration gives the user control.

Examples:
---------

Use the ``cugraph`` backend for every algorithm function it supports. This will
allow for fall back to the default NetworkX implementations for algorithm calls
not supported by cugraph because graph generator functions are still returning
NetworkX graphs.

.. code-block:: bash

   bash> NETWORKX_BACKEND_PRIORITY=cugraph python my_networkx_script.py

Explicitly use the ``parallel`` backend for a function call.

.. code-block:: python

    nx.betweenness_centrality(G, k=10, backend="parallel")

Explicitly use the ``parallel`` backend for a function call by passing an
instance of the backend graph type to the function.

.. code-block:: python

   H = nx_parallel.ParallelGraph(G)
   nx.betweenness_centrality(H, k=10)

Explicitly use the ``parallel`` backend and pass additional backend-specific
arguments. Here, ``get_chunks`` is an argument unique to the ``parallel``
backend.

.. code-block:: python

   nx.betweenness_centrality(G, k=10, backend="parallel", get_chunks=get_chunks)

Automatically dispatch the ``cugraph`` backend for all NetworkX algorithms and
generators, and allow the backend graph object returned from generators to be
passed to NetworkX functions the backend does not support.

.. code-block:: bash

   bash> NETWORKX_BACKEND_PRIORITY_ALGOS=cugraph \
         NETWORKX_BACKEND_PRIORITY_GENERATORS=cugraph \
         NETWORKX_FALLBACK_TO_NX=True \
         python my_networkx_script.py

How does this work?
-------------------

If you've looked at functions in the NetworkX codebase, you might have seen the
``@nx._dispatchable`` decorator on most of the functions. This decorator allows the NetworkX
function to dispatch to the corresponding backend function if available. When the decorated
function is called, it first checks for a backend to run the function, and if no appropriate
backend is specified or available, it runs the NetworkX version of the function.

Backend Keyword Argument
^^^^^^^^^^^^^^^^^^^^^^^^

When a decorated function is called with the ``backend`` kwarg provided, it checks
if the specified backend is installed, and loads it. Next it checks whether to convert
input graphs by first resolving the backend of each input graph by looking
for an attribute named ``__networkx_backend__`` that holds the backend name for that
graph type. If all input graphs backend matches the ``backend`` kwarg, the backend's
function is called with the original inputs. If any of the input graphs do not match
the ``backend`` kwarg, they are converted to the backend graph type before calling.
Exceptions are raised if any step is not possible, e.g. if the backend does not
implement this function.

Finding a Backend
^^^^^^^^^^^^^^^^^

When a decorated function is called without a ``backend`` kwarg, it tries to find a
dispatchable backend function.
The backend type of each input graph parameter is resolved (using the
``__networkx_backend__`` attribute) and if they all agree, that backend's function
is called if possible. Otherwise the backends listed in the config ``backend_priority``
are considered one at a time in order. If that backend supports the function and
can convert the input graphs to its backend type, that backend function is called.
Otherwise the next backend is considered.

During this process, the backends can provide helpful information to the dispatcher
via helper methods in the backend's interface. Backend methods ``can_run`` and
``should_run`` are used by the dispatcher to determine whether to use the backend
function. If the number of nodes is small, it might be faster to run the NetworkX
version of the function. This is how backends can provide info about whether to run.

Falling Back to NetworkX
^^^^^^^^^^^^^^^^^^^^^^^^

If none of the backends are appropriate, we "fall back" to the NetworkX function.
That means we resolve the backends of all input graphs and if all are NetworkX
graphs we call the NetworkX function. If any are not NetworkX graphs, we raise
an exception unless the `fallback_to_nx` config is set. If it is, we convert all
graph types to NetworkX graph types before calling the NetworkX function.

Functions that mutate the graph
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Any function decorated with the option that indicates it mutates the graph goes through
a slightly different path to automatically find backends. These functions typically
generate a graph, or add attributes or change the graph structure. The config
`backend_priority.generators` holds a list of backend names similar to the config
`backend_priority`. The process is similar for finding a matching backend. Once found,
the backend function is called and a backend graph is returned (instead of a NetworkX
graph). You can then use this backend graph in any function supported by the backend.
And you can use it for functions not supported by the backend if you set the config
`fallback_to_nx` to allow it to convert the backend graph to a NetworkX graph before
calling the function.

Optional keyword arguments
^^^^^^^^^^^^^^^^^^^^^^^^^^

Backends can add optional keyword parameters to NetworkX functions to allow you to
control aspects of the backend algorithm. Thus the function signatures can be extended
beyond the NetworkX function signature. For example, the ``parallel`` backend might
have a parameter to specify how many CPUs to use. These parameters are collected
by the dispatchable decorator code at the start of the function call and used when
calling the backend function.

Existing Backends
^^^^^^^^^^^^^^^^^

NetworkX does not know all the backends that have been created.  In fact, the
NetworkX library does not need to know that a backend exists for it to work. As
long as the backend package creates the ``entry_point``, and provides the
correct interface, it will be called when the user requests it using one of the
three approaches described above. Some backends have been working with the
NetworkX developers to ensure smooth operation.

Refer to the :doc:`/backends` section to see a list of available backends known
to work with the current stable release of NetworkX.

.. _introspect:

Introspection and Logging
-------------------------
Introspection techniques aim to demystify dispatching and backend graph conversion behaviors.

The primary way to see what the dispatch machinery is doing is by enabling logging.
This can help you verify that the backend you specified is being used.
You can enable NetworkX's backend logger to print to ``sys.stderr`` like this::

    import logging
    nxl = logging.getLogger("networkx")
    nxl.addHandler(logging.StreamHandler())
    nxl.setLevel(logging.DEBUG)

And you can disable it by running this::

    nxl.setLevel(logging.CRITICAL)

Refer to :external+python:mod:`logging` to learn more about the logging facilities in Python.

By looking at the ``.backends`` attribute, you can get the set of all currently
installed backends that implement a particular function. For example::

    >>> nx.betweenness_centrality.backends  # doctest: +SKIP
    {'parallel'}

The function docstring will also show which installed backends support it
along with any backend-specific notes and keyword arguments::

    >>> help(nx.betweenness_centrality)  # doctest: +SKIP
    ...
    Backends
    --------
    parallel : Parallel backend for NetworkX algorithms
      The parallel computation is implemented by dividing the nodes into chunks
      and computing betweenness centrality for each chunk concurrently.
    ...

The NetworkX documentation website also includes info about trusted backends of NetworkX in function references.
For example, see :func:`~networkx.algorithms.shortest_paths.weighted.all_pairs_bellman_ford_path_length`.

Introspection capabilities are currently limited, but we are working to improve them.
We plan to make it easier to answer questions such as:

- What happened (and why)?
- What *will* happen (and why)?
- Where was time spent (including conversions)?
- What is in the cache and how much memory is it using?

Transparency is essential to allow for greater understanding, debug-ability,
and customization. After all, NetworkX dispatching is extremely flexible and can
support advanced workflows with multiple backends and fine-tuned configuration,
but introspection can be helpful by describing *when* and *how* to evolve your workflow
to meet your needs. If you have suggestions for how to improve introspection, please
`let us know <https://github.com/networkx/networkx/issues/new>`_!

Docs for backend developers
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Creating a custom backend
-------------------------

1.  Defining a ``BackendInterface`` object:

    Note that the ``BackendInterface`` doesn't need to must be a class. It can be an
    instance of a class, or a module as well. You can define the following methods or
    functions in your backend's ``BackendInterface`` object.:

    1. ``convert_from_nx`` and ``convert_to_nx`` methods or functions are required for
       backend dispatching to work. The arguments to ``convert_from_nx`` are:

       - ``G`` : NetworkX Graph
       - ``edge_attrs`` : dict, optional
            Dictionary mapping edge attributes to default values if missing in ``G``.
            If None, then no edge attributes will be converted and default may be 1.
       - ``node_attrs``: dict, optional
            Dictionary mapping node attributes to default values if missing in ``G``.
            If None, then no node attributes will be converted.
       - ``preserve_edge_attrs`` : bool
            Whether to preserve all edge attributes.
       - ``preserve_node_attrs`` : bool
            Whether to preserve all node attributes.
       - ``preserve_graph_attrs`` : bool
            Whether to preserve all graph attributes.
       - ``preserve_all_attrs`` : bool
            Whether to preserve all graph, node, and edge attributes.
       - ``name`` : str
            The name of the algorithm.
       - ``graph_name`` : str
            The name of the graph argument being converted.

    2. ``can_run`` (Optional):
          If your backend only partially implements an algorithm, you can define
          a ``can_run(name, args, kwargs)`` function in your ``BackendInterface`` object that
          returns True or False indicating whether the backend can run the algorithm with
          the given arguments or not. Instead of a boolean you can also return a string
          message to inform the user why that algorithm can't be run.

    3. ``should_run`` (Optional):
          A backend may also define ``should_run(name, args, kwargs)``
          that is similar to ``can_run``, but answers whether the backend *should* be run.
          ``should_run`` is only run when performing backend graph conversions. Like
          ``can_run``, it receives the original arguments so it can decide whether it
          should be run by inspecting the arguments. ``can_run`` runs before
          ``should_run``, so ``should_run`` may assume ``can_run`` is True. If not
          implemented by the backend, ``can_run``and ``should_run`` are assumed to
          always return True if the backend implements the algorithm.

    4. ``on_start_tests`` (Optional):
          A special ``on_start_tests(items)`` function may be defined by the backend.
          It will be called with the list of NetworkX tests discovered. Each item
          is a test object that can be marked as xfail if the backend does not support
          the test using ``item.add_marker(pytest.mark.xfail(reason=...))``.

2.  Adding entry points

    To be discoverable by NetworkX, your package must register an
    `entry-point <https://packaging.python.org/en/latest/specifications/entry-points>`_
    ``networkx.backends`` in the package's metadata, with a `key pointing to your
    dispatch object <https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/#using-package-metadata>`_ .
    For example, if you are using ``setuptools`` to manage your backend package,
    you can `add the following to your pyproject.toml file <https://setuptools.pypa.io/en/latest/userguide/entry_point.html>`_::

        [project.entry-points."networkx.backends"]
        backend_name = "your_backend_interface_object"

    You can also add the ``backend_info`` entry-point. It points towards the ``get_info``
    function that returns all the backend information, which is then used to build the
    "Additional Backend Implementation" box at the end of algorithm's documentation
    page. Note that the `get_info` function shouldn't import your backend package.::

        [project.entry-points."networkx.backend_info"]
        backend_name = "your_get_info_function"

    The ``get_info`` should return a dictionary with following key-value pairs:
        - ``backend_name`` : str or None
            It is the name passed in the ``backend`` kwarg.
        - ``project`` : str or None
            The name of your backend project.
        - ``package`` : str or None
            The name of your backend package.
        - ``url`` : str or None
            This is the url to either your backend's codebase or documentation, and
            will be displayed as a hyperlink to the ``backend_name``, in the
            "Additional backend implementations" section.
        - ``short_summary`` : str or None
            One line summary of your backend which will be displayed in the
            "Additional backend implementations" section.
        - ``default_config`` : dict
            A dictionary mapping the backend config parameter names to their default values.
            This is used to automatically initialize the default configs for all the
            installed backends at the time of networkx's import.

            .. seealso:: `~networkx.utils.configs.Config`

        - ``functions`` : dict or None
            A dictionary mapping function names to a dictionary of information
            about the function. The information can include the following keys:

            - ``url`` : str or None
              The url to ``function``'s source code or documentation.
            - ``additional_docs`` : str or None
              A short description or note about the backend function's
              implementation.
            - ``additional_parameters`` : dict or None
              A dictionary mapping additional parameters headers to their
              short descriptions. For example::

                  "additional_parameters": {
                      'param1 : str, function (default = "chunks")' : "...",
                      'param2 : int' : "...",
                  }

            If any of these keys are not present, the corresponding information
            will not be displayed in the "Additional backend implementations"
            section on NetworkX docs website.

        Note that your backend's docs would only appear on the official NetworkX docs only
        if your backend is a trusted backend of NetworkX, and is present in the
        `.circleci/config.yml` and `.github/workflows/deploy-docs.yml` files in the
        NetworkX repository.

3.  Defining a Backend Graph class

    The backend must create an object with an attribute ``__networkx_backend__`` that holds
    a string with the entry point name::

        class BackendGraph:
            __networkx_backend__ = "backend_name"
            ...

    A backend graph instance may have a ``G.__networkx_cache__`` dict to enable
    caching, and care should be taken to clear the cache when appropriate.

Testing the Custom backend
--------------------------

To test your custom backend, you can run the NetworkX test suite on your backend.
This also ensures that the custom backend is compatible with NetworkX's API.
The following steps will help you run the tests:

1. Setting Backend Environment Variables:
    - ``NETWORKX_TEST_BACKEND`` : Setting this to your backend's ``backend_name`` will
      let NetworkX's dispatch machinery to automatically convert a regular NetworkX
      ``Graph``, ``DiGraph``, ``MultiGraph``, etc. to their backend equivalents, using
      ``your_backend_interface_object.convert_from_nx(G, ...)`` function.
    - ``NETWORKX_FALLBACK_TO_NX`` (default=False) : Setting this variable to `True` will
      instruct tests to use a NetworkX ``Graph`` for algorithms not implemented by your
      custom backend. Setting this to `False` will only run the tests for algorithms
      implemented by your custom backend and tests for other algorithms will ``xfail``.

2. Running Tests:
    You can invoke NetworkX tests for your custom backend with the following commands::

        NETWORKX_TEST_BACKEND=<backend_name>
        NETWORKX_FALLBACK_TO_NX=True # or False
        pytest --pyargs networkx

How tests are run?
------------------

1. While dispatching to the backend implementation the ``_convert_and_call`` function
   is used and while testing the ``_convert_and_call_for_tests`` function is used.
   Other than testing it also checks for functions that return numpy scalars, and
   for functions that return graphs it runs the backend implementation and the
   networkx implementation and then converts the backend graph into a NetworkX graph
   and then compares them, and returns the networkx graph. This can be regarded as
   (pragmatic) technical debt. We may replace these checks in the future.

2. Conversions while running tests:
    - Convert NetworkX graphs using ``<your_backend_interface_object>.convert_from_nx(G, ...)`` into
      the backend graph.
    - Pass the backend graph objects to the backend implementation of the algorithm.
    - Convert the result back to a form expected by NetworkX tests using
      ``<your_backend_interface_object>.convert_to_nx(result, ...)``.
    - For nx_loopback, the graph is copied using the dispatchable metadata

3. Dispatchable algorithms that are not implemented by the backend
   will cause a ``pytest.xfail``, when the ``NETWORKX_FALLBACK_TO_NX``
   environment variable is set to ``False``, giving some indication that
   not all tests are running, while avoiding causing an explicit failure.
    N)partial)entry_points   )BackendPrioritiesConfigNetworkXConfig)argmap_dispatchablec                      g)zKThis does nothing at all, yet it helps turn `_dispatchable` into functions.N r       I/var/www/html/env/lib/python3.13/site-packages/networkx/utils/backends.py_do_nothingr     s    r   Fload_and_callc                   [        U S9n0 nU Hu  nUR                  U;   a)  [        R                  " SUR                   3[        SS9  M<  U(       a$   UR                  5       " 5       X4R                  '   Mg  XCUR                  '   Mw     UR                  SS5        U$ ! [         a5  n[        R                  " SUR                   SU 3[        SS9   SnAM  SnAff = f)	a;  
Retrieve NetworkX ``backends`` and ``backend_info`` from the entry points.

Parameters
-----------
group : str
    The entry_point to be retrieved.
load_and_call : bool, optional
    If True, load and call the backend. Defaults to False.

Returns
--------
dict
    A dictionary mapping backend names to their respective backend objects.

Notes
------
If a backend is defined more than once, a warning is issued.
The `nx_loopback` backend is removed if it exists, as it is only available during testing.
A warning is displayed if an error occurs while loading a backend.
)groupz)networkx backend defined more than once:    )
stacklevelz0Error encountered when loading info for backend z: Nnx_loopback)r   namewarningswarnRuntimeWarningload	Exceptionpop)r   r   itemsrvepexcs         r   _get_backendsr"     s    , u%E	B77b=MM;BGG9E
  ggik77 rwwK# $ FF=$I  FrwwirRUQVW"  s   !B
C%*CCznetworkx.backendsc                     U R                  5       R                  S5       Vs/ s H  oR                  5       =n(       d  M  UPM     sn$ s  snf )N,)stripsplit)stringxstrippeds      r   _comma_sep_to_listr*   &  s;    $lln2237S7	<QH<QH7SSSs   A	 A	c                     [         R                  [        SSS95        [         R                  S [        R	                  5       [         R	                  5       -
   5       5        [        [        / / S9[        S0 [         R                  5        V Vs0 s H=  u  pU SU;   a'  [        US   =n[        5      (       a  UO[        S0 UD6O	[        5       _M?     snn D6[        [        R                  R                  SS5      5      [        [        R                  R                  SS	5      5      [        R                  R                  S
S5      R                  S5       Vs1 s H*  nUR                  5       (       d  M  UR                  5       iM,     snS9n0 [         S'   S[!        UR                  5      l        [        R                  R                  5        VVs0 s H1  u  pVUR%                  S5      (       d  M  USS R'                  5       U_M3     nnnUR(                  nSU;   a  [+        UR-                  S5      5      OF[+        [        R                  R                  S[        R                  R                  SS5      5      5      Ul        [+        UR-                  SS5      5      Ul        [3        U5       H  n[+        Xu   5      X'   M     U$ s  snn f s  snf s  snnf )a  Initialize ``config.backend_priority``, load backend_info and config.

This gets default values from environment variables (see ``nx.config`` for details).
This function is run at the very end of importing networkx. It is run at this time
to avoid loading backend_info before the rest of networkx is imported in case a
backend uses networkx for its backend_info (e.g. subclassing the Config class.)
znetworkx.backend_infoTr   c              3   (   #    U  H  o0 4v   M
     g 7fNr   ).0backends     r   	<genexpr>0_set_configs_from_environment.<locals>.<genexpr>4  s      %J'"%J   )algos
generatorsdefault_configNETWORKX_CACHE_CONVERTED_GRAPHSNETWORKX_FALLBACK_TO_NXFNETWORKX_WARNINGS_TO_IGNORE r$   )backend_prioritybackendscache_converted_graphsfallback_to_nxwarnings_to_ignorenetworkxz2All installed NetworkX backends and their configs.NETWORKX_BACKEND_PRIORITY_   Nr3   NETWORKX_BACKEND_PRIORITYNETWORKX_AUTOMATIC_BACKENDSr4   r   )backend_infoupdater"   r;   keysr   r   r   r   
isinstanceboolosenvirongetr&   r%   type__doc__
startswithlowerr:   r*   r   r3   r4   sorted)	r/   infocfgr(   configkeyval
prioritiesr:   s	            r   _set_configs_from_environmentrW   *  s~    &=TRS %-]]_|7H7H7J%J 
 *
  
 &2%7%7%9	 &:MG 
 $t+ ".>)?"?#HH # X &:	
  $JJNN<dC 
 BJJNN+DeLM ZZ^^$A2FLLSQ
Qwwy AGGIQ
+F6  "L$XD!
 

((**HC>>67 	BC#*  
 .. j  	:>>'23JJNN+

<bA
  #5Z^^LRT5U"Vj! 2:? C " M[	
s   AKK4KK1Kc                     g)NTr   )r   argskwargss      r   _always_runr[   o  s    r   c                    U [         ;   a	  [         U    $ U [        ;  a  [        SU  S35      e[        U    R                  5       =n[         U '   [	        US5      (       d  [
        Ul        [	        US5      (       d  [
        Ul        U$ )N'' backend is not installedcan_run
should_run)_loaded_backendsr;   ImportErrorr   hasattrr[   r_   r`   )backend_namer   s     r   _load_backendre   s  s~    ''--8#Al^+EFGG*2<*@*E*E*GGB	,	'2y!! 
2|$$#Ir   c                      \ rS rSrSr " S S5      r\" 5       r SSSSSSSSSSSS.
S jjr\S	 5       r\R                  S
 5       r\S 5       r
SS.S jrS rS rS rS rS rS rS rSS.S jrSSS.S jrSS.S jrS rS rSrg)r
   i  Fc                   "    \ rS rSrSrSS jrSrg)_dispatchable._fallback_to_nxi  z9Class property that returns ``nx.config.fallback_to_nx``.Nc                 j    [         R                  " S[        SS9  [        R                  R
                  $ )Nz{`_dispatchable._fallback_to_nx` is deprecated and will be removed in NetworkX v3.5. Use `nx.config.fallback_to_nx` instead.r   )categoryr   )r   r   DeprecationWarningnxrS   r=   )selfinstanceowners      r   __get__%_dispatchable._fallback_to_nx.__get__  s,    MML+	 99+++r   r   r-   )__name__
__module____qualname____firstlineno__rM   rp   __static_attributes__r   r   r   _fallback_to_nxrh     s
    G	,r   rw   NG
r   graphs
edge_attrs
node_attrspreserve_edge_attrspreserve_node_attrspreserve_graph_attrspreserve_all_attrsmutates_inputreturns_graphc       
         	   Uc  [        [        UUUUUUUU	U
US9$ [        U[        5      (       a  [	        S5      SeUc  UR
                  n[        R                  U 5      nUR
                  Ul        UR                  Ul        UR                  (       a  0 UR                  ESS0EUl	        O	SS0Ul	        UR                  Ul
        UR                  Ul        UR                  R                  UR                  5        Xl        UR                  Ul        SUl        Xl        X,l        XLl        X\l        U=(       d    U	Ul        U=(       d    U	Ul        U=(       d    U	Ul        Xl        Xl        Ub5  [        U[        [6        -  5      (       d  [	        S[9        U5       S35      SeUb5  [        U[        [6        -  5      (       d  [	        S[9        U5       S35      Se[        UR,                  [:        [        -  [6        -  5      (       d#  [	        S[9        UR,                  5       S	35      Se[        UR.                  [:        [        -  [6        -  5      (       d#  [	        S
[9        UR.                  5       S	35      Se[        UR0                  [:        [<        -  5      (       d#  [	        S[9        UR0                  5       S35      Se[        UR2                  [:        [6        -  5      (       d#  [	        S[9        UR2                  5       S35      Se[        UR4                  [:        5      (       d#  [	        S[9        UR4                  5       S35      Se[        U[        5      (       a  US0nOMUc  OI[        U[6        5      (       d  [	        S[9        U5       S35      Se[?        U5      S:X  a  [A        S5      Se[=        5       Ul!        [=        5       Ul"        Uc  0 Ul#        OURI                  5        VVs0 s Hk  u  pUS   =nS:X  a)  URB                  RK                  USS =n5      =(       d    UO0US:X  a)  URD                  RK                  USS =n5      =(       d    UOUU_Mm     snnUl#        SUl&        [N        RI                  5        VVs1 s H  u  nnSU;   d  M  UUS   ;   d  M  UiM     snnUl(        U[R        ;   a  [A        SU 35      Se[U        [V        5      " U5      nU[R        U'   U$ s  snnf s  snnf )a  A decorator function that is used to redirect the execution of ``func``
function to its backend implementation.

This decorator function dispatches to
a different backend implementation based on the input graph types, and it also
manages all the ``backend_kwargs``. Usage can be any of the following decorator
forms:

- ``@_dispatchable``
- ``@_dispatchable()``
- ``@_dispatchable(name="override_name")``
- ``@_dispatchable(graphs="graph_var_name")``
- ``@_dispatchable(edge_attrs="weight")``
- ``@_dispatchable(graphs={"G": 0, "H": 1}, edge_attrs={"weight": "default"})``
    with 0 and 1 giving the position in the signature function for graph
    objects. When ``edge_attrs`` is a dict, keys are keyword names and values
    are defaults.

Parameters
----------
func : callable, optional
    The function to be decorated. If ``func`` is not provided, returns a
    partial object that can be used to decorate a function later. If ``func``
    is provided, returns a new callable object that dispatches to a backend
    algorithm based on input graph types.

name : str, optional
    The name of the algorithm to use for dispatching. If not provided,
    the name of ``func`` will be used. ``name`` is useful to avoid name
    conflicts, as all dispatched algorithms live in a single namespace.
    For example, ``tournament.is_strongly_connected`` had a name conflict
    with the standard ``nx.is_strongly_connected``, so we used
    ``@_dispatchable(name="tournament_is_strongly_connected")``.

graphs : str or dict or None, default "G"
    If a string, the parameter name of the graph, which must be the first
    argument of the wrapped function. If more than one graph is required
    for the algorithm (or if the graph is not the first argument), provide
    a dict keyed to argument names with argument position as values for each
    graph argument. For example, ``@_dispatchable(graphs={"G": 0, "auxiliary?": 4})``
    indicates the 0th parameter ``G`` of the function is a required graph,
    and the 4th parameter ``auxiliary?`` is an optional graph.
    To indicate that an argument is a list of graphs, do ``"[graphs]"``.
    Use ``graphs=None``, if *no* arguments are NetworkX graphs such as for
    graph generators, readers, and conversion functions.

edge_attrs : str or dict, optional
    ``edge_attrs`` holds information about edge attribute arguments
    and default values for those edge attributes.
    If a string, ``edge_attrs`` holds the function argument name that
    indicates a single edge attribute to include in the converted graph.
    The default value for this attribute is 1. To indicate that an argument
    is a list of attributes (all with default value 1), use e.g. ``"[attrs]"``.
    If a dict, ``edge_attrs`` holds a dict keyed by argument names, with
    values that are either the default value or, if a string, the argument
    name that indicates the default value.

node_attrs : str or dict, optional
    Like ``edge_attrs``, but for node attributes.

preserve_edge_attrs : bool or str or dict, optional
    For bool, whether to preserve all edge attributes.
    For str, the parameter name that may indicate (with ``True`` or a
    callable argument) whether all edge attributes should be preserved
    when converting.
    For dict of ``{graph_name: {attr: default}}``, indicate pre-determined
    edge attributes (and defaults) to preserve for input graphs.

preserve_node_attrs : bool or str or dict, optional
    Like ``preserve_edge_attrs``, but for node attributes.

preserve_graph_attrs : bool or set
    For bool, whether to preserve all graph attributes.
    For set, which input graph arguments to preserve graph attributes.

preserve_all_attrs : bool
    Whether to preserve all edge, node and graph attributes.
    This overrides all the other preserve_*_attrs.

mutates_input : bool or dict, default False
    For bool, whether the function mutates an input graph argument.
    For dict of ``{arg_name: arg_pos}``, arguments that indicate whether an
    input graph will be mutated, and ``arg_name`` may begin with ``"not "``
    to negate the logic (for example, this is used by ``copy=`` arguments).
    By default, dispatching doesn't convert input graphs to a different
    backend for functions that mutate input graphs.

returns_graph : bool, default False
    Whether the function can return or yield a graph object. By default,
    dispatching doesn't convert input graphs to a different backend for
    functions that return graphs.
Nry   z-'name' and 'graphs' must be passed by keywordr/   zBad type for edge_attrs: z. Expected str or dict.zBad type for node_attrs: z"Bad type for preserve_edge_attrs: z. Expected bool, str, or dict.z"Bad type for preserve_node_attrs: z#Bad type for preserve_graph_attrs: z. Expected bool or set.zBad type for mutates_input: z. Expected bool or dict.zBad type for returns_graph: z. Expected bool.r   zBad type for graphs: z0'graphs' must contain at least one variable name?]r   	functionsz/Algorithm already exists in dispatch registry: ),r   r
   rG   str	TypeErrorrr   object__new____defaults____kwdefaults__rs   rt   __dict__rE   __wrapped__rM   	_orig_doc_cached_doc	orig_funcr   r{   r|   r}   r~   r   r   _returns_graphdictrL   rH   setlenKeyErroroptional_graphslist_graphsrz   r   add_sigrD   r;   _registered_algorithmsr	   r   )clsfuncr   rz   r{   r|   r}   r~   r   r   r   r   rm   kvlastrU   r/   rQ   s                      r   r   _dispatchable.__new__  s    V <%%$7$7%9#5++  dC  KLRVV<==D~~c"  --"JT%8%8"J)T"JD#,d"3D// --T]]+ 	$$#6#L:L #6#L:L $8$N<N!*+!*Zt*L*L+D,<+==TU !*Zt*L*L+D,<+==TU $22D3J4EFF4T$:R:R5S4T U0 0  $22D3J4EFF4T$:R:R5S4T U0 0  $33TCZ@@5d4;T;T6U5V W) )  $,,dTk::.tD4F4F/G.H I* *  $--t44.tD4G4G/H.I J" " 
 fc""a[F^FD))'V~5LM [AMNTXX  #u5>DK #LLN +DA	 bEMDc) $$((#27>3 3; %%))1R.#9@S	
 +DK 	
 ".!3!3!5
!5d" '+tK/@'@ !5
 ))A$H k"4('+t$C"
s   4A2S1S7S7)S7c                 T    U R                   =nb  U$ U R                  5       =ol         U$ )zIf the cached documentation exists, it is returned.
Otherwise, the documentation is generated using _make_doc() method,
cached, and then returned.)r   	_make_doc)rm   r   s     r   rM   _dispatchable.__doc__  s1     """B/I $ 00	r   c                     Xl         SU l        g)zWSets the original documentation to the given value and resets the
cached documentation.N)r   r   )rm   rU   s     r   rM   r     s    
 r   c           	         U R                   Gc9  [        R                  " U R                  5      n[	        S UR
                  R                  5        5       5      (       d  UR                  / UR
                  R                  5       Q[        R                  " S[        R                  R                  SS9P[        R                  " S[        R                  R                  5      PS9nO]UR
                  R                  5       Gt p#UR                  / UQ[        R                  " S[        R                  R                  SS9PUPS9nXl         U R                   $ )zrReturn the signature of the original function, with the addition of
the `backend` and `backend_kwargs` parameters.Nc              3   n   #    U  H+  oR                   [        R                  R                  :H  v   M-     g 7fr-   )kindinspect	ParameterVAR_KEYWORD)r.   ps     r   r0   ._dispatchable.__signature__.<locals>.<genexpr>  s'      AXA'++777AXs   35r/   )defaultbackend_kwargs
parameters)r   r   	signaturer   anyr   valuesreplacer   KEYWORD_ONLYr   )rm   sigr   var_keywords       r   __signature___dispatchable.__signature__  s>   
 99##DNN3C  ADAVAVAX   kk ..0 ))%w'8'8'E'Et 
  )),g.?.?.K.K  " 
 ,/>>+@+@+B(kk # ))%w'8'8'E'Et 
 $  "  Iyyr   )r/   c               >   [         (       d*  Ub  US:w  a  [        SU S35      eU R                  " U0 UD6$ UnUb  U[        ;  a  [        SU S35      e0 nU R                  R                  5        H  u  pgU[        U5      :  a%  Xc;   a  [        U R                   SU< 35      eX'   nO5Xc;   a  X6   nO+X`R                  ;  a  [        U R                   SU 35      eMn  Uc-  X`R                  ;  a  [        U R                   SU< S35      eM  XU'   M     U R                  (       a  [        U5      nU R                  UR                  5       -   H0  n[        XV   5      n	XU'   Xc;   a  XU'   M  XU R                  U   '   M2     UR                  5        VV
s1 s H#  u  pjX`R                  ;  d  M  [        U
S	S5      iM%     nnn
U R                  UR                  5       -   H  nUR                  S
 XV    5       5        M     O+UR                  5        V
s1 s H  n
[        U
S	S5      iM     nn
[         R"                  R$                  R'                  U R                  U R(                  (       a$  [         R"                  R$                  R*                  O#[         R"                  R$                  R,                  5      nU R.                  (       a7  U(       a0  Uc-  U R1                  US   UU[         R"                  R2                  S9$ UR5                  S5        UGb  SU S3nSU SU R                   SU 3nU(       a  X1:X  ac  U R7                  XBU5      (       a  U R9                  XBX>S9$ U R;                  U5      (       a  SnOSn[=        SU R                   SU SU SU 35      eU R?                  XK5      (       a  U R7                  XBU5      (       aw  U RA                  X#5      (       a$  [B        RE                  SU R                  U5        / nOSnU RG                  UUUUUUS9nU(       a  U H  u  nnURI                  US5        M     U$ U R;                  U5      (       a  SnOSn[=        SU R                   SU SU SU 35      e[        U5      S:X  a  SnS[K        [M        U5      5       S3nOSn[        SU R                   SU SU SU SU S U 35      eU RA                  X#5      (       Ga  S!nS"n[        U5      S:X  a  Uu  nS#U S$U R                   S%U 3n U R7                  XBU5      (       a  U R9                  UUUUS&-  S9$  [         R"                  R2                  (       aH  [O        S' UR                  5        5       5      (       a#  [B        RE                  S(UU R                  U5        OU R;                  U5      (       a  S&nOSn[=        UU-  5      e[         R"                  R2                  (       aH  [O        S+ UR                  5        5       5      (       a#  [B        RE                  S,U R                  UU5        O[Q        SU R                   S-U S.U 35      eU R                  " U0 UD6$ [         R"                  R2                  (       d  U(       d  S/nO/ n[S        5       n/ n/ nU HF  nUU;   a  M  URU                  U5        UU;   a  URW                  U5        M5  URW                  U5        MH     / n/ nU HF  nUU;   a  M  URU                  U5        UU;   a  URW                  U5        M5  URW                  U5        MH     UU-
  n[        U5      S:  a#  [B        RE                  S/U R                  U5        S0n[        [X        RZ                  " UUUUU5      5      n [        U 5      S:  a+  [B        RE                  S1U R                  U=(       d    S2U 5        / n![]        U 5       GH  u  n"nU"(       a  [B        RE                  S3U5         U(       a  X1:X  a-  U R7                  XBU5      (       a  U R9                  XBU5      s  $ M_  U R?                  XK5      (       a  U R7                  XBU5      (       a  U R_                  XBU5      (       aV  U RG                  XKX#5      nU R(                  (       a/  U(       a(  XK;  a#  [B        RE                  S4U R                  UUU5        Us  $ U!RW                  U5        GM  GM  GM     U! Hn  n[B        RE                  S6U5         U RG                  XKX#5      nU R(                  (       a/  U(       a(  XK;  a#  [B        RE                  S4U R                  UUU5        Us  $    [        UU-
  =n#5      S:  a"  [        S7U S8U R                   S9U  S:U# S;3	5      e[=        SU R                   S<U  S=35      es  sn
nf s  sn
f ! [<         aT  n[O        S) UR                  5        5       5      (       a)  [B        RE                  S*UU R                  UU5         SnAGNe SnAff = f! [<         a.  n[B        RE                  S5UU R                  U5         SnAGMz  SnAff = f! [<         a.  n[B        RE                  S5UU R                  U5         SnAGM  SnAff = f)>zReturns the result of the original function, or the backend function if
the backend is specified and that backend implements `func`.Nr?   r]   r^   z() got multiple values for z$() missing required graph argument: z() required graph argument z is None; must be a graph__networkx_backend__c              3   <   #    U  H  n[        US S5      v   M     g7fr   N)getattrr.   gs     r   r0   )_dispatchable.__call__.<locals>.<genexpr>  s$      +3 A5t<<3   r   r=   zZNo other backends will be attempted, because the backend was specified with the `backend='z'` keyword argument.z3' backend raised NotImplementedError when calling `z'. extra_messagez for the given argumentsr9   `z' is not implemented by 'z	' backendz. z`%s' will mutate an input graph. This prevents automatic conversion to, and use of, backends listed in `nx.config.backend_priority`. Using backend specified by the `backend='%s'` keyword argument. This may change behavior by not mutating inputs.r   	mutationsr   sz)' is unable to convert graph from backend z to 'z2' backend, which was specified with the `backend='z'` keyword argument. zconversions between backends (if configured) will not be attempted, because this may change behavior. You may specify a backend to use by passing e.g. `backend='networkx'` keyword, but this may also change behavior by not mutating inputs.)zThis call will mutate inputs, so fall back to 'networkx' backend (without converting) since all input graphs are instances of nx.Graph and are hopefully compatible.z	Backend 'z' does not implement `z2'%s. This call will mutate an input, so automatic z with these argumentsc              3   V   #    U  H  n[        U[        R                  5      v   M!     g 7fr-   rG   rl   Graphr   s     r   r0   r     s'      8 ":A #1bhh//!9   ')zBackend '%s' can't run `%s'. %sc              3   V   #    U  H  n[        U[        R                  5      v   M!     g 7fr-   r   r   s     r   r0   r     s      U<Tq:a22<Tr   z-Backend '%s' raised when calling `%s': %s. %sc              3   V   #    U  H  n[        U[        R                  5      v   M!     g 7fr-   r   r   s     r   r0   r     s'      2 2A 1bhh''1r   z:`%s' was called with inputs from multiple backends: %s. %szN' will mutate an input, but it was called with inputs from multiple backends: z. Automatic zCall to `%s' has inputs from multiple backends, %s, that have no priority set in `nx.config.backend_priority`, so automatic conversions to these backends will not be attempted.r   zaCall to `%s' has inputs from %s backends, and will try to use backends in the following order: %snozTrying next backend: '%s'zCall to `%s' is returning a graph from a different backend! It has inputs from %s backends, but ran with '%s' backend and is returning graph from '%s' backend)Backend '%s' raised when calling `%s': %sz2Trying backend: '%s' (ignoring `should_run=False`)zUnable to convert inputs from z backends and run `z6'. NetworkX is configured to automatically convert to zB backends. To remedy this, you may enable automatic conversion to z backends by adding them to `nx.config.backend_priority`, or you may specify a backend to use with the `backend=` keyword argument.z' is not implemented by z backends. To remedy this, you may enable automatic conversion to more backends (including 'networkx') by adding them to `nx.config.backend_priority`, or you may specify a backend to use with the `backend=` keyword argument.)0r;   rb   r   rD   rz   r   r   r   r   r   r   listrF   r   rE   r   rl   rS   r:   rK   r   r4   r3   _is_testing_convert_and_call_for_testsr=   discard_can_backend_run_call_with_backend_does_backend_haveNotImplementedError_can_convert_will_call_mutate_input_loggerdebug_convert_and_callr   nextiterallRuntimeErrorr   r   append	itertoolschain	enumerate_should_backend_run)$rm   r/   rY   rZ   rd   graphs_resolvedgnameposgraphlist_of_graphsr   graph_backend_namesr:   blurbr   extrar   r   cacherT   maybe_sfallback_blurbmsg_templater!   backend_fallbackseengroup1group2r   group4group5group3	try_orderbackends_to_try_againis_not_firstunspecified_backendss$                                       r   __call___dispatchable.__call__  s7    x"w*'<!AgY.H"IJJ>>42622
 #L(H,/IJKK++++-JESY?#tyyk1LUI$VWW	222yyk!EeWM  } 4 44#99+%@	Ibc  5
 */&' .: :D))O,@,@,BB!%o&<!=)7&?$25M/=U+, C !0 5 5 7# 7HE 0 00 9148 7   #
 ))O,@,@,BB#** +,3+  C )//1#1A 1481   #
 995599II"" II&&11++11	
  0\5I 33 #!yy77	 4   	##D)#
00<~=QS 
 L> "II;c%*  '*=*O((VDD22$F 3   **<886EE)		{";L>gRw(    CC((VDD33DAA/
 !II( %'	$(	//$+&3"+ 0 B !*3JE3 "IIc40	 +4
 I**<886EE)		{";L>gRw(  &'1,()$t4G/H*I)J!&L#DII;GyPQ&'u\N ;00<~=R'  ''55: N
 &'1,!4~-CDII; ODDI7L 
&H,,\HH#66( "*69P*P	  7    I& yy//C 8 "1!7!7!9	8 5 5  =( II*	  22<@@$;E$&E1,2FGG))c 2 )//1	2 / / PII'"	 #		{ #//B.C<PUwX  >>42622 99##+> !+|!x u$Dt|HHTN**d#d# % $Dt|HHTN**d#d# % %t+v;?" MM8 		 FPQ	y>A MM6		#+t !#*3I*>&L,9<H)*.A^.S,,\HH#66|6RR I&&  ++LGG//FKK!33(t !// 3 , G $MM!X !%		 3 , ,  "	)00>9 H +?` 2LMMDl++ t ''+$?MMP 		+$$ 	- 2D ':T'AA#BQF01D0E F		{ #[ !!!5 6 7UU  "		{29+ >/ /
 	
O##T + 
UO<R<R<TUUUK( II*  
z ' ? II	 B ' ? II	 so   f=/f=g+g 5h)Bh)h)Ai$
h&Ah! h!!h&)
i!3"ii!$
j."jjc                    ^^ U R                   =n=(       a/    USL =(       d$    [        UU4S jUR                  5        5       5      $ )NTc              3      >#    U  Hr  u  pUR                  S 5      (       a.  [        T5      U:  a  TU   OTR                  USS S5      (       + O&[        T5      U:  a  TU   OTR                  U5      SLv   Mt     g7f)znot    NT)rN   r   rK   )r.   arg_namearg_posrY   rZ   s      r   r0   8_dispatchable._will_call_mutate_input.<locals>.<genexpr>  s       *?%H &&v..	 4y7* M  HQRL$7	 (+4y7':d7m

8@T *?s   A:A=)r   r   r   )rm   rY   rZ   r   s    `` r   r   %_dispatchable._will_call_mutate_input  sH    !%!3!33 
T!   *7)<)<)> 	
r   c                     US:H  =(       d    UR                  SU15      nU(       d  [        R                  SUU5        U$ )Nr?   z2Unable to convert from %s backends to '%s' backend)issubsetr   r   )rm   rd   r   r   s       r   r   _dispatchable._can_convert  sJ     Z' 
+>+G+G&,
 MMD#
 	r   c                 P    US:X  a  g[        U5      n[        X R                  5      $ )z/Does the specified backend have this algorithm?r?   T)re   rc   r   )rm   rd   r/   s      r   r    _dispatchable._does_backend_have  s&    :%-w		**r   c           
         US:X  a  g[        U5      n[        X@R                  5      (       d!  [        R	                  SXR                  5        gUR                  U R                  X#5      n[        U[        5      (       d  U(       dJ  [        U[        5      (       a  SU 3OSn[        R	                  SUU R                  [        XU5      U5        gg)zBCan the specified backend run this algorithm with these arguments?r?   Tz$Backend '%s' does not implement `%s'F, because: r9   z0Backend '%s' can't run `%s` with arguments: %s%s)	re   rc   r   r   r   r_   rG   r   _LazyArgsRepr)rm   rd   rY   rZ   r/   r_   reasons          r   r   _dispatchable._can_backend_run  s    :%- w		**MM6ii //$))T:gs##70:7C0H0H{7),bFMMB		d&1 r   c           
      ,   US:X  a  g[        U5      nUR                  U R                  X#5      n[        U[        5      (       d  U(       dJ  [        U[        5      (       a  SU 3OSn[
        R                  SUU R                  [        XU5      U5        gg)zzShould the specified backend run this algorithm with these arguments?

Note that this does not check ``backend.can_run``.
r?   Tr  r9   z4Backend '%s' shouldn't run `%s` with arguments: %s%sF)re   r`   r   rG   r   r   r   r  )rm   rd   rY   rZ   r/   r`   r  s          r   r   !_dispatchable._should_backend_run  s     :%-''		4@
j#&&j3=j#3N3N{:,/TVFMMF		d&1 r   c                   U R                   R                  " U0 UD6nUR                  5         U R                  (       d  UR                  nUS	 UR
                  U4$ US:X  a  S=n=pO<U R                  nU R                  n	U R                  n
U R                  nU R                  nUSL a  OUSL a  SnO[        U[        5      (       a  UR                  U   SL d  [        UR                  U   5      (       a  SnSnOMUR                  U   SL a9  [        W[        5      (       a  X:X  d  [        U[        5      (       a
  X;   a  SnSnOSnWc  GOK[        U[        5      (       a  US   S:X  a$  UR                  USS	     Vs0 s H  oS_M     nnGO	[        UR                  U   5      (       a  SnSnOUR                  U   b  UR                  U   S0nOU R                   S
:X  aH  [#        UR                  S   S5      (       a*  UR                  S   R$                   Vs0 s H  oS_M     nnOmSnOjUR'                  5        VVs0 s HM  u  pUR                  U   =nc  M  U[        U[        5      (       a  UR                  R)                  US5      OU_MO     nnnU	SL a  OU	SL a  SnO[        U	[        5      (       a  UR                  U	   SL d  [        UR                  U	   5      (       a  Sn	SnOMUR                  U	   SL a9  [        W[        5      (       a  X:X  d  [        U[        5      (       a
  X;   a  Sn	SnOSn	Wc  O[        U[        5      (       at  US   S:X  a$  UR                  USS	     Vs0 s H  nUS_M     nnO[        UR                  U   5      (       a  Sn	SnOUR                  U   b  UR                  U   S0nOlSnOiUR'                  5        VVs0 s HL  u  pUR                  U   =nc  M  U[        U[        5      (       a  UR                  R)                  U5      OU_MN     nnnU R                   GH^  nUU R*                  ;   aX  UR                  U    Vs/ s H.  n[-        USS5      U:w  a  U R/                  UUUUUU	U
UUUS9
OUPM0     snUR                  U'   Ml  UR                  U   nUc.  UU R0                  ;   a  M  [3        SU SU R                    S35      e[        U[        5      (       a  SnUR)                  UU5      nOUnUn[        U	[        5      (       a  SnU	R)                  UU5      nOU	nUn[        U
[4        5      (       a  UU
;   nOU
n[-        USS5      U:w  d  GM9  U R/                  UUUUUUUUUUS9
UR                  U'   GMa     UR                  nUS	 UR
                  U4$ s  snf s  snf s  snnf s  snf s  snnf s  snf )z^Convert graph arguments to the specified backend.

Returns
-------
args tuple and kwargs dict
r/   r?   TFNr   [r   r   to_numpy_arraydtypenamesr   )r{   r|   r}   r~   r   
graph_name	use_cacher   z!Missing required graph argument `z` in z	 function)r   bindapply_defaultsrz   rZ   rY   r}   r~   r   r{   r|   rG   r   	argumentscallabler   r   rc   r  r   rK   r   r   _convert_graphr   r   r   )rm   rd   rY   rZ   r  r   boundbound_kwargsr}   r~   r   r{   r|   	edge_attrrT   rU   	node_attrr   r   r   preserve_edgesedgespreserve_nodesnodespreserve_graphs                            r   _convert_arguments _dispatchable._convert_arguments  sc    ""''88{{ <<LY'::|++:%OSSS"58L"&":":"&":":#'#<#< JJ %' D(J+S1123t;x 34@ @
 '+#!
!45>:s++5j$//'5
 ',#!
 ',# 
C((!}# 38//*QrBR2S2SYqL2S  
 %//*566&*#!
,8#ooj91=
..7('4 4
 38//'2J2P2P2PYqL2P  

 "
 !+ 0 0 2 2HC!&!55I X	*S#:N:N5??..sA6TWW 2   %' D(J+S1123t;x 34@ @
 '+#!
!45>:s++5j$//'5
 ',#!
 ',# 
C((!}# 6;__ZPQRTEU5V5V	ItO5V  
 %//*566&*#!
,8#ooj94@
 "
 !+ 0 0 2 2HC!&!55I U	z#s7K7K5??..s3QTT 2   [[E(((  #__U3* 4 q"8*EU ''$#-#-,?,?-A#("+"+ (   4*&$ .= 4 44 #;E7%		{R[\  1488%*N/33E:FE%8N&E1488%*N/33E:FE%8N&E2C88%*.B%BN%9N5"8*EU-1-@-@$#(#(,:,:-;#("+"+ .A .EOOE*Y !p ||#zz<''iV *s0   >V=W W8W1WW77W"5Wc                X   U	(       a  [        USS 5      =nb  UR                  S0 5      R                  U0 5      n[        UUUUUS9n[        XU
S9u  pUbv  S[        R
                  R                  ;  a(  [        R                  " SU< SU R                   S35        [        R                  S	[        US
S 5      UU R                  U5        U$ US:X  a\  [        US
5      (       d$  [        R                  SU R                  UU5        U$ [        UR                  5      nUR                  U5      nO4[        U5      nUR!                  UUUUUU=(       d    U	U R                  US9nU	(       aA  Wb>  U
c;  [#        WWU5        [        R                  S[        US
S 5      UU R                  U5        U$ )N__networkx_cache__r;   r{   r|   r}   r~   r   )r   r   zNote: conversions to backend graphs are saved to cache (`G.__networkx_cache__` on the original graph) by default.

This warning means the cached graph is being used for the z backend in the call to a  .

For the cache to be consistent (i.e., correct), the input graph must not have been manually mutated since the cached graph was created. Examples of manually mutating the graph data structures resulting in an inconsistent cache include:

    >>> G[u][v][key] = val

and

    >>> for u, v, d in G.edges(data=True):
    ...     d[key] = val

Using methods such as `G.add_edge(u, v, weight=val)` will correctly clear the cache to keep it consistent. You may also use `G.__networkx_cache__.clear()` to manually clear the cache, or set `G.__networkx_cache__` to None to disable caching for G. Enable or disable caching globally via `nx.config.cache_converted_graphs` config.

To disable this warning:

    >>> nx.config.warnings_to_ignore.add("cache")
zZUsing cached converted graph (from '%s' to '%s' backend) in call to `%s' for '%s' argumentr   r?   zUnable to convert input to 'networkx' backend in call to `%s' for '%s argument, because it is not from a backend (i.e., it does not have `G.__networkx_backend__` attribute). Using the original object: %s)r{   r|   r}   r~   r   r   r  zUCaching converted graph (from '%s' to '%s' backend) in call to `%s' for '%s' argument)r   
setdefault_get_cache_key_get_from_cacherl   rS   r>   r   r   r   r   r   rc   re   r   convert_to_nxconvert_from_nx_set_to_cache)rm   rd   r   r{   r|   r}   r~   r   r  r  r   nx_cacher   rT   
compat_keyr   r/   s                    r   r"  _dispatchable._convert_graph  s    $U,@$GGT''
B7BB<QSTE %%$7$7%9C -U9MNJ~"))">">>MM# $0"2 3##'99+ .N	N. 8E#94@ II 	:% 5"899! II #E$>$>?G&&u-B#L1G((%%$7$7 &:%FYYY% ) B -)2C%b)MM45t<		 	r   r   c          
      `   US:X  a  U R                   " U0 UD6$ [        U5      n[        R                  SUU R                  [        XU5      5         [        XPR                  5      " U0 UD6$ ! [         a7  nUb.  [        R                  SUU R                  U5        [        U5      Uee SnAff = f)zICall this dispatchable function with a backend without converting inputs.r?   6Using backend '%s' for call to `%s' with arguments: %sNr   )r   re   r   r   r   r  r   r   )rm   rd   rY   rZ   r   r/   r!   s          r   r    _dispatchable._call_with_backend?  s    :%>>42622-DII$f-		
	7II.???" 		(? II	 *-8cA		s   A, ,
B-62B((B-r   c          
      *   US:X  a  U R                   nO [        U5      n[        XR                  5      nX!1-
  n	[        R                  S[        U	5      S:  a  U	OS[        [        U	5      5       S3[        U	5      S:  a  SOSUU R                  5         U R                  UUU[        R                  R                  US9u  pUS:w  a,  [        R                  SUU R                  [        X
U5      5         U" U
0 UD6$ ! [         aG  n[        R
                  " SUc  SOS
-   UUU R                  /Uc  SOU4Q76   Ub  [        U5      Uee S	nAff = f! [         a7  nUb.  [        R                  SUU R                  U5        [        U5      Uee S	nAff = f)a  Call this dispatchable function with a backend after converting inputs.

Parameters
----------
backend_name : str
input_backend_names : set[str]
args : arguments tuple
kwargs : keywords dict
extra_message : str, optional
    Additional message to log if NotImplementedError is raised by backend.
mutations : list, optional
    Used to clear objects gotten from cache if inputs will be mutated.
r?   zJConverting input graphs from %s backend%s to '%s' backend for call to `%s'r   r]   r   r9   r  r   zAFailed to convert graphs from %s to '%s' backend for call to `%s'Nz: %sr   r;  r   )r   re   r   r   r   r   r   r   r   r,  rl   rS   r<   r   r  )rm   rd   input_backend_namesrY   rZ   r   r   r   r/   other_backend_namesconverted_argsconverted_kwargsr!   s                r   r   _dispatchable._convert_and_callW  s   . :%>>D#L1G7II.D1NBX&'!+  T$2345Q7*+a/CRII	
	/3/F/F))::# 0G 0,N* :%MMH		d4DE		<+;<<- # 	 MMS&.2F<#		 &-"C6 ()-8cA	. # 		(? II	 *-8cA		s1   -C= 5E =
EAE		E
F2FFr   c                f  ^ ^^^^^ ^!^"^#^$^%^&^'^(^)^*^+^, [        U5      nT R                  XU5      (       d  U(       d  T R                  (       dE  U(       a,  [        R	                  SUT R
                  [        T X#5      5        T R                  " U0 UD6$ SSKnST R
                   SU 3n[        UT R
                  5      (       a  US-  nUR                  U5        SSKJmJm Jm!  SSKJm'Jm(  SS	KJmJmJm$Jm%  SS
KJm+  SSKJm"  SSKm)SSKJmJm#  SSKJm*  U(       d  U=pO[A        UUUU U"U#U$U%U'U(U+4S jU 5       6 u  pU(       d  U=pOC[A        UUUU U"U#U$U%U'U(U+U,4S jURC                  5        5       6 u  p[E        U
5      n
[E        U5      n T RG                  XU
SSS9u  p[        R	                  SUT R
                  [        T X5      5        [I        UT R
                  5      " U0 UD6nT RR                  [U        W[V        RX                  5      =(       dC    [        US5      =(       d0    [U        U[Z        [\        -  5      =(       a    [_        S U 5       5      :w  av  T R
                  S;   a  [_        S U 5       5      (       dO  T R
                  S;   a  [_        S U 5       5      (       d(  T R
                  S;  a  [a        ST R
                   35      eS5UU U!U&U)U U*4S jjm&U&U 4S jnT R
                  S;   a  O+[U        UT 5      (       a	  U" U5      nO T&" U5        T&" U5        T R
                  S#;   Ga\  T Rb                  Rd                  " W0 WD6nURg                  5         T Rb                  Rd                  " U	0 UD6nURg                  5         T R
                  S$;   a|  URi                  URj                  S%   5      nURj                  S%   nURl                  Ul6        URo                  5       (       a  URp                  Ul8        [V        Rr                  " U5        GOgT R
                  S&:X  a  URi                  URj                  S'   5      nURj                  S'   nUbw  Ubt  URt                  RC                  5        H  u  nnUS(   URt                  U   S('   M     URv                  Ry                  URv                  5        [V        Rr                  " U5        GOT R
                  S):X  a  URj                  S*   b  URi                  URj                  S%   5      nURj                  S%   nURj                  S*   nURz                  RC                  5        H  u  nnUU   URz                  U   U'   M     [V        Rr                  " U5        GOT R
                  S+;   a~  URj                  S,   (       dj  URi                  URj                  S%   5      nURj                  S%   nUR|                  Ry                  UR|                  5        [V        Rr                  " U5        GOsT R
                  S-:X  a  URj                  S,   (       d~  URi                  URj                  S%   5      nURj                  S%   nURt                  RC                  5        H  u  nnUS.   URt                  U   S.'   M     [V        Rr                  " U5        GOT R
                  S/:X  a  URj                  S,   (       a  T R
                  S0;   Ga  URi                  URj                  S%   5      nURj                  S%   nUUL a  U$ UR~                  R                  5         UR~                  Ry                  UR~                  5        URl                  R                  5         URl                  Ry                  URl                  5        [        US15      (       aP  [        US15      (       a?  URp                  R                  5         URp                  Ry                  URp                  5        [        US25      (       aP  [        US25      (       a?  UR                  R                  5         UR                  Ry                  UR                  5        [V        Rr                  " U5        T R
                  S/:X  a  U$ URi                  U5      $ URi                  U5      n[U        U[V        RX                  5      (       Ga	  T R
                  S3;  a  T R                  " U	0 UD6n[V        R                  R                  UU5      (       d  UR                  5       UR                  5       :X  d   eUR                  5       UR                  5       :X  d   eURv                  URv                  :X  d   eURz                  URz                  :X  d   eUR                  UR                  :X  d   e[O        U5      [O        U5      L d   e[        S45      eU$ U$ ! [J         a  nU(       a8  [        R	                  SUT R
                  5        T R                  " U	0 UD6s SnA$ SSKnUR                  URL                  (       a  URL                  S   O#T R
                   S[O        U5      RP                   35         SnAGNSnAff = f! [`         a-  n[a        T R
                   S U S![O        U5       S"35      UeSnAff = f)6zECall this dispatchable function with a backend; for use with testing.zZFalling back to use 'networkx' instead of '%s' backend for call to `%s' with arguments: %sr   Nr]   z' not implemented by z with the given arguments)IterableIteratorMapping)copydeepcopy)BufferedReaderBytesIOStringIOTextIOWrapper)tee)Random)	GeneratorRandomState)sparrayc              3     >#    U  Ht  n[        UT5      (       a
  UT" U5      4OS[        UTT-  T-  T-  5      (       a
  UT
" U5      4O/[        UT5      (       a  [        UTT	-  5      (       d  T" U5      OX4v   Mv     g 7fr-   rG   )r.   argrJ  rK  rP  rF  rO  rQ  rL  rM  rH  rI  rN  s     r   r0   <_dispatchable._convert_and_call_for_tests.<locals>.<genexpr>  s      
  $ "#{33 (3-( "#w'9F'BY'NOO tCy) "#x00&sN],JKK S $  $s   A<A?c              3   4  >#    U  H  u  p[        UT5      (       a  X4UT" U5      44Og[        UTT	-  T-  T-  5      (       a  X4UT" U5      44O@[        UT5      (       a*  [        UTT
-  5      (       d  UT" U5      =mS    4UTS   44OX4X44v   M     g7f)r   r   NrT  )r.   r   r   rJ  rK  rP  rF  rO  rQ  rL  rM  rH  rI  rN  teeds      r   r0   rV    s      
 !/ "![11 Va!-. "!Wx%7&%@9%LMM &1d1g,/ "!X..&q.=*HII s1v~tq12QQLA &1&)* !/s   BBFr>  r;  z`Graph conversion failed; falling back to use 'networkx' instead of '%s' backend for call to `%s'z raised r   c              3   |   #    U  H2  n[        U[        R                  5      =(       d    [        US 5      v   M4     g7fr   )rG   rl   r   rc   r.   r(   s     r   r0   rV    s2      # q"((+Qwq:P/QQ#s   :<>   check_planaritycheck_planarity_recursivec              3   (   #    U  H  oS L v   M
     g 7fr-   r   rZ  s     r   r0   rV    s     26aT	6r2   >   held_karp_ascentc              3   B   #    U  H  n[        U[        5      v   M     g 7fr-   )rG   r   rZ  s     r   r0   rV    s     <V
1d++Vs   >   
all_triadsnonisomorphic_treesgeneral_k_edge_subgraphsz!`returns_graph` is incorrect for c           
      `  > [        U TR                  5      (       a*  [        TR                   SU  S[	        U 5       SU S35      e[        U TR
                  T	-  5      (       a  g [        U [        R                  5      (       a)  T" U R                  US-   S9  T" U R                  US-   S9  g [        U T5      (       a  [        e[        U T5      (       a'  [        U [        5      (       d  U  H  nT" X!S-   S9  M     [        U T5      (       a!  U R                  5        H  nT" X!S-   S9  M     g g )N returned a numpy scalar  (z, depth=)r   )depth)rG   numberr   r   rL   ndarrayrl   r   _node_adjr   r   r   )
rU   rg  r(   rE  rF  rG  check_resultnprm   rR  s
      r   rl  ?_dispatchable._convert_and_call_for_tests.<locals>.check_result*  s   #ryy))"yyk!:3%r$s)HUZT[[\]  #rzzG344#rxx((SYYeai8SXXUQY7#x(())#x((C1E1EA !)4 #w''A !)4 & (r   c              3      >#    U  H  n T" U5        Uv   M     g ! [          a-  n[        TR                   SU S[        U5       S35      UeS nAff = f7f)Nrd  re  rf  )r   r   rL   )itrU   r!   rl  rm   s      r   check_iteratorA_dispatchable._convert_and_call_for_tests.<locals>.check_iterator>  se      %
 	  $ &99+%>se2d3i[PQRs$   A	A
A(AAA>   from_edgelistrd  re  rf  >   
barycenteredmonds_karprelabel_nodescontracted_edgecontracted_nodesstochastic_graphmaximum_branchingminimal_branchingrecursive_simple_cyclesconnected_double_edge_swapminimum_spanning_arborescence incremental_closeness_centrality>   r{  r|  r}  r~  rx   ru  residualflowrt  attr>   rw  rx  rH  ry  weightrv  >   r  _pred_succ>   read_gml	read_gexf
from_pydot
read_pajekread_graph6preflow_pushread_adjlistread_graphmlread_sparse6read_edgelistpydot_read_dotquotient_graphagraph_read_dotboykov_kolmogorovspectral_graph_forgeread_multiline_adjlistbipartite_read_edgelistshortest_augmenting_pathzGraphs are not equal)r   )Hre   r   rz   r   r   r   r  r   pytestrc   xfailcollections.abcrE  rF  rG  rH  rI  iorJ  rK  rL  rM  r   rN  randomrO  numpynumpy.randomrP  rQ  scipy.sparserR  zipr   r   r,  r   r   rY   rL   rr   r   rG   rl   r   tupler   r   r   r   r  r  r4  r   rk  is_directedr  _clear_cacher(  r   rE   r*  r   rj  clearr  utilsgraphs_equalnumber_of_nodesnumber_of_edgesadjAssertionError)-rm   rd   rY   rZ   r=   r/   r  msgargs1args2kwargs1kwargs2rA  rB  resultr!   rq  r#  bound2G1G2R1R2r   r   r  converted_resultrx   rJ  rK  rP  rE  rF  rG  rO  rQ  rL  rM  rl  rH  rI  rm  rR  rN  rX  s-   `                           @@@@@@@@@@@@@@@@@r   r   )_dispatchable._convert_and_call_for_tests  s     -$$\@@T[[!MM>$		%dD9 ~~t6v66dii[ 5l^DCw		**22LL??'GG!!7(
   EE
 
  $
LE  &&Gg"
 
 !'
 G 7mG7mG	/3/F/FW 0G 0,N MMH		dNE	 Wdii0.UDTUF& 6288, 6#9:fedl3  # 	 		MM26222 		11<V<<<		 !B499+NOO	5 	5(	 99))))#F+FV$
  99 
 
 &&++^P?OPE  "'',,e?w?F!!#yy   **5??3+?@%%c*''>>##!xxBH#n,**5??:+FG%%j1>bn " 01./iF+ !1HHOOBHH-OOB'l*uv/F/R**5??3+?@%%c*v.HHNN,DAq()$BHHQK% -#		DD/ **5??3+?@%%c*""2;;/#009P**5??3+?@%%c*HHNN,DAq,-hKBHHQK) -#		_,/99 DD**5??3+?@%%c*8I )rww'2w''GB,@,@HHNN$HHOOBHH-2w''GB,@,@HHNN$HHOOBHH-#99/I((00"008&11dii H
 7
4 11A88((,<==((*.>.N.N.PPPP((*.>.N.N.PPPPww"2"8"8888ww"2"8"8888uu 0 4 4444Aw$'7"8888$%;<<Ho # 	7 II	 ~~u888LL"xx		{(49CUCUBV-W 	n   "yyk!:6("T&\NRSTs>   Ag i9 
i69i1i6Ai11i69
j0(j++j0c                    U R                   (       d  U R                  $ SS/n[        U R                   5       GH  n[        U   nSU;   a  UR	                  U SUS    35        OUR	                  U5        SU;  d  U R
                  US   ;  a  UR	                  S5        Mj  US   U R
                     nUR                  S5      =(       d    UR                  S5      =n(       a*  UR                  S	 UR                  S
5       5       5        SnOSnUR                  S5      =(       d    UR                  S5      =n(       a  U(       a  UR	                  S5        UR	                  S5        [        U5       HG  nUR	                  SU 35        Xx   =n	(       a  UR	                  SU	 35        UR	                  S5        MI     OUR	                  S5        UR                  S5      =n
(       d  GM  UR	                  SU
 S35        UR	                  S5        GM     UR                  5         SR                  U5      nU R                  (       d  SU R
                   SU 3$ U R                  R                  5        SU 3$ )zGenerate the backends section at the end for functions having an alternate
backend implementation(s) using the `backend_info` entry-point.Backendsz--------short_summaryz : r   r9   additional_docsextra_docstringc              3   <   #    U  H  o(       a  S U 3OUv   M     g7f)z  Nr   )r.   lines     r   r0   *_dispatchable._make_doc.<locals>.<genexpr>  s!      >Sd4bKT1>Sr   
TFextra_parametersadditional_parametersz  Additional parameters:z    z      urlz
[`Source <z>`_]z
    zThe original docstring for z was empty.

    z

    )r;   r   rP   rD   r   r   rK   extendr&   r   joinrstrip)rm   linesr/   rQ   	func_info	func_docsadd_gapr  paramdescfunc_urlto_adds               r   r   _dispatchable._make_doc  s?    }}>>!
 dmm,G(D$&yD,A+BCDW%$&$))4;L*LR [)$))4I /0TIMMBS4Ty   >Good>S   01 :==!89  LL$78#$45ELL4w0/66t6vdV_5LL$	 6 R $==//x//z(489R S -V 			u%~~0;NvhWW..'')*(6(;;r   c                 (    [         U R                  44$ )zxAllow this object to be serialized with pickle.

This uses the global registry `_registered_algorithms` to deserialize.
)_restore_dispatchabler   )rm   s    r   
__reduce___dispatchable.__reduce__	  s    
 %tyyl22r   )r   r   rs   rr   rt   r   r   r   r   r   r;   r{   rz   r   r   r   r|   r   r   r}   r   r~   r-   )rr   rs   rt   ru   r   rw   r   propertyrM   setterr   r  r   r   r   r   r   r,  r"  r   r   r   r   r  rv   r   r   r   r
   r
     s    K
, 
, &'O s !!" sj   ^^    " "H *. g
R
&+2.Q(fiV OS > Nb =Bi V	9<v3r   c                 (    [         U    R                  $ r-   )r   r   )r   s    r   r  r  	  s    !$'333r   c                 |    U b  [        U R                  5       5      OUUb  [        UR                  5       5      4$ U4$ )zLReturn key used by networkx caching given arguments for ``convert_from_nx``.)	frozensetr   r0  s        r   r2  r2  	  sR     ! 	*""$% ! 	*""$%	  ! r   )rd   r   c                l   Ub"  U R                  S0 5      R                  U0 5      n U (       d  gUu  pE[        R                  " USLa  US4OSUSLa  US4OS5       H1  nU R                  U5      =nc  M  Ub  UR                  X45        Xg4s  $    USLa  USLa  [	        U R                  5       5       H~  u  u  pn
USL d  USL a  O"USL d  USL d  UR                  U5      (       d  M5  USL d  U	SL a  O"USL d  U	SL d  UR                  U	5      (       d  Mb  Ub  UR                  XU	445        X4U
4s  $    g)a  Search the networkx cache for a graph that is compatible with ``key``.

Parameters
----------
cache : dict
    If ``backend_name`` is given, then this is treated as ``G.__networkx_cache__``,
    but if ``backend_name`` is None, then this is treated as the resolved inner
    cache such as ``G.__networkx_cache__["backends"][backend_name]``.
key : tuple
    Cache key from ``_get_cache_key``.
backend_name : str, optional
    Name of the backend to control how ``cache`` is interpreted.
mutations : list, optional
    Used internally to clear objects gotten from cache if inputs will be mutated.

Returns
-------
tuple or None
    The key of the compatible graph found in the cache.
graph or None
    A compatible graph or None.
r;   )NNT)TF)rK   r   productr   r   r   r  )r   rT   rd   r   edge_keynode_keyr8  r   ekeynkeyr   s              r   r3  r3  0	  sg   . 		*b)--lB? H''$D04g$D04g
 ))J''B4$   %!45>! t 4 $(#6LT%5 DDLT!TU](:K:KD:Q:Q5 DDLT!TU](:K:KD:Q:Q$   %!67<&& $7 r   )rd   c                   Ub"  U R                  S0 5      R                  U0 5      n 0 nUu  pVX U'   [        U 5       H  nXq:X  a  M
  Uu  pUSL d  USL a  O"USL d  USL d  UR                  U5      (       d  M;  U	SL d  USL a  O"U	SL d  USL d  U	R                  U5      (       d  Mh  U R                  US5      =nc  M  X$U'   M     U$ )a:  Set a backend graph to the cache, and remove unnecessary cached items.

Parameters
----------
cache : dict
    If ``backend_name`` is given, then this is treated as ``G.__networkx_cache__``,
    but if ``backend_name`` is None, then this is treated as the resolved inner
    cache such as ``G.__networkx_cache__["backends"][backend_name]``.
key : tuple
    Cache key from ``_get_cache_key``.
graph : graph
backend_name : str, optional
    Name of the backend to control how ``cache`` is interpreted.

Returns
-------
dict
    The items that were removed from the cache.
Nr;   FT)r1  r   r  r   )
r   rT   r   rd   removedr  r  cur_keyr  r  s
             r   r6  r6  r	  s    (   R0;;L"M
 GH#J;>
5=H,T\X.dmmH6M6M5=H,T\X.dmmH6M6MYYw--E:$G  Nr   c                   $    \ rS rSrSrS rS rSrg)r  i	  zOSimple wrapper to display arguments of dispatchable functions in logging calls.c                 6    Xl         X l        X0l        S U l        g r-   )r   rY   rZ   value)rm   r   rY   rZ   s       r   __init___LazyArgsRepr.__init__	  s    		
r   c                    U R                   cu  U R                  R                  R                  " U R                  0 U R
                  D6nSR                  S UR                  R                  5        5       5      nSU S3U l         U R                   $ )Nz, c              3   6   #    U  H  u  pU S U< 3v   M     g7f)=Nr   )r.   rT   rU   s      r   r0   )_LazyArgsRepr.__repr__.<locals>.<genexpr>	  s     W?V83Qsg.?Vs   (rf  )	r  r   r   bind_partialrY   rZ   r  r   r   )rm   r#  inners      r   __repr___LazyArgsRepr.__repr__	  sm    ::II++88$))St{{SEIIWu?T?T?VWWEUG1DJzzr   )rY   r   rZ   r  N)rr   rs   rt   ru   rM   r  r  rv   r   r   r   r  r  	  s    Yr   r  _NETWORKX_BUILDING_DOCS_c                 f    U c  [        [        40 UD6$ [        U 40 UD6nUR                  U l        U $ r-   )r   r
   _orig_dispatchablerM   )r   rZ   dispatched_funcs      r   r
   r
   	  s8    <=3F33,T<V<&..r   r   r   r-   )0rM   r   r   loggingrI   r   	functoolsr   importlib.metadatar   r?   rl   configsr   r   r   
decoratorsr	   __all__	getLoggerrr   r   r   r"   r;   rD   ra   r   r*   rW   r[   re   r
   r  r2  r3  r6  r  rJ   rK   r  r   r   r   r   r   r   r   )r   r   s   00r   <module>r     sb  Sj    	   +  > > 



H
%V +0 +b ,-   TBJ
R3 R3j44. 15 ?D 6: ,^ " ::>>,-- ' /66>>M/778D"&,,"&//"7"7"9H"9$!Q%ZA"9H #/ #M# .$ Is   E
/E
