diff --git a/configmanager/__init__.py b/configmanager/__init__.py
index b0b47c1..e912d5f 100644
--- a/configmanager/__init__.py
+++ b/configmanager/__init__.py
@@ -1,4 +1,4 @@
-__version__ = '0.0.15'
+__version__ = '0.0.16'
 
 from .base import not_set, ConfigItem, ConfigManager
 from .exceptions import UnknownConfigItem, ConfigValueNotSet, UnsupportedOperation
diff --git a/configmanager/base.py b/configmanager/base.py
index 27b2a3a..fbe389e 100644
--- a/configmanager/base.py
+++ b/configmanager/base.py
@@ -115,6 +115,7 @@ class ConfigItem(object):
         """
         The first segment of :attr:`.path`.
         """
+        # TODO Deprecated
         return self.path[0]
 
     @property
@@ -122,6 +123,7 @@ class ConfigItem(object):
         """
         The second segment of :attr:`.path`.
         """
+        # TODO Deprecated
         return self.path[-1]
 
     @property
@@ -129,6 +131,7 @@ class ConfigItem(object):
         """
         A string, :attr:`.path` joined by dots.
         """
+        # TODO Deprecated
         return '.'.join(self.path)
 
     @property
@@ -384,26 +387,6 @@ class ConfigManager(object):
         """
         return self._resolve_config_path(*path) in self._configs
 
-    def items(self, *prefix):
-        """
-        Returns:
-            list: list of :class:`.ConfigItem` instances managed by this manager.
-            
-            If ``prefix`` is specified, only items with matching path prefix are included.
-        
-        Note:
-            This is different from ``ConfigParser.items()`` which returns what we would call
-            here resolved values of items.
-        
-        See Also:
-            :meth:`.ConfigManager.export()`
-        """
-        prefix = resolve_config_prefix(*prefix)
-        if not prefix:
-            return list(self._configs.values())
-        else:
-            return [c for c in self._configs.values() if c.path[:len(prefix)] == prefix[:]]
-
     def find_items(self, *prefix):
         prefix = resolve_config_prefix(*prefix)
         if not prefix:
@@ -433,7 +416,7 @@ class ConfigManager(object):
         """
         pairs = []
 
-        for item in self.items(*prefix):
+        for item in self.find_items(*prefix):
             if item.has_value or item.has_default:
                 item_name_without_prefix = '.'.join(item.path[len(prefix):])
                 pairs.append((item_name_without_prefix, item.value))
diff --git a/configmanager/proxies.py b/configmanager/proxies.py
index 1e2a07b..3fbdf00 100644
--- a/configmanager/proxies.py
+++ b/configmanager/proxies.py
@@ -60,6 +60,9 @@ class PathProxy(object):
     def __eq__(self, other):
         return isinstance(other, self.__class__) and (self._path_ == other._path_) and (self._config_ is other._config_)
 
+    def items(self):
+        return ((k, self[k]) for k in self)
+
 
 class ConfigItemProxy(PathProxy):
 
diff --git a/docs/guide.rst b/docs/guide.rst
index beaa2b1..e76a5ce 100644
--- a/docs/guide.rst
+++ b/docs/guide.rst
@@ -109,13 +109,13 @@ Copying Config Items Between Managers
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The easiest way to copy all config items from one :ref:`config-manager` to another is
-to use :meth:`.ConfigManager.items()`::
+to use :meth:`.ConfigManager.find_items()`::
 
     config1 = ConfigManager(
          ConfigItem('upload', 'threads', default=1, value=3)
     )
 
-    config2 = ConfigManager(*config1.items())
+    config2 = ConfigManager(*config1.find_items())
 
 If you don't want to keep the values (just the defaults), you can call :meth:`.ConfigManager.reset`:
 
@@ -128,4 +128,4 @@ If you don't want to keep the values (just the defaults), you can call :meth:`.C
 If the second config manager already exists, you can add config items to it with
 :meth:`.ConfigManager.add`::
 
-    map(config2.add, config1.items())
+    map(config2.add, config1.find_items())

Get rid of current ConfigManager.items() implementation
diff --git a/tests/test_configmanager.py b/tests/test_configmanager.py
index b0bbe4d..d93ec92 100644
--- a/tests/test_configmanager.py
+++ b/tests/test_configmanager.py
@@ -164,52 +164,6 @@ def test_reset():
     assert m.get('forgettable', 'y') == 'YES'
 
 
-def test_items_returns_all_config_items():
-    m = ConfigManager(
-        ConfigItem('a', 'aa', 'aaa'),
-        ConfigItem('b', 'bb'),
-        ConfigItem('a', 'aa', 'AAA'),
-        ConfigItem('b', 'BB'),
-    )
-
-    assert len(m.items()) == 4
-    assert m.items()[0].path == ('a', 'aa', 'aaa')
-    assert m.items()[-1].path == ('b', 'BB')
-
-
-def test_items_with_prefix_returns_matching_config_items():
-    m = ConfigManager(
-        ConfigItem('a', 'aa', 'aaa'),
-        ConfigItem('a.aa', 'haha'),
-        ConfigItem('b', 'bb'),
-        ConfigItem('a', 'aa', 'AAA'),
-        ConfigItem('b', 'BB'),
-    )
-
-    a_items = m.items('a')
-    assert len(a_items) == 2
-    assert a_items[0].path == ('a', 'aa', 'aaa')
-    assert a_items[1].path == ('a', 'aa', 'AAA')
-
-    a_aa_items1 = m.items('a', 'aa')
-    a_aa_items2 = m.items('a.aa')
-    assert a_aa_items1 != a_aa_items2
-
-    assert len(a_aa_items1) == 2
-    assert a_aa_items1[0].path == ('a', 'aa', 'aaa')
-    assert a_aa_items1[1].path == ('a', 'aa', 'AAA')
-
-    assert len(a_aa_items2) == 1
-    assert a_aa_items2[0].path == ('a.aa', 'haha')
-
-    assert len(m.items('b')) == 2
-    assert len(m.items('b', 'bb')) == 1
-    assert len(m.items('b.bb')) == 0
-
-    no_items = m.items('haha.haha')
-    assert len(no_items) == 0
-
-
 def test_can_add_items_to_default_section_and_set_their_value_without_naming_section():
     m = ConfigManager()
 
@@ -302,7 +256,7 @@ def test_copying_items_between_managers():
         ConfigItem('b', 'bbbb', 'q'),
     )
 
-    n = ConfigManager(*m.items())
+    n = ConfigManager(*m.find_items())
     assert m.export() == n.export()
 
     m.set('a', 'x', 'xaxa')
diff --git a/tests/test_proxies.py b/tests/test_proxies.py
index 6b94e11..7035e8f 100644
--- a/tests/test_proxies.py
+++ b/tests/test_proxies.py
@@ -51,8 +51,8 @@ def test_value_proxy_does_not_provide_section_and_item_access(config):
     with pytest.raises(AttributeError):
         config.v.uploads.get('enabled', True)
 
-    with pytest.raises(AttributeError):
-        config.v.items()
+    # This is different, "items" don't refer to config items here, it's part of Python's dictionary interface.
+    assert config.v.items()
 
 
 def test_value_proxy_is_iterable(config):
@@ -151,8 +151,8 @@ def test_section_proxy_raises_attribute_error_if_section_not_specified(config):
     with pytest.raises(AttributeError):
         config.s.set('enabled', True)
 
-    with pytest.raises(AttributeError):
-        config.s.items()
+    # This is different now, items() is part of Python's dictionary interface, nothing to do with config items.
+    assert config.s.items()
 
     with pytest.raises(AttributeError):
         config.s.has('uploads')
@@ -194,3 +194,17 @@ def test_item_proxy_is_iterable(config):
     assert ('auth', 'server', 'port') in paths
     assert ('uploads', 'something_else') not in paths
 
+
+def test_proxies_support_items_transparently(config):
+    items = dict(config.t.items())
+    assert len(items) == 7
+    assert isinstance(items[('uploads', 'enabled')], ConfigItem)
+
+    sections = dict(config.s.items())
+    assert len(sections) == 5
+    assert isinstance(sections[('auth', 'server')], ConfigSectionProxy)
+
+    values = dict(config.v.items())
+    assert len(values) == 2
+    assert values[('uploads', 'enabled')] is False
+    assert values[('downloads', 'threads')] == 0

