Repository: networkx/networkx

Issue:
Dispatch test suite incompatible with pygraphviz
Just something I noticed today while attempting to run the test suite with `NETWORKX_TEST_BACKEND=nx-loopback` with the `pytest-xdist` extension. Doing so gives Segmentation faults, indicating that something about the nx-loopback mechanism isn't threadsafe (perhaps this is known?).

## To reproduce

Install xdist (`pip install pytest-xdist`) in the development environment and run the test suite with the nx-loopback backend with more than 1 worker, e.g.:

```bash
NETWORKX_TEST_BACKEND=nx-loopback pytest -n auto --doctest-modules --durations=10 --pyargs networkx
```

A selection from the pytest log below (can't include the whole thing due to gh issue character limits):

<details>
  <summary>Pytest log</summary>
<pre>
=========================================================== test session starts ===========================================================
platform linux -- Python 3.11.6, pytest-8.1.1, pluggy-1.4.0
Matplotlib: 3.9.0.dev0
Freetype: 2.6.1
rootdir: /home/ross/repos/networkx
configfile: pyproject.toml
plugins: anyio-4.2.0, mpl-0.16.1, cov-4.1.0, xdist-3.5.0
12 workers [6269 items]   
<clipped>
............................................x....x................................................................................. [ 64%]
........................................................................................................Fatal Python error: Segmentation fault

Thread 0x0000747ba7c006c0 (most recent call first):
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 474 in read
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 507 in from_io
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1049 in _thread_receiver
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 296 in run
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 361 in _perform_spawn

Current thread 0x0000747ba9422740 (most recent call first):
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pygraphviz/graphviz.py", line 226 in agnameof
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pygraphviz/agraph.py", line 228 in __repr__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_io/saferepr.py", line 73 in repr_instance
  File "/usr/lib/python3.11/reprlib.py", line 63 in repr1
  File "/usr/lib/python3.11/reprlib.py", line 53 in repr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_io/saferepr.py", line 61 in repr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_io/saferepr.py", line 111 in saferepr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 843 in repr_args
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 939 in repr_traceback_entry
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 994 in <listcomp>
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 993 in repr_traceback
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 1064 in repr_excinfo
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 699 in getrepr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/nodes.py", line 464 in _repr_failure_py
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/python.py", line 1814 in repr_failure
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/reports.py", line 364 in from_item_and_call
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 367 in pytest_runtest_makereport
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 242 in call_and_report
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 134 in runtestprotocol
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 115 in pytest_runtest_protocol
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/xdist/remote.py", line 174 in run_one_test
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/xdist/remote.py", line 157 in pytest_runtestloop
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/main.py", line 339 in _main
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/main.py", line 285 in wrap_session
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/main.py", line 332 in pytest_cmdline_main
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/xdist/remote.py", line 355 in <module>
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1157 in executetask
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 296 in run
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 361 in _perform_spawn
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 343 in integrate_as_primary_thread
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1142 in serve
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1640 in serve
  File "<string>", line 8 in <module>
  File "<string>", line 1 in <module>

Extension modules: markupsafe._speedups, numpy.core._multiarray_umath, numpy.core._multiarray_tests, numpy.linalg._umath_linalg, numpy.fft._pocketfft_internal, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, scipy._lib._ccallback_c, PIL._imaging, matplotlib._path, kiwisolver._cext, pandas._libs.tslibs.ccalendar, pandas._libs.tslibs.np_datetime, pandas._libs.tslibs.dtypes, pandas._libs.tslibs.base, pandas._libs.tslibs.nattype, pandas._libs.tslibs.timezones, pandas._libs.tslibs.fields, pandas._libs.tslibs.timedeltas, pandas._libs.tslibs.tzconversion, pandas._libs.tslibs.timestamps, pandas._libs.properties, pandas._libs.tslibs.offsets, pandas._libs.tslibs.strptime, pandas._libs.tslibs.parsing, pandas._libs.tslibs.conversion, pandas._libs.tslibs.period, pandas._libs.tslibs.vectorized, pandas._libs.ops_dispatch, pandas._libs.missing, pandas._libs.hashtable, pandas._libs.algos, pandas._libs.interval, pandas._libs.lib, pandas._libs.ops, pandas._libs.hashing, pandas._libs.arrays, pandas._libs.tslib, pandas._libs.sparse, pandas._libs.internals, pandas._libs.indexing, pandas._libs.index, pandas._libs.writers, pandas._libs.join, pandas._libs.window.aggregations, pandas._libs.window.indexers, pandas._libs.reshape, pandas._libs.groupby, pandas._libs.json, pandas._libs.parsers, pandas._libs.testing, pygraphviz._graphviz, scipy.sparse._sparsetools, _csparsetools, scipy.sparse._csparsetools, scipy.linalg._fblas, scipy.linalg._flapack, scipy.linalg.cython_lapack, scipy.linalg._cythonized_array_utils, scipy.linalg._solve_toeplitz, scipy.linalg._decomp_lu_cython, scipy.linalg._matfuncs_sqrtm_triu, scipy.linalg.cython_blas, scipy.linalg._matfuncs_expm, scipy.linalg._decomp_update, scipy.sparse.linalg._dsolve._superlu, scipy.sparse.linalg._eigen.arpack._arpack, scipy.sparse.csgraph._tools, scipy.sparse.csgraph._shortest_path, scipy.sparse.csgraph._traversal, scipy.sparse.csgraph._min_spanning_tree, scipy.sparse.csgraph._flow, scipy.sparse.csgraph._matching, scipy.sparse.csgraph._reordering, scipy.optimize._minpack2, scipy.optimize._group_columns, scipy._lib.messagestream, scipy.optimize._trlib._trlib, scipy.optimize._lbfgsb, _moduleTNC, scipy.optimize._moduleTNC, scipy.optimize._cobyla, scipy.optimize._slsqp, scipy.optimize._minpack, scipy.optimize._lsq.givens_elimination, scipy.optimize._zeros, scipy.optimize._highs.cython.src._highs_wrapper, scipy.optimize._highs._highs_wrapper, scipy.optimize._highs.cython.src._highs_constants, scipy.optimize._highs._highs_constants, scipy.linalg._interpolative, scipy.optimize._bglu_dense, scipy.optimize._lsap, scipy.spatial._ckdtree, scipy.spatial._qhull, scipy.spatial._voronoi, scipy.spatial._distance_wrap, scipy.spatial._hausdorff, scipy.special._ufuncs_cxx, scipy.special._ufuncs, scipy.special._specfun, scipy.special._comb, scipy.special._ellip_harm_2, scipy.spatial.transform._rotation, scipy.optimize._direct, fontTools.misc.bezierTools, lxml._elementpath, lxml.etree, fontTools.varLib.iup (total: 116)
........................... [ 66%]
............................................................................x...............................FFF.................... [ 68%]
.............................F...F................................................................................................. [ 71%]
............[gw3] node down: Not properly terminated
F
replacing crashed worker gw3
collecting: 12/13 

<clipped>

Fatal Python error: Segmentation fault

Thread 0x00007eda27a006c0 (most recent call first):
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 474 in read
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 507 in from_io
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1049 in _thread_receiver
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 296 in run
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 361 in _perform_spawn

Current thread 0x00007eda293e3740 (most recent call first):
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pygraphviz/graphviz.py", line 226 in agnameof
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pygraphviz/agraph.py", line 228 in __repr__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_io/saferepr.py", line 73 in repr_instance
  File "/usr/lib/python3.11/reprlib.py", line 63 in repr1
  File "/usr/lib/python3.11/reprlib.py", line 53 in repr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_io/saferepr.py", line 61 in repr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_io/saferepr.py", line 111 in saferepr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 843 in repr_args
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 939 in repr_traceback_entry
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 994 in <listcomp>
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 993 in repr_traceback
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 1064 in repr_excinfo
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 699 in getrepr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/nodes.py", line 464 in _repr_failure_py
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/python.py", line 1814 in repr_failure
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/reports.py", line 364 in from_item_and_call
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 367 in pytest_runtest_makereport
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 242 in call_and_report
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 134 in runtestprotocol
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 115 in pytest_runtest_protocol
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/xdist/remote.py", line 174 in run_one_test
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/xdist/remote.py", line 157 in pytest_runtestloop
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/main.py", line 339 in _main
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/main.py", line 285 in wrap_session
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/main.py", line 332 in pytest_cmdline_main
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/xdist/remote.py", line 355 in <module>
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1157 in executetask
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 296 in run
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 361 in _perform_spawn
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 343 in integrate_as_primary_thread
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1142 in serve
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1640 in serve
  File "<string>", line 8 in <module>
  File "<string>", line 1 in <module>

Extension modules: markupsafe._speedups, numpy.core._multiarray_umath, numpy.core._multiarray_tests, numpy.linalg._umath_linalg, numpy.fft._pocketfft_internal, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, scipy._lib._ccallback_c, PIL._imaging, matplotlib._path, kiwisolver._cext, pandas._libs.tslibs.ccalendar, pandas._libs.tslibs.np_datetime, pandas._libs.tslibs.dtypes, pandas._libs.tslibs.base, pandas._libs.tslibs.nattype, pandas._libs.tslibs.timezones, pandas._libs.tslibs.fields, pandas._libs.tslibs.timedeltas, pandas._libs.tslibs.tzconversion, pandas._libs.tslibs.timestamps, pandas._libs.properties, pandas._libs.tslibs.offsets, pandas._libs.tslibs.strptime, pandas._libs.tslibs.parsing, pandas._libs.tslibs.conversion, pandas._libs.tslibs.period, pandas._libs.tslibs.vectorized, pandas._libs.ops_dispatch, pandas._libs.missing, pandas._libs.hashtable, pandas._libs.algos, pandas._libs.interval, pandas._libs.lib, pandas._libs.ops, pandas._libs.hashing, pandas._libs.arrays, pandas._libs.tslib, pandas._libs.sparse, pandas._libs.internals, pandas._libs.indexing, pandas._libs.index, pandas._libs.writers, pandas._libs.join, pandas._libs.window.aggregations, pandas._libs.window.indexers, pandas._libs.reshape, pandas._libs.groupby, pandas._libs.json, pandas._libs.parsers, pandas._libs.testing, pygraphviz._graphviz, scipy.sparse._sparsetools, _csparsetools, scipy.sparse._csparsetools, scipy.linalg._fblas, scipy.linalg._flapack, scipy.linalg.cython_lapack, scipy.linalg._cythonized_array_utils, scipy.linalg._solve_toeplitz, scipy.linalg._decomp_lu_cython, scipy.linalg._matfuncs_sqrtm_triu, scipy.linalg.cython_blas, scipy.linalg._matfuncs_expm, scipy.linalg._decomp_update, scipy.sparse.linalg._dsolve._superlu, scipy.sparse.linalg._eigen.arpack._arpack, scipy.sparse.csgraph._tools, scipy.sparse.csgraph._shortest_path, scipy.sparse.csgraph._traversal, scipy.sparse.csgraph._min_spanning_tree, scipy.sparse.csgraph._flow, scipy.sparse.csgraph._matching, scipy.sparse.csgraph._reordering, scipy.special._ufuncs_cxx, scipy.special._ufuncs, scipy.special._specfun, scipy.special._comb, scipy.special._ellip_harm_2 (total: 86)
.............................[gw12] node down: Not properly terminated
F
replacing crashed worker gw12
collecting: 13/14 workers.........................[gw4] node down: Not properly terminated
F
replacing crashed worker gw4
collecting: 13/15 workers...Fatal Python error: Segmentation fault

Thread 0x00007a522ba006c0 (most recent call first):
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 474 in read
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 507 in from_io
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1049 in _thread_receiver
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 296 in run
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 361 in _perform_spawn

Current thread 0x00007a522d3ff740 (most recent call first):
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pygraphviz/graphviz.py", line 226 in agnameof
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pygraphviz/agraph.py", line 228 in __repr__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_io/saferepr.py", line 73 in repr_instance
  File "/usr/lib/python3.11/reprlib.py", line 63 in repr1
  File "/usr/lib/python3.11/reprlib.py", line 53 in repr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_io/saferepr.py", line 61 in repr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_io/saferepr.py", line 111 in saferepr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 843 in repr_args
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 939 in repr_traceback_entry
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 994 in <listcomp>
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 993 in repr_traceback
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 1064 in repr_excinfo
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/_code/code.py", line 699 in getrepr
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/nodes.py", line 464 in _repr_failure_py
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/python.py", line 1814 in repr_failure
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/reports.py", line 364 in from_item_and_call
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 367 in pytest_runtest_makereport
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 242 in call_and_report
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 134 in runtestprotocol
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/runner.py", line 115 in pytest_runtest_protocol
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/xdist/remote.py", line 174 in run_one_test
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/xdist/remote.py", line 157 in pytest_runtestloop
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/main.py", line 339 in _main
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/main.py", line 285 in wrap_session
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/_pytest/main.py", line 332 in pytest_cmdline_main
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/xdist/remote.py", line 355 in <module>
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1157 in executetask
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 296 in run
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 361 in _perform_spawn
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 343 in integrate_as_primary_thread
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1142 in serve
  File "/home/ross/.virtualenvs/nx-dev/lib/python3.11/site-packages/execnet/gateway_base.py", line 1640 in serve
  File "<string>", line 8 in <module>
  File "<string>", line 1 in <module>

Extension modules: markupsafe._speedups, numpy.core._multiarray_umath, numpy.core._multiarray_tests, numpy.linalg._umath_linalg, numpy.fft._pocketfft_internal, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, scipy._lib._ccallback_c, PIL._imaging, matplotlib._path, kiwisolver._cext, pandas._libs.tslibs.ccalendar, pandas._libs.tslibs.np_datetime, pandas._libs.tslibs.dtypes, pandas._libs.tslibs.base, pandas._libs.tslibs.nattype, pandas._libs.tslibs.timezones, pandas._libs.tslibs.fields, pandas._libs.tslibs.timedeltas, pandas._libs.tslibs.tzconversion, pandas._libs.tslibs.timestamps, pandas._libs.properties, pandas._libs.tslibs.offsets, pandas._libs.tslibs.strptime, pandas._libs.tslibs.parsing, pandas._libs.tslibs.conversion, pandas._libs.tslibs.period, pandas._libs.tslibs.vectorized, pandas._libs.ops_dispatch, pandas._libs.missing, pandas._libs.hashtable, pandas._libs.algos, pandas._libs.interval, pandas._libs.lib, pandas._libs.ops, pandas._libs.hashing, pandas._libs.arrays, pandas._libs.tslib, pandas._libs.sparse, pandas._libs.internals, pandas._libs.indexing, pandas._libs.index, pandas._libs.writers, pandas._libs.join, pandas._libs.window.aggregations, pandas._libs.window.indexers, pandas._libs.reshape, pandas._libs.groupby, pandas._libs.json, pandas._libs.parsers, pandas._libs.testing, pygraphviz._graphviz, scipy.sparse._sparsetools, _csparsetools, scipy.sparse._csparsetools, scipy.linalg._fblas, scipy.linalg._flapack, scipy.linalg.cython_lapack, scipy.linalg._cythonized_array_utils, scipy.linalg._solve_toeplitz, scipy.linalg._decomp_lu_cython, scipy.linalg._matfuncs_sqrtm_triu, scipy.linalg.cython_blas, scipy.linalg._matfuncs_expm, scipy.linalg._decomp_update, scipy.sparse.linalg._dsolve._superlu, scipy.sparse.linalg._eigen.arpack._arpack, scipy.sparse.csgraph._tools, scipy.sparse.csgraph._shortest_path, scipy.sparse.csgraph._traversal, scipy.sparse.csgraph._min_spanning_tree, scipy.sparse.csgraph._flow, scipy.sparse.csgraph._matching, scipy.sparse.csgraph._reordering, fontTools.misc.bezierTools, lxml._elementpath, lxml.etree, fontTools.varLib.iup, scipy.optimize._minpack2, scipy.optimize._group_columns, scipy._lib.messagestream, scipy.optimize._trlib._trlib, scipy.optimize._lbfgsb, _moduleTNC, scipy.optimize._moduleTNC, scipy.optimize._cobyla, scipy.optimize._slsqp, scipy.optimize._minpack, scipy.optimize._lsq.givens_elimination, scipy.optimize._zeros, scipy.optimize._highs.cython.src._highs_wrapper, scipy.optimize._highs._highs_wrapper, scipy.optimize._highs.cython.src._highs_constants, scipy.optimize._highs._highs_constants, scipy.linalg._interpolative, scipy.optimize._bglu_dense, scipy.optimize._lsap, scipy.spatial._ckdtree, scipy.spatial._qhull, scipy.spatial._voronoi, scipy.spatial._distance_wrap, scipy.spatial._hausdorff, scipy.special._ufuncs_cxx, scipy.special._ufuncs, scipy.special._specfun, scipy.special._comb, scipy.special._ellip_harm_2, scipy.spatial.transform._rotation, scipy.optimize._direct, scipy.ndimage._nd_image, _ni_label, scipy.ndimage._ni_label, scipy.integrate._odepack, scipy.integrate._quadpack, scipy.integrate._vode, scipy.integrate._dop, scipy.integrate._lsoda, scipy.special.cython_special, scipy.stats._stats, scipy.stats.beta_ufunc, scipy.stats._boost.beta_ufunc, scipy.stats.binom_ufunc, scipy.stats._boost.binom_ufunc, scipy.stats.nbinom_ufunc, scipy.stats._boost.nbinom_ufunc, scipy.stats.hypergeom_ufunc, scipy.stats._boost.hypergeom_ufunc, scipy.stats.ncf_ufunc, scipy.stats._boost.ncf_ufunc, scipy.stats.ncx2_ufunc, scipy.stats._boost.ncx2_ufunc, scipy.stats.nct_ufunc, scipy.stats._boost.nct_ufunc, scipy.stats.skewnorm_ufunc, scipy.stats._boost.skewnorm_ufunc, scipy.stats.invgauss_ufunc, scipy.stats._boost.invgauss_ufunc, scipy.interpolate._fitpack, scipy.interpolate.dfitpack, scipy.interpolate._bspl, scipy.interpolate._ppoly, scipy.interpolate.interpnd, scipy.interpolate._rbfinterp_pythran, scipy.interpolate._rgi_cython, scipy.stats._biasedurn, scipy.stats._levy_stable.levyst, scipy.stats._stats_pythran, scipy._lib._uarray._uarray, scipy.stats._ansari_swilk_statistics, scipy.stats._sobol, scipy.stats._qmc_cy, scipy.stats._mvn, scipy.stats._rcont.rcont, scipy.stats._unuran.unuran_wrapper (total: 161)
15 workers [6269 items]  ....s...........[gw6] node down: Not properly terminated
F
replacing crashed worker gw6
16 workers [6269 items]  ..................s..............................................................................................................................................x...............x......x..............................................................................................................................................................................................................s...................................................................................................................................................s....................................................................................................
================================================================ FAILURES =================================================================
_____________________________________________________ TestPydot.test_pydot[neato-G0] ______________________________________________________
[gw2] linux -- Python 3.11.6 /home/ross/.virtualenvs/nx-dev/bin/python

self = <networkx.drawing.tests.test_pydot.TestPydot object at 0x75a13f3dd050>, G = <networkx.classes.graph.Graph object at 0x75a13f3cd550>
prog = 'neato', tmp_path = PosixPath('/tmp/pytest-of-ross/pytest-4/popen-gw2/test_pydot_neato_G0_0')

    @pytest.mark.parametrize("G", (nx.Graph(), nx.DiGraph()))
    @pytest.mark.parametrize("prog", ("neato", "dot"))
    def test_pydot(self, G, prog, tmp_path):
        """
        Validate :mod:`pydot`-based usage of the passed NetworkX graph with the
        passed basename of an external GraphViz command (e.g., `dot`, `neato`).
        """
    
        # Set the name of this graph to... "G". Failing to do so will
        # subsequently trip an assertion expecting this name.
        G.graph["name"] = "G"
    
        # Add arbitrary nodes and edges to the passed empty graph.
        G.add_edges_from([("A", "B"), ("A", "C"), ("B", "C"), ("A", "D")])
        G.add_node("E")
    
        # Validate layout of this graph with the passed GraphViz command.
        graph_layout = nx.nx_pydot.pydot_layout(G, prog=prog)
        assert isinstance(graph_layout, dict)
    
        # Convert this graph into a "pydot.Dot" instance.
        P = nx.nx_pydot.to_pydot(G)
    
        # Convert this "pydot.Dot" instance back into a graph of the same type.
        G2 = G.__class__(nx.nx_pydot.from_pydot(P))
    
        # Validate the original and resulting graphs to be the same.
        assert graphs_equal(G, G2)
    
        fname = tmp_path / "out.dot"
    
        # Serialize this "pydot.Dot" instance to a temporary file in dot format
        P.write_raw(fname)
    
        # Deserialize a list of new "pydot.Dot" instances back from this file.
        Pin_list = pydot.graph_from_dot_file(path=fname, encoding="utf-8")
    
        # Validate this file to contain only one graph.
        assert len(Pin_list) == 1
    
        # The single "pydot.Dot" instance deserialized from this file.
        Pin = Pin_list[0]
    
        # Sorted list of all nodes in the original "pydot.Dot" instance.
        n1 = sorted(p.get_name() for p in P.get_node_list())
    
        # Sorted list of all nodes in the deserialized "pydot.Dot" instance.
        n2 = sorted(p.get_name() for p in Pin.get_node_list())
    
        # Validate these instances to contain the same nodes.
        assert n1 == n2
    
        # Sorted list of all edges in the original "pydot.Dot" instance.
        e1 = sorted((e.get_source(), e.get_destination()) for e in P.get_edge_list())
    
        # Sorted list of all edges in the original "pydot.Dot" instance.
        e2 = sorted((e.get_source(), e.get_destination()) for e in Pin.get_edge_list())
    
        # Validate these instances to contain the same edges.
        assert e1 == e2
    
        # Deserialize a new graph of the same type back from this file.
>       Hin = nx.nx_pydot.read_dot(fname)

networkx/drawing/tests/test_pydot.py:75: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
networkx/utils/decorators.py:789: in func
    return argmap._lazy_compile(__wrapper)(*args, **kwargs)
<class 'networkx.utils.decorators.argmap'> compilation 1108:5: in argmap_read_dot_1103
    ???
networkx/utils/backends.py:538: in __call__
    return self._convert_and_call_for_tests(
networkx/utils/backends.py:949: in _convert_and_call_for_tests
    result = getattr(backend, self.name)(*converted_args, **converted_kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

path = <itertools._tee object at 0x75a130792800>

    @open_file(0, mode="r")
    @nx._dispatchable(name="pydot_read_dot", graphs=None, returns_graph=True)
    def read_dot(path):
        """Returns a NetworkX :class:`MultiGraph` or :class:`MultiDiGraph` from the
        dot file with the passed path.
    
        If this file contains multiple graphs, only the first such graph is
        returned. All graphs _except_ the first are silently ignored.
    
        Parameters
        ----------
        path : str or file
            Filename or file handle.
    
        Returns
        -------
        G : MultiGraph or MultiDiGraph
            A :class:`MultiGraph` or :class:`MultiDiGraph`.
    
        Notes
        -----
        Use `G = nx.Graph(nx.nx_pydot.read_dot(path))` to return a :class:`Graph` instead of a
        :class:`MultiGraph`.
        """
        import pydot
    
>       data = path.read()
E       AttributeError: 'itertools._tee' object has no attribute 'read'

networkx/drawing/nx_pydot.py:74: AttributeError
_____________________________________________________ TestPydot.test_pydot[neato-G1] ______________________________________________________
[gw2] linux -- Python 3.11.6 /home/ross/.virtualenvs/nx-dev/bin/python

self = <networkx.drawing.tests.test_pydot.TestPydot object at 0x75a13f3dd790>
G = <networkx.classes.digraph.DiGraph object at 0x75a13f3cd690>, prog = 'neato'
tmp_path = PosixPath('/tmp/pytest-of-ross/pytest-4/popen-gw2/test_pydot_neato_G1_0')

    @pytest.mark.parametrize("G", (nx.Graph(), nx.DiGraph()))
    @pytest.mark.parametrize("prog", ("neato", "dot"))
    def test_pydot(self, G, prog, tmp_path):
        """
        Validate :mod:`pydot`-based usage of the passed NetworkX graph with the
        passed basename of an external GraphViz command (e.g., `dot`, `neato`).
        """
    
        # Set the name of this graph to... "G". Failing to do so will
        # subsequently trip an assertion expecting this name.
        G.graph["name"] = "G"
    
        # Add arbitrary nodes and edges to the passed empty graph.
        G.add_edges_from([("A", "B"), ("A", "C"), ("B", "C"), ("A", "D")])
        G.add_node("E")
    
        # Validate layout of this graph with the passed GraphViz command.
        graph_layout = nx.nx_pydot.pydot_layout(G, prog=prog)
        assert isinstance(graph_layout, dict)
    
        # Convert this graph into a "pydot.Dot" instance.
        P = nx.nx_pydot.to_pydot(G)
    
        # Convert this "pydot.Dot" instance back into a graph of the same type.
        G2 = G.__class__(nx.nx_pydot.from_pydot(P))
    
        # Validate the original and resulting graphs to be the same.
        assert graphs_equal(G, G2)
    
        fname = tmp_path / "out.dot"
    
        # Serialize this "pydot.Dot" instance to a temporary file in dot format
        P.write_raw(fname)
    
        # Deserialize a list of new "pydot.Dot" instances back from this file.
        Pin_list = pydot.graph_from_dot_file(path=fname, encoding="utf-8")
    
        # Validate this file to contain only one graph.
        assert len(Pin_list) == 1
    
        # The single "pydot.Dot" instance deserialized from this file.
        Pin = Pin_list[0]
    
        # Sorted list of all nodes in the original "pydot.Dot" instance.
        n1 = sorted(p.get_name() for p in P.get_node_list())
    
        # Sorted list of all nodes in the deserialized "pydot.Dot" instance.
        n2 = sorted(p.get_name() for p in Pin.get_node_list())
    
        # Validate these instances to contain the same nodes.
        assert n1 == n2
    
        # Sorted list of all edges in the original "pydot.Dot" instance.
        e1 = sorted((e.get_source(), e.get_destination()) for e in P.get_edge_list())
    
        # Sorted list of all edges in the original "pydot.Dot" instance.
        e2 = sorted((e.get_source(), e.get_destination()) for e in Pin.get_edge_list())
    
        # Validate these instances to contain the same edges.
        assert e1 == e2
    
        # Deserialize a new graph of the same type back from this file.
>       Hin = nx.nx_pydot.read_dot(fname)

networkx/drawing/tests/test_pydot.py:75: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
<class 'networkx.utils.decorators.argmap'> compilation 1108:5: in argmap_read_dot_1103
    ???
networkx/utils/backends.py:538: in __call__
    return self._convert_and_call_for_tests(
networkx/utils/backends.py:949: in _convert_and_call_for_tests
    result = getattr(backend, self.name)(*converted_args, **converted_kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

path = <itertools._tee object at 0x75a11922a800>

    @open_file(0, mode="r")
    @nx._dispatchable(name="pydot_read_dot", graphs=None, returns_graph=True)
    def read_dot(path):
        """Returns a NetworkX :class:`MultiGraph` or :class:`MultiDiGraph` from the
        dot file with the passed path.
    
        If this file contains multiple graphs, only the first such graph is
        returned. All graphs _except_ the first are silently ignored.
    
        Parameters
        ----------
        path : str or file
            Filename or file handle.
    
        Returns
        -------
        G : MultiGraph or MultiDiGraph
            A :class:`MultiGraph` or :class:`MultiDiGraph`.
    
        Notes
        -----
        Use `G = nx.Graph(nx.nx_pydot.read_dot(path))` to return a :class:`Graph` instead of a
        :class:`MultiGraph`.
        """
        import pydot
    
>       data = path.read()
E       AttributeError: 'itertools._tee' object has no attribute 'read'

networkx/drawing/nx_pydot.py:74: AttributeError
______________________________________________________ TestPydot.test_pydot[dot-G0] _______________________________________________________
[gw2] linux -- Python 3.11.6 /home/ross/.virtualenvs/nx-dev/bin/python

self = <networkx.drawing.tests.test_pydot.TestPydot object at 0x75a13f3dda50>, G = <networkx.classes.graph.Graph object at 0x75a13f3cd550>
prog = 'dot', tmp_path = PosixPath('/tmp/pytest-of-ross/pytest-4/popen-gw2/test_pydot_dot_G0_0')

    @pytest.mark.parametrize("G", (nx.Graph(), nx.DiGraph()))
    @pytest.mark.parametrize("prog", ("neato", "dot"))
    def test_pydot(self, G, prog, tmp_path):
        """
        Validate :mod:`pydot`-based usage of the passed NetworkX graph with the
        passed basename of an external GraphViz command (e.g., `dot`, `neato`).
        """
    
        # Set the name of this graph to... "G". Failing to do so will
        # subsequently trip an assertion expecting this name.
        G.graph["name"] = "G"
    
        # Add arbitrary nodes and edges to the passed empty graph.
        G.add_edges_from([("A", "B"), ("A", "C"), ("B", "C"), ("A", "D")])
        G.add_node("E")
    
        # Validate layout of this graph with the passed GraphViz command.
        graph_layout = nx.nx_pydot.pydot_layout(G, prog=prog)
        assert isinstance(graph_layout, dict)
    
        # Convert this graph into a "pydot.Dot" instance.
        P = nx.nx_pydot.to_pydot(G)
    
        # Convert this "pydot.Dot" instance back into a graph of the same type.
        G2 = G.__class__(nx.nx_pydot.from_pydot(P))
    
        # Validate the original and resulting graphs to be the same.
        assert graphs_equal(G, G2)
    
        fname = tmp_path / "out.dot"
    
        # Serialize this "pydot.Dot" instance to a temporary file in dot format
        P.write_raw(fname)
    
        # Deserialize a list of new "pydot.Dot" instances back from this file.
        Pin_list = pydot.graph_from_dot_file(path=fname, encoding="utf-8")
    
        # Validate this file to contain only one graph.
        assert len(Pin_list) == 1
    
        # The single "pydot.Dot" instance deserialized from this file.
        Pin = Pin_list[0]
    
        # Sorted list of all nodes in the original "pydot.Dot" instance.
        n1 = sorted(p.get_name() for p in P.get_node_list())
    
        # Sorted list of all nodes in the deserialized "pydot.Dot" instance.
        n2 = sorted(p.get_name() for p in Pin.get_node_list())
    
        # Validate these instances to contain the same nodes.
        assert n1 == n2
    
        # Sorted list of all edges in the original "pydot.Dot" instance.
        e1 = sorted((e.get_source(), e.get_destination()) for e in P.get_edge_list())
    
        # Sorted list of all edges in the original "pydot.Dot" instance.
        e2 = sorted((e.get_source(), e.get_destination()) for e in Pin.get_edge_list())
    
        # Validate these instances to contain the same edges.
        assert e1 == e2
    
        # Deserialize a new graph of the same type back from this file.
>       Hin = nx.nx_pydot.read_dot(fname)

networkx/drawing/tests/test_pydot.py:75: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
<class 'networkx.utils.decorators.argmap'> compilation 1108:5: in argmap_read_dot_1103
    ???
networkx/utils/backends.py:538: in __call__
    return self._convert_and_call_for_tests(
networkx/utils/backends.py:949: in _convert_and_call_for_tests
    result = getattr(backend, self.name)(*converted_args, **converted_kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

path = <itertools._tee object at 0x75a114fe2880>

    @open_file(0, mode="r")
    @nx._dispatchable(name="pydot_read_dot", graphs=None, returns_graph=True)
    def read_dot(path):
        """Returns a NetworkX :class:`MultiGraph` or :class:`MultiDiGraph` from the
        dot file with the passed path.
    
        If this file contains multiple graphs, only the first such graph is
        returned. All graphs _except_ the first are silently ignored.
    
        Parameters
        ----------
        path : str or file
            Filename or file handle.
    
        Returns
        -------
        G : MultiGraph or MultiDiGraph
            A :class:`MultiGraph` or :class:`MultiDiGraph`.
    
        Notes
        -----
        Use `G = nx.Graph(nx.nx_pydot.read_dot(path))` to return a :class:`Graph` instead of a
        :class:`MultiGraph`.
        """
        import pydot
    
>       data = path.read()
E       AttributeError: 'itertools._tee' object has no attribute 'read'

networkx/drawing/nx_pydot.py:74: AttributeError
______________________________________________________ TestPydot.test_pydot[dot-G1] _______________________________________________________
[gw2] linux -- Python 3.11.6 /home/ross/.virtualenvs/nx-dev/bin/python

self = <networkx.drawing.tests.test_pydot.TestPydot object at 0x75a13f3cf1d0>
G = <networkx.classes.digraph.DiGraph object at 0x75a13f3cd690>, prog = 'dot'
tmp_path = PosixPath('/tmp/pytest-of-ross/pytest-4/popen-gw2/test_pydot_dot_G1_0')

    @pytest.mark.parametrize("G", (nx.Graph(), nx.DiGraph()))
    @pytest.mark.parametrize("prog", ("neato", "dot"))
    def test_pydot(self, G, prog, tmp_path):
        """
        Validate :mod:`pydot`-based usage of the passed NetworkX graph with the
        passed basename of an external GraphViz command (e.g., `dot`, `neato`).
        """
    
        # Set the name of this graph to... "G". Failing to do so will
        # subsequently trip an assertion expecting this name.
        G.graph["name"] = "G"
    
        # Add arbitrary nodes and edges to the passed empty graph.
        G.add_edges_from([("A", "B"), ("A", "C"), ("B", "C"), ("A", "D")])
        G.add_node("E")
    
        # Validate layout of this graph with the passed GraphViz command.
        graph_layout = nx.nx_pydot.pydot_layout(G, prog=prog)
        assert isinstance(graph_layout, dict)
    
        # Convert this graph into a "pydot.Dot" instance.
        P = nx.nx_pydot.to_pydot(G)
    
        # Convert this "pydot.Dot" instance back into a graph of the same type.
        G2 = G.__class__(nx.nx_pydot.from_pydot(P))
    
        # Validate the original and resulting graphs to be the same.
        assert graphs_equal(G, G2)
    
        fname = tmp_path / "out.dot"
    
        # Serialize this "pydot.Dot" instance to a temporary file in dot format
        P.write_raw(fname)
    
        # Deserialize a list of new "pydot.Dot" instances back from this file.
        Pin_list = pydot.graph_from_dot_file(path=fname, encoding="utf-8")
    
        # Validate this file to contain only one graph.
        assert len(Pin_list) == 1
    
        # The single "pydot.Dot" instance deserialized from this file.
        Pin = Pin_list[0]
    
        # Sorted list of all nodes in the original "pydot.Dot" instance.
        n1 = sorted(p.get_name() for p in P.get_node_list())
    
        # Sorted list of all nodes in the deserialized "pydot.Dot" instance.
        n2 = sorted(p.get_name() for p in Pin.get_node_list())
    
        # Validate these instances to contain the same nodes.
        assert n1 == n2
    
        # Sorted list of all edges in the original "pydot.Dot" instance.
        e1 = sorted((e.get_source(), e.get_destination()) for e in P.get_edge_list())
    
        # Sorted list of all edges in the original "pydot.Dot" instance.
        e2 = sorted((e.get_source(), e.get_destination()) for e in Pin.get_edge_list())
    
        # Validate these instances to contain the same edges.
        assert e1 == e2
    
        # Deserialize a new graph of the same type back from this file.
>       Hin = nx.nx_pydot.read_dot(fname)

networkx/drawing/tests/test_pydot.py:75: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
<class 'networkx.utils.decorators.argmap'> compilation 1108:5: in argmap_read_dot_1103
    ???
networkx/utils/backends.py:538: in __call__
    return self._convert_and_call_for_tests(
networkx/utils/backends.py:949: in _convert_and_call_for_tests
    result = getattr(backend, self.name)(*converted_args, **converted_kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

path = <itertools._tee object at 0x75a114e1d680>

    @open_file(0, mode="r")
    @nx._dispatchable(name="pydot_read_dot", graphs=None, returns_graph=True)
    def read_dot(path):
        """Returns a NetworkX :class:`MultiGraph` or :class:`MultiDiGraph` from the
        dot file with the passed path.
    
        If this file contains multiple graphs, only the first such graph is
        returned. All graphs _except_ the first are silently ignored.
    
        Parameters
        ----------
        path : str or file
            Filename or file handle.
    
        Returns
        -------
        G : MultiGraph or MultiDiGraph
            A :class:`MultiGraph` or :class:`MultiDiGraph`.
    
        Notes
        -----
        Use `G = nx.Graph(nx.nx_pydot.read_dot(path))` to return a :class:`Graph` instead of a
        :class:`MultiGraph`.
        """
        import pydot
    
>       data = path.read()
E       AttributeError: 'itertools._tee' object has no attribute 'read'

networkx/drawing/nx_pydot.py:74: AttributeError
________________________________________________________ TestPydot.test_read_write ________________________________________________________
[gw2] linux -- Python 3.11.6 /home/ross/.virtualenvs/nx-dev/bin/python

self = <networkx.drawing.tests.test_pydot.TestPydot object at 0x75a13f3c62d0>

    def test_read_write(self):
        G = nx.MultiGraph()
        G.graph["name"] = "G"
        G.add_edge("1", "2", key="0")  # read assumes strings
        fh = StringIO()
        nx.nx_pydot.write_dot(G, fh)
        fh.seek(0)
>       H = nx.nx_pydot.read_dot(fh)

networkx/drawing/tests/test_pydot.py:88: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
<class 'networkx.utils.decorators.argmap'> compilation 1108:5: in argmap_read_dot_1103
    ???
networkx/utils/backends.py:538: in __call__
    return self._convert_and_call_for_tests(
networkx/utils/backends.py:949: in _convert_and_call_for_tests
    result = getattr(backend, self.name)(*converted_args, **converted_kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

path = <itertools._tee object at 0x75a12e9a1f40>

    @open_file(0, mode="r")
    @nx._dispatchable(name="pydot_read_dot", graphs=None, returns_graph=True)
    def read_dot(path):
        """Returns a NetworkX :class:`MultiGraph` or :class:`MultiDiGraph` from the
        dot file with the passed path.
    
        If this file contains multiple graphs, only the first such graph is
        returned. All graphs _except_ the first are silently ignored.
    
        Parameters
        ----------
        path : str or file
            Filename or file handle.
    
        Returns
        -------
        G : MultiGraph or MultiDiGraph
            A :class:`MultiGraph` or :class:`MultiDiGraph`.
    
        Notes
        -----
        Use `G = nx.Graph(nx.nx_pydot.read_dot(path))` to return a :class:`Graph` instead of a
        :class:`MultiGraph`.
        """
        import pydot
    
>       data = path.read()
E       AttributeError: 'itertools._tee' object has no attribute 'read'

networkx/drawing/nx_pydot.py:74: AttributeError
__________________________________________________ networkx/drawing/tests/test_agraph.py __________________________________________________
[gw3] linux -- Python 3.11.6 /home/ross/.virtualenvs/nx-dev/bin/python
worker 'gw3' crashed while running 'networkx/drawing/tests/test_agraph.py::TestAGraph::test_agraph_roundtripping[G0]'
__________________________________________________ networkx/drawing/tests/test_agraph.py __________________________________________________
[gw12] linux -- Python 3.11.6 /home/ross/.virtualenvs/nx-dev/bin/python
worker 'gw12' crashed while running 'networkx/drawing/tests/test_agraph.py::TestAGraph::test_agraph_roundtripping[G2]'
__________________________________________________ networkx/drawing/tests/test_agraph.py __________________________________________________
[gw4] linux -- Python 3.11.6 /home/ross/.virtualenvs/nx-dev/bin/python
worker 'gw4' crashed while running 'networkx/drawing/tests/test_agraph.py::TestAGraph::test_agraph_roundtripping[G1]'
__________________________________________________ networkx/drawing/tests/test_agraph.py __________________________________________________
[gw6] linux -- Python 3.11.6 /home/ross/.virtualenvs/nx-dev/bin/python
worker 'gw6' crashed while running 'networkx/drawing/tests/test_agraph.py::TestAGraph::test_agraph_roundtripping[G3]'

========================================================= short test summary info =========================================================
FAILED networkx/drawing/tests/test_pydot.py::TestPydot::test_pydot[neato-G0] - AttributeError: 'itertools._tee' object has no attribute 'read'
FAILED networkx/drawing/tests/test_pydot.py::TestPydot::test_pydot[neato-G1] - AttributeError: 'itertools._tee' object has no attribute 'read'
FAILED networkx/drawing/tests/test_pydot.py::TestPydot::test_pydot[dot-G0] - AttributeError: 'itertools._tee' object has no attribute 'read'
FAILED networkx/drawing/tests/test_pydot.py::TestPydot::test_pydot[dot-G1] - AttributeError: 'itertools._tee' object has no attribute 'read'
FAILED networkx/drawing/tests/test_pydot.py::TestPydot::test_read_write - AttributeError: 'itertools._tee' object has no attribute 'read'
FAILED networkx/drawing/tests/test_agraph.py::TestAGraph::test_agraph_roundtripping[G0]
FAILED networkx/drawing/tests/test_agraph.py::TestAGraph::test_agraph_roundtripping[G2]
FAILED networkx/drawing/tests/test_agraph.py::TestAGraph::test_agraph_roundtripping[G1]
FAILED networkx/drawing/tests/test_agraph.py::TestAGraph::test_agraph_roundtripping[G3]
============================= 9 failed, 6237 passed, 12 skipped, 11 xfailed, 36 warnings in 104.94s (0:01:44) =============================
</pre>
</details>


Discussion:
Can confirm I could reproduce the seg fault errors (. Graphviz makes no promises about being thread-safe, but unsure why only the backend causes the faults...
As discussed at the last community meeting, I went ahead and ran the tests both with and without xdist + with and without backends to get a clearer picture of when the failures occur. I can confirm that the agraph tests fail as above both with and without xdist:

1. No xdist, no backend: `pytest --doctest-modules --pyargs networkx` | PASS
2. xdist, no backend: `pytest --doctest-modules -n auto --pyargs networkx` | PASS
3. No xdist, with backend: `NETWORKX_TEST_BACKEND=nx-loopback pytest --doctest-modules --pyargs networkx` | FAIL
4. xdist, with backend: `NETWORKX_TEST_BACKEND=nx-loopback pytest --doctest-modules -n auto --pyargs networkx | FAIL

So - @eriknw 's suspicions are confirmed: bullet 3 indicates that the problem is not necessarily related to xdist, but the backend machinery's interaction with pygraphviz.


I think I have seen something similar before, not sure about the `segfault` but maybe we need to use `threadpoolctl` here?
Maybe tangential but scipy ran into something that could be helpful (?) https://github.com/scipy/scipy/pull/14441
> but maybe we need to use threadpoolctl here?

From the previous set of tests, this doesn't seem to stem from parallelism but rather from nx-loopback itself. I haven't dug down into how the loopback interface works though!
Narrowing it down to a single test (quicker to reproduce):
```
NETWORKX_TEST_BACKEND=nx-loopback pytest networkx -k "test_agraph_roundtripping"   # FAILS
pytest networkx -k "test_agraph_roundtripping"                                     # PASSES
```
and the error is:
<details close>
<summary>pytest log</summary>
<br>

```
platform linux -- Python 3.10.12, pytest-8.0.2, pluggy-1.4.0
rootdir: /mnt/c/dev/networkx
plugins: cov-4.1.0, xdist-3.5.0
collected 5556 items / 5552 deselected / 4 selected                                                                                                                                                                                                 

networkx/drawing/tests/test_agraph.py Fatal Python error: Segmentation fault

Current thread 0x00007f83f4bd1000 (most recent call first):
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pygraphviz/graphviz.py", line 226 in agnameof
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pygraphviz/agraph.py", line 228 in __repr__
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/_io/saferepr.py", line 73 in repr_instance
  File "/usr/lib/python3.10/reprlib.py", line 62 in repr1
  File "/usr/lib/python3.10/reprlib.py", line 52 in repr
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/_io/saferepr.py", line 61 in repr
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/_io/saferepr.py", line 111 in saferepr
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/_code/code.py", line 842 in repr_args
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/_code/code.py", line 938 in repr_traceback_entry
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/_code/code.py", line 993 in <listcomp>
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/_code/code.py", line 992 in repr_traceback
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/_code/code.py", line 1063 in repr_excinfo
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/_code/code.py", line 698 in getrepr
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/nodes.py", line 496 in _repr_failure_py
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/python.py", line 1874 in repr_failure
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/reports.py", line 363 in from_item_and_call
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/runner.py", line 369 in pytest_runtest_makereport
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/runner.py", line 225 in call_and_report
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/runner.py", line 134 in runtestprotocol
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/runner.py", line 115 in pytest_runtest_protocol
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/main.py", line 352 in pytest_runtestloop
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/main.py", line 327 in _main
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/main.py", line 273 in wrap_session
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/main.py", line 320 in pytest_cmdline_main
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 175 in main
  File "/mnt/c/dev/networkx/.venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 198 in console_main
  File "/mnt/c/dev/networkx/.venv/bin/pytest", line 8 in <module>

Extension modules: numpy.core._multiarray_umath, numpy.core._multiarray_tests, numpy.linalg._umath_linalg, numpy.fft._pocketfft_internal, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, scipy._lib._ccallback_c, matplotlib._c_internal_utils, PIL._imaging, matplotlib._path, kiwisolver._cext, pandas._libs.tslibs.ccalendar, pandas._libs.tslibs.np_datetime, pandas._libs.tslibs.dtypes, pandas._libs.tslibs.base, pandas._libs.tslibs.nattype, pandas._libs.tslibs.timezones, pandas._libs.tslibs.fields, pandas._libs.tslibs.timedeltas, pandas._libs.tslibs.tzconversion, pandas._libs.tslibs.timestamps, pandas._libs.properties, pandas._libs.tslibs.offsets, pandas._libs.tslibs.strptime, pandas._libs.tslibs.parsing, pandas._libs.tslibs.conversion, pandas._libs.tslibs.period, pandas._libs.tslibs.vectorized, pandas._libs.ops_dispatch, pandas._libs.missing, pandas._libs.hashtable, pandas._libs.algos, pandas._libs.interval, pandas._libs.lib, pandas._libs.ops, pandas._libs.hashing, pandas._libs.arrays, pandas._libs.tslib, pandas._libs.sparse, pandas._libs.internals, pandas._libs.indexing, pandas._libs.index, pandas._libs.writers, pandas._libs.join, pandas._libs.window.aggregations, pandas._libs.window.indexers, pandas._libs.reshape, pandas._libs.groupby, pandas._libs.json, pandas._libs.parsers, pandas._libs.testing, pygraphviz._graphviz, scipy.sparse._sparsetools, _csparsetools, scipy.sparse._csparsetools, scipy.linalg._fblas, scipy.linalg._flapack, scipy.linalg.cython_lapack, scipy.linalg._cythonized_array_utils, scipy.linalg._solve_toeplitz, scipy.linalg._flinalg, scipy.linalg._decomp_lu_cython, scipy.linalg._matfuncs_sqrtm_triu, scipy.linalg.cython_blas, scipy.linalg._matfuncs_expm, scipy.linalg._decomp_update, scipy.sparse.linalg._dsolve._superlu, scipy.sparse.linalg._eigen.arpack._arpack, scipy.sparse.csgraph._tools, scipy.sparse.csgraph._shortest_path, scipy.sparse.csgraph._traversal, scipy.sparse.csgraph._min_spanning_tree, scipy.sparse.csgraph._flow, scipy.sparse.csgraph._matching, scipy.sparse.csgraph._reordering, matplotlib._image (total: 83)
Segmentation fault (core dumped)
```
<br>
</details>

---

Edit: It seems the issue arises when a file handler is passed to `networkx.nx_agraph.read_dot`. Exchanging 
```python
with open(fname) as fh:
    Hin = nx.nx_agraph.read_dot(fh)
```
for
```python
Hin = nx.nx_agraph.read_dot(fname)
```
[here](https://github.com/networkx/networkx/blob/f0b5a6d884ac7e303f2e2092d3a0a48723815239/networkx/drawing/tests/test_agraph.py#L44-L45) causes the test to no longer error for me. Interestingly the write method is fine either way.

Also, running the test code in a python file works fine too. It seems like the seg fault happens due to some thing pytest is doing with the handler/agraph

---

Edit 2: I've managed to circumvent the seg-fault - it's happening when pytest tries to call `repr` on the `pygraphviz.AGraph` during an error trace. I patched `lambda _: "<redacted>"` onto `AGraph.__repr__`, and now I believe the real error is:

<details close>
<summary>pytest log 2</summary>
<br>

```python
<class 'networkx.utils.decorators.argmap'> compilation 117:3: in argmap_read_dot_114
    ???
networkx/utils/backends.py:662: in __call__
    return self._convert_and_call_for_tests(
networkx/utils/backends.py:1248: in _convert_and_call_for_tests
    G = self.orig_func(*args2, **kwargs2)
networkx/drawing/nx_agraph.py:222: in read_dot
    A = pygraphviz.AGraph(file=path)
.venv/lib/python3.10/site-packages/pygraphviz/agraph.py:157: in __init__
    self.read(filename)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <redacted>, path = <_io.TextIOWrapper name='/tmp/pytest-of-aaronzo/pytest-109/test_agraph_roundtripping_G0_0/fh_test.dot' mode='r' encoding='UTF-8'>

    def read(self, path):
        """Read graph from dot format file on path.
    
        path can be a file name or file handle
    
        use::
    
           G.read('file.dot')
    
        """
        fh = self._get_fh(path)
        try:
            self._close_handle()
            try:
                self.handle = gv.agread(fh, None)
            except ValueError:
>               raise DotError("Invalid Input")
E               pygraphviz.agraph.DotError: Invalid Input

.venv/lib/python3.10/site-packages/pygraphviz/agraph.py:1252: DotError
```
<br>
</details>

Resolving patch:
diff --git a/networkx/utils/backends.py b/networkx/utils/backends.py
--- a/networkx/utils/backends.py
+++ b/networkx/utils/backends.py
@@ -1239,6 +1239,7 @@ def check_iterator(it):
             "read_pajek",
             "from_pydot",
             "pydot_read_dot",
+            "agraph_read_dot",
             # graph comparison fails b/c of nan values
             "read_gexf",
         }:


Test patch: