icemac: Rebased onto master to get flake8 tests green.
icemac: Give an object `a` wrapped into `b` aka `a.__of__(b)`
Using `ExtensionClass.Base` removes the Acquisition proxy when writing such an object onto an attribute of the instance. Using `object` as base class does not do this. Maybe that's the reason why the former C implementation did not inherit from `ExtensionClass.Base`. 
diff --git a/CHANGES.rst b/CHANGES.rst
index 9bd0e39..5845a28 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,7 +4,9 @@ Changelog
 3.0b6 (unreleased)
 ------------------
 
-- Nothing changed yet.
+- Fix regression in ``.DT_Util.InstanceDict`` which broke the acquisition
+  chain of the item it wraps.
+  (`#38 <https://github.com/zopefoundation/DocumentTemplate/issues/38>`_)
 
 
 3.0b5 (2018-10-05)
diff --git a/src/DocumentTemplate/_DocumentTemplate.py b/src/DocumentTemplate/_DocumentTemplate.py
index 950cb61..e985a6e 100644
--- a/src/DocumentTemplate/_DocumentTemplate.py
+++ b/src/DocumentTemplate/_DocumentTemplate.py
@@ -108,7 +108,6 @@ import sys
 import types
 
 from Acquisition import aq_base
-from Acquisition import aq_inner
 from ExtensionClass import Base
 
 from DocumentTemplate.html_quote import html_quote
@@ -267,7 +266,7 @@ def safe_callable(ob):
     return callable(ob)
 
 
-class InstanceDict(Base):
+class InstanceDict(object):
     """"""
 
     guarded_getattr = None
@@ -306,7 +305,7 @@ class InstanceDict(Base):
             get = getattr
 
         try:
-            result = get(aq_inner(self.inst), key)
+            result = get(self.inst, key)
         except AttributeError:
             raise KeyError(key)
 

Changed behavior in acquisition
When trying to port a Zope installation from Zope2 to Zope4, I encountered an error where I am not sure if the behavior is intended and was broken in Zope2 or if it is a regression.

I could reproduce the problematic behavior with DTML Method, DTML Document as well as Z SQL Methods.

The minimal setup looks like this:

    /
    /main/
    /main/test (DTML Method containing <dtml-var included>)
    /side/
    /side/included (p.e., Python Script returning 1)

Expected behavior, working with Zope2:
Either by calling `/side/main/test` or `/main/side/test`, the content or result of `included` is found in the acquisition context and included in `test`.

Found behavior in Zope4:
Only `/main/side/test` gives the expected result, `/side/main/test` gives the attached `KeyError`

[traceback.txt](https://github.com/zopefoundation/DocumentTemplate/files/2705889/traceback.txt)

diff --git a/src/DocumentTemplate/tests/test_DocumentTemplate.py b/src/DocumentTemplate/tests/test_DocumentTemplate.py
index 585f522..a58fc5f 100644
--- a/src/DocumentTemplate/tests/test_DocumentTemplate.py
+++ b/src/DocumentTemplate/tests/test_DocumentTemplate.py
@@ -1,4 +1,18 @@
 import unittest
+import Acquisition
+
+
+class Item(Acquisition.Implicit):
+    """Class modelling the here necessary parts of OFS.SimpleItem."""
+
+    def __init__(self, id):
+        self.id = id
+
+    def __repr__(self):
+        return '<Item id={0.id!r}>'.format(self)
+
+    def method1(self):
+        pass
 
 
 class InstanceDictTests(unittest.TestCase):
@@ -12,22 +26,23 @@ class InstanceDictTests(unittest.TestCase):
         # https://github.com/zopefoundation/Zope/issues/292
 
         from DocumentTemplate.DT_Util import InstanceDict
-        import Acquisition
-
-        class Item(Acquisition.Implicit):
-            """Class modelling the here necessary parts of OFS.SimpleItem."""
-
-            def __init__(self, id):
-                self.id = id
-
-            def __repr__(self):
-                return '<Item id={0.id!r}>'.format(self)
-
-            def method1(self):
-                pass
 
         inst = Item('a').__of__(Item('b'))
         i_dict = InstanceDict(inst, {}, getattr)
 
         for element in Acquisition.aq_chain(i_dict['method1'].__self__):
             self.assertNotIsInstance(element, InstanceDict)
+
+    def test_getitem_2(self):
+        # It does not break the acquisition chain of stored objects.
+
+        from DocumentTemplate.DT_Util import InstanceDict
+
+        main = Item('main')
+        main.sub = Item('sub')
+        side = Item('side')
+        side.here = Item('here')
+
+        path = side.here.__of__(main)
+        i_dict = InstanceDict(path, {}, getattr)
+        self.assertEqual(main.sub, i_dict['sub'])

pip install -e .[dev]
parse_log_pytest
coverage flake8 pytest
apt-get update apt-get install -y gcc
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
AccessControl==5.7
Acquisition==4.13
attrs==22.2.0
AuthEncoding==4.3
BTrees==4.11.3
certifi==2021.5.30
cffi==1.15.1
coverage==6.2
DateTime==4.9
-e git+https://github.com/zopefoundation/DocumentTemplate.git@4ff3d6e91d933794306a915ef6088ed7d724989b#egg=DocumentTemplate
ExtensionClass==4.9
flake8==5.0.4
importlib-metadata==4.2.0
iniconfig==1.1.1
mccabe==0.7.0
multipart==1.1.0
packaging==21.3
Persistence==3.6
persistent==4.9.3
pluggy==1.0.0
py==1.11.0
pycodestyle==2.9.1
pycparser==2.21
pyflakes==2.5.0
pyparsing==3.1.4
pytest==7.0.1
python-gettext==4.1
pytz==2025.2
RestrictedPython==6.2
six==1.17.0
tomli==1.2.3
transaction==3.1.0
typing_extensions==4.1.1
zExceptions==4.3
zipp==3.6.0
zope.browser==2.4
zope.component==5.1.0
zope.configuration==4.4.1
zope.contenttype==4.6
zope.deferredimport==4.4
zope.deprecation==4.4.0
zope.event==4.6
zope.exceptions==4.6
zope.hookable==5.4
zope.i18n==4.9.0
zope.i18nmessageid==5.1.1
zope.interface==5.5.2
zope.location==4.3
zope.proxy==4.6.1
zope.publisher==6.1.0
zope.schema==6.2.1
zope.security==5.8
zope.sequencesort==4.2
zope.structuredtext==4.4
zope.testing==5.0.1

name: DocumentTemplate
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
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - 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=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - accesscontrol==5.7
      - acquisition==4.13
      - attrs==22.2.0
      - authencoding==4.3
      - btrees==4.11.3
      - cffi==1.15.1
      - coverage==6.2
      - datetime==4.9
      - extensionclass==4.9
      - flake8==5.0.4
      - importlib-metadata==4.2.0
      - iniconfig==1.1.1
      - mccabe==0.7.0
      - multipart==1.1.0
      - packaging==21.3
      - persistence==3.6
      - persistent==4.9.3
      - pluggy==1.0.0
      - py==1.11.0
      - pycodestyle==2.9.1
      - pycparser==2.21
      - pyflakes==2.5.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - python-gettext==4.1
      - pytz==2025.2
      - restrictedpython==6.2
      - six==1.17.0
      - tomli==1.2.3
      - transaction==3.1.0
      - typing-extensions==4.1.1
      - zexceptions==4.3
      - zipp==3.6.0
      - zope-browser==2.4
      - zope-component==5.1.0
      - zope-configuration==4.4.1
      - zope-contenttype==4.6
      - zope-deferredimport==4.4
      - zope-deprecation==4.4.0
      - zope-event==4.6
      - zope-exceptions==4.6
      - zope-hookable==5.4
      - zope-i18n==4.9.0
      - zope-i18nmessageid==5.1.1
      - zope-interface==5.5.2
      - zope-location==4.3
      - zope-proxy==4.6.1
      - zope-publisher==6.1.0
      - zope-schema==6.2.1
      - zope-security==5.8
      - zope-sequencesort==4.2
      - zope-structuredtext==4.4
      - zope-testing==5.0.1
prefix: /opt/conda/envs/DocumentTemplate

src/DocumentTemplate/tests/test_DocumentTemplate.py::InstanceDictTests::test_getitem_2
src/DocumentTemplate/tests/test_DocumentTemplate.py::InstanceDictTests::test_getitem
src/DocumentTemplate/_DocumentTemplate.py CHANGES.rst
src/DocumentTemplate/_DocumentTemplate.py CHANGES.rst