about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/networkx/utils/tests/test_config.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/networkx/utils/tests/test_config.py')
-rw-r--r--.venv/lib/python3.12/site-packages/networkx/utils/tests/test_config.py231
1 files changed, 231 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/networkx/utils/tests/test_config.py b/.venv/lib/python3.12/site-packages/networkx/utils/tests/test_config.py
new file mode 100644
index 00000000..7416b0ac
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/networkx/utils/tests/test_config.py
@@ -0,0 +1,231 @@
+import collections
+import pickle
+
+import pytest
+
+import networkx as nx
+from networkx.utils.configs import BackendPriorities, Config
+
+
+# Define this at module level so we can test pickling
+class ExampleConfig(Config):
+    """Example configuration."""
+
+    x: int
+    y: str
+
+    def _on_setattr(self, key, value):
+        if key == "x" and value <= 0:
+            raise ValueError("x must be positive")
+        if key == "y" and not isinstance(value, str):
+            raise TypeError("y must be a str")
+        return value
+
+
+class EmptyConfig(Config):
+    pass
+
+
+@pytest.mark.parametrize("cfg", [EmptyConfig(), Config()])
+def test_config_empty(cfg):
+    assert dir(cfg) == []
+    with pytest.raises(AttributeError):
+        cfg.x = 1
+    with pytest.raises(KeyError):
+        cfg["x"] = 1
+    with pytest.raises(AttributeError):
+        cfg.x
+    with pytest.raises(KeyError):
+        cfg["x"]
+    assert len(cfg) == 0
+    assert "x" not in cfg
+    assert cfg == cfg
+    assert cfg.get("x", 2) == 2
+    assert set(cfg.keys()) == set()
+    assert set(cfg.values()) == set()
+    assert set(cfg.items()) == set()
+    cfg2 = pickle.loads(pickle.dumps(cfg))
+    assert cfg == cfg2
+    assert isinstance(cfg, collections.abc.Collection)
+    assert isinstance(cfg, collections.abc.Mapping)
+
+
+def test_config_subclass():
+    with pytest.raises(TypeError, match="missing 2 required keyword-only"):
+        ExampleConfig()
+    with pytest.raises(ValueError, match="x must be positive"):
+        ExampleConfig(x=0, y="foo")
+    with pytest.raises(TypeError, match="unexpected keyword"):
+        ExampleConfig(x=1, y="foo", z="bad config")
+    with pytest.raises(TypeError, match="unexpected keyword"):
+        EmptyConfig(z="bad config")
+    cfg = ExampleConfig(x=1, y="foo")
+    assert cfg.x == 1
+    assert cfg["x"] == 1
+    assert cfg["y"] == "foo"
+    assert cfg.y == "foo"
+    assert "x" in cfg
+    assert "y" in cfg
+    assert "z" not in cfg
+    assert len(cfg) == 2
+    assert set(iter(cfg)) == {"x", "y"}
+    assert set(cfg.keys()) == {"x", "y"}
+    assert set(cfg.values()) == {1, "foo"}
+    assert set(cfg.items()) == {("x", 1), ("y", "foo")}
+    assert dir(cfg) == ["x", "y"]
+    cfg.x = 2
+    cfg["y"] = "bar"
+    assert cfg["x"] == 2
+    assert cfg.y == "bar"
+    with pytest.raises(TypeError, match="can't be deleted"):
+        del cfg.x
+    with pytest.raises(TypeError, match="can't be deleted"):
+        del cfg["y"]
+    assert cfg.x == 2
+    assert cfg == cfg
+    assert cfg == ExampleConfig(x=2, y="bar")
+    assert cfg != ExampleConfig(x=3, y="baz")
+    assert cfg != Config(x=2, y="bar")
+    with pytest.raises(TypeError, match="y must be a str"):
+        cfg["y"] = 5
+    with pytest.raises(ValueError, match="x must be positive"):
+        cfg.x = -5
+    assert cfg.get("x", 10) == 2
+    with pytest.raises(AttributeError):
+        cfg.z = 5
+    with pytest.raises(KeyError):
+        cfg["z"] = 5
+    with pytest.raises(AttributeError):
+        cfg.z
+    with pytest.raises(KeyError):
+        cfg["z"]
+    cfg2 = pickle.loads(pickle.dumps(cfg))
+    assert cfg == cfg2
+    assert cfg.__doc__ == "Example configuration."
+    assert cfg2.__doc__ == "Example configuration."
+
+
+def test_config_defaults():
+    class DefaultConfig(Config):
+        x: int = 0
+        y: int
+
+    cfg = DefaultConfig(y=1)
+    assert cfg.x == 0
+    cfg = DefaultConfig(x=2, y=1)
+    assert cfg.x == 2
+
+
+def test_nxconfig():
+    assert isinstance(nx.config.backend_priority, BackendPriorities)
+    assert isinstance(nx.config.backend_priority.algos, list)
+    assert isinstance(nx.config.backends, Config)
+    with pytest.raises(TypeError, match="must be a list of backend names"):
+        nx.config.backend_priority.algos = "nx_loopback"
+    with pytest.raises(ValueError, match="Unknown backend when setting"):
+        nx.config.backend_priority.algos = ["this_almost_certainly_is_not_a_backend"]
+    with pytest.raises(TypeError, match="must be a Config of backend configs"):
+        nx.config.backends = {}
+    with pytest.raises(TypeError, match="must be a Config of backend configs"):
+        nx.config.backends = Config(plausible_backend_name={})
+    with pytest.raises(ValueError, match="Unknown backend when setting"):
+        nx.config.backends = Config(this_almost_certainly_is_not_a_backend=Config())
+    with pytest.raises(TypeError, match="must be True or False"):
+        nx.config.cache_converted_graphs = "bad value"
+    with pytest.raises(TypeError, match="must be a set of "):
+        nx.config.warnings_to_ignore = 7
+    with pytest.raises(ValueError, match="Unknown warning "):
+        nx.config.warnings_to_ignore = {"bad value"}
+
+
+def test_not_strict():
+    class FlexibleConfig(Config, strict=False):
+        x: int
+
+    cfg = FlexibleConfig(x=1)
+    assert "_strict" not in cfg
+    assert len(cfg) == 1
+    assert list(cfg) == ["x"]
+    assert list(cfg.keys()) == ["x"]
+    assert list(cfg.values()) == [1]
+    assert list(cfg.items()) == [("x", 1)]
+    assert cfg.x == 1
+    assert cfg["x"] == 1
+    assert "x" in cfg
+    assert hasattr(cfg, "x")
+    assert "FlexibleConfig(x=1)" in repr(cfg)
+    assert cfg == FlexibleConfig(x=1)
+    del cfg.x
+    assert "FlexibleConfig()" in repr(cfg)
+    assert len(cfg) == 0
+    assert not hasattr(cfg, "x")
+    assert "x" not in cfg
+    assert not hasattr(cfg, "y")
+    assert "y" not in cfg
+    cfg.y = 2
+    assert len(cfg) == 1
+    assert list(cfg) == ["y"]
+    assert list(cfg.keys()) == ["y"]
+    assert list(cfg.values()) == [2]
+    assert list(cfg.items()) == [("y", 2)]
+    assert cfg.y == 2
+    assert cfg["y"] == 2
+    assert hasattr(cfg, "y")
+    assert "y" in cfg
+    del cfg["y"]
+    assert len(cfg) == 0
+    assert list(cfg) == []
+    with pytest.raises(AttributeError, match="y"):
+        del cfg.y
+    with pytest.raises(KeyError, match="y"):
+        del cfg["y"]
+    with pytest.raises(TypeError, match="missing 1 required keyword-only"):
+        FlexibleConfig()
+    # Be strict when first creating the config object
+    with pytest.raises(TypeError, match="unexpected keyword argument 'y'"):
+        FlexibleConfig(x=1, y=2)
+
+    class FlexibleConfigWithDefault(Config, strict=False):
+        x: int = 0
+
+    assert FlexibleConfigWithDefault().x == 0
+    assert FlexibleConfigWithDefault(x=1)["x"] == 1
+
+
+def test_context():
+    cfg = Config(x=1)
+    with cfg(x=2) as c:
+        assert c.x == 2
+        c.x = 3
+        assert cfg.x == 3
+    assert cfg.x == 1
+
+    with cfg(x=2) as c:
+        assert c == cfg
+        assert cfg.x == 2
+        with cfg(x=3) as c2:
+            assert c2 == cfg
+            assert cfg.x == 3
+            with pytest.raises(RuntimeError, match="context manager without"):
+                with cfg as c3:  # Forgot to call `cfg(...)`
+                    pass
+            assert cfg.x == 3
+        assert cfg.x == 2
+    assert cfg.x == 1
+
+    c = cfg(x=4)  # Not yet as context (not recommended, but possible)
+    assert c == cfg
+    assert cfg.x == 4
+    # Cheat by looking at internal data; context stack should only grow with __enter__
+    assert cfg._prev is not None
+    assert cfg._context_stack == []
+    with c:
+        assert c == cfg
+        assert cfg.x == 4
+    assert cfg.x == 1
+    # Cheat again; there was no preceding `cfg(...)` call this time
+    assert cfg._prev is None
+    with pytest.raises(RuntimeError, match="context manager without"):
+        with cfg:
+            pass
+    assert cfg.x == 1