diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index 92c2617..a13f5ef 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 0.4.0
+current_version = 0.5.0.dev0
 commit = True
 tag = False
 parse = (?P<major>\d+)
diff --git a/dequindre/__init__.py b/dequindre/__init__.py
index 8c68511..ad99842 100644
--- a/dequindre/__init__.py
+++ b/dequindre/__init__.py
@@ -16,7 +16,7 @@ from subprocess import check_output, CalledProcessError
 from time import sleep
 
 
-__version__ = '0.4.0'
+__version__ = '0.5.0.dev0'
 
 
 class CyclicGraphError(Exception):
@@ -120,7 +120,7 @@ class DAG:
     def __init__(self, *, tasks: set = None, dependencies: dict = None):
         # check_conda()
         self.tasks = set()
-        self.edges = defaultdict(set)
+        self._edges = defaultdict(set)
 
         if tasks is not None:
             assert isinstance(tasks, set), '`tasks` must be a set of tasks'
@@ -174,11 +174,11 @@ class DAG:
         self.tasks.remove(task)
 
         # remove task from edges
-        for k in self.edges:
-            if task in self.edges[k]:
-                self.edges[k].remove(task)
-        if task in self.edges:
-            del self.edges[task]
+        for k in self._edges:
+            if task in self._edges[k]:
+                self._edges[k].remove(task)
+        if task in self._edges:
+            del self._edges[task]
 
         return None
 
@@ -190,7 +190,7 @@ class DAG:
         assert isinstance(end, Task), TypeError('end is not a dequindre Task')
 
         self.add_tasks({start, end})
-        self.edges[start].add(end)
+        self._edges[start].add(end)
 
         return None
 
@@ -219,7 +219,7 @@ class DAG:
         assert isinstance(depends_on, Task), TypeError('end is not a dequindre Task')
 
         self.add_tasks({task, depends_on})
-        self.edges[depends_on].add(task)
+        self._edges[depends_on].add(task)
 
         # cycles can only be introduced here
         if self.is_cyclic():
@@ -251,7 +251,7 @@ class DAG:
     def get_downstream(self) -> dict:
         """Return adjacency dict of downstream Tasks."""
         return defaultdict(set,
-            {k: v for k, v in self.edges.items() if len(v) > 0})
+            {k: v for k, v in self._edges.items() if len(v) > 0})
 
 
     def get_upstream(self) -> dict:
diff --git a/setup.py b/setup.py
index 9e231ba..990a919 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,5 @@
 from setuptools import setup, find_packages
 
-
 version = {}
 with open('./dequindre/__init__.py', 'r') as ifile:
     exec(ifile.read(), version)

protect DAG.edges from end users
rename `edges` to `_edges`. Users shouldn't be accessing edges unless they know what they're doing. The naming should also reflect that `edges` are an internal attribute. 
diff --git a/dequindre/tests/test_DAG.py b/dequindre/tests/test_DAG.py
index 7efa2d0..db1ca4c 100644
--- a/dequindre/tests/test_DAG.py
+++ b/dequindre/tests/test_DAG.py
@@ -82,7 +82,7 @@ def test__DAG_remove_task():
     assert dag.tasks == {B}, 'Test Task was not added to the DAG'
 
 # ----------------------------------------------------------------------------
-# DAG.edges
+# DAG._edges
 # ----------------------------------------------------------------------------
 @pytest.mark.run(order=2)
 def test__DAG_add_edge():
@@ -91,12 +91,12 @@ def test__DAG_add_edge():
     dag = DAG()
     dag.add_tasks({A, B})
     dag.add_edge(A, B)
-    assert dag.edges == {A: {B,}}, 'edge was not created'
+    assert dag._edges == {A: {B,}}, 'edge was not created'
 
     del dag 
     dag = DAG()
     dag.add_edge(A, B)
-    assert dag.edges == {A: {B,}}, 'edge Tasks were not added to DAG.tasks'
+    assert dag._edges == {A: {B,}}, 'edge Tasks were not added to DAG.tasks'
 
 
 @pytest.mark.run(order=2)
@@ -104,7 +104,7 @@ def test__DAG_edges():
     A, B = get_two_tasks()
     dag = DAG()
     dag.add_edges({A: B})
-    assert isinstance(dag.edges[A], set), 'edge dict value is not a set'
+    assert isinstance(dag._edges[A], set), 'edge dict value is not a set'
 
 # ----------------------------------------------------------------------------
 # add dependencies
@@ -113,7 +113,7 @@ def test__DAG_add_dependency():
     A, B = get_two_tasks()
     dag = DAG()
     dag.add_dependency(B, A)
-    assert dag.edges[A] == set([B])
+    assert dag._edges[A] == set([B])
 
 
 def test__DAG_add_dependency_detect_cycle():
@@ -129,12 +129,12 @@ def test__DAG_add_dependencies():
     C = Task('C.py', env='test-env')
     dag = DAG()
     dag.add_dependencies({B: A})
-    assert dag.edges[A] == set([B])
+    assert dag._edges[A] == set([B])
 
     dag = DAG()
     dag.add_dependencies({C: {A, B}})
-    assert dag.edges[A] == set([C])
-    assert dag.edges[B] == set([C])
+    assert dag._edges[A] == set([C])
+    assert dag._edges[B] == set([C])
 
 
 def test__DAG_add_dependency_detect_cycle():

pip install -e .[dev]
parse_log_pytest
pytest
pytest
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
-e git+https://github.com/vogt4nick/dequindre.git@8cdb24e2126557b56d99da17bed48428c3913712#egg=dequindre
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
packaging @ file:///croot/packaging_1734472117206/work
pluggy @ file:///croot/pluggy_1733169602837/work
pytest @ file:///croot/pytest_1738938843180/work
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work

name: dequindre
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py39h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pip=25.0=py39h06a4308_0
  - pluggy=1.5.0=py39h06a4308_0
  - pytest=8.3.4=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
prefix: /opt/conda/envs/dequindre

dequindre/tests/test_DAG.py::test__DAG_add_edge dequindre/tests/test_DAG.py::test__DAG_edges dequindre/tests/test_DAG.py::test__DAG_add_dependency dequindre/tests/test_DAG.py::test__DAG_add_dependencies
dequindre/tests/test_DAG.py::test__DAG_init dequindre/tests/test_DAG.py::test__DAG_repr dequindre/tests/test_DAG.py::test__DAG_add_task dequindre/tests/test_DAG.py::test__DAG_add_tasks dequindre/tests/test_DAG.py::test__DAG_remove_task dequindre/tests/test_DAG.py::test__DAG_add_dependency_detect_cycle dequindre/tests/test_DAG.py::test__DAG_get_downstream dequindre/tests/test_DAG.py::test__DAG_get_upstream dequindre/tests/test_DAG.py::test__DAG_get_sources dequindre/tests/test_DAG.py::test__DAG_get_sinks dequindre/tests/test_DAG.py::test__DAG_is_cyclic
setup.py .bumpversion.cfg dequindre/__init__.py
setup.py .bumpversion.cfg dequindre/__init__.py