pip install -e .
parse_log_pytest
requirements.txt
pytest
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
cachetools==5.5.2
chardet==5.2.0
colorama==0.4.6
-e git+https://github.com/jbasko/configmanager.git@b63b5e6c97f694392d3b01a7f2b8345c56ddf7f6#egg=configmanager
configparser==7.2.0
coverage==7.8.0
distlib==0.3.9
exceptiongroup==1.2.2
filelock==3.18.0
iniconfig==2.1.0
packaging==24.2
platformdirs==4.3.7
pluggy==1.5.0
pyproject-api==1.9.0
pytest==8.3.5
six==1.17.0
tomli==2.2.1
tox==4.25.0
typing_extensions==4.13.0
virtualenv==20.29.3

name: configmanager
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
  - 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
  - pip=25.0=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
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - cachetools==5.5.2
      - chardet==5.2.0
      - colorama==0.4.6
      - configparser==7.2.0
      - coverage==7.8.0
      - distlib==0.3.9
      - exceptiongroup==1.2.2
      - filelock==3.18.0
      - iniconfig==2.1.0
      - packaging==24.2
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pyproject-api==1.9.0
      - pytest==8.3.5
      - six==1.17.0
      - tomli==2.2.1
      - tox==4.25.0
      - typing-extensions==4.13.0
      - virtualenv==20.29.3
prefix: /opt/conda/envs/configmanager

tests/test_proxies.py::test_value_proxy_does_not_provide_section_and_item_access tests/test_proxies.py::test_section_proxy_raises_attribute_error_if_section_not_specified tests/test_proxies.py::test_proxies_support_items_transparently
tests/test_configmanager.py::test_get_item_returns_config_item tests/test_configmanager.py::test_get_returns_value_not_item tests/test_configmanager.py::test_basic_accessors_with_no_path_raise_value_error[get] tests/test_configmanager.py::test_basic_accessors_with_no_path_raise_value_error[has] tests/test_configmanager.py::test_basic_accessors_with_no_path_raise_value_error[get_item] tests/test_configmanager.py::test_basic_accessors_with_no_path_raise_value_error[set] tests/test_configmanager.py::test_duplicate_config_raises_value_error tests/test_configmanager.py::test_sets_config tests/test_configmanager.py::test_config_manager_configs_are_safe_copies tests/test_configmanager.py::test_has tests/test_configmanager.py::test_cannot_retrieve_non_existent_config tests/test_configmanager.py::test_reset tests/test_configmanager.py::test_can_add_items_to_default_section_and_set_their_value_without_naming_section tests/test_configmanager.py::test_export_empty_config_manager tests/test_configmanager.py::test_export_config_manager_with_no_values tests/test_configmanager.py::test_export_config_manager_with_default_section_item tests/test_configmanager.py::test_export_config_manager_with_multiple_sections_and_defaults tests/test_configmanager.py::test_exports_configs_with_prefix tests/test_configmanager.py::test_exports_configs_with_deep_paths tests/test_configmanager.py::test_copying_items_between_managers tests/test_configmanager.py::test_read_as_defaults_treats_all_values_as_declarations tests/test_proxies.py::test_value_proxy_exposes_values_for_reading_and_writing tests/test_proxies.py::test_value_proxy_is_iterable tests/test_proxies.py::test_section_proxy_forbids_access_to_config_items_via_attributes tests/test_proxies.py::test_section_proxy_exposes_sections_and_basic_manager_interface tests/test_proxies.py::test_section_proxy_exposes_has_values_and_reset tests/test_proxies.py::test_section_proxy_is_iterable tests/test_proxies.py::test_item_proxy_provides_access_to_items tests/test_proxies.py::test_item_proxy_is_iterable
configmanager/base.py configmanager/__init__.py configmanager/proxies.py docs/guide.rst
configmanager/base.py configmanager/__init__.py configmanager/proxies.py docs/guide.rst