Skip to content

Commit c62e64e

Browse files
committed
fix: handle 3.11 find_spec implementation
3.11 changed some aspect of how finders are implemented, and broke our previous approach to wrapping find_spec. These changes make wrapping work again.
1 parent 646d1bc commit c62e64e

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

_appmap/importer.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,7 @@ def do_import(cls, *args, **kwargs):
165165

166166
logger.debug("do_import, mod %s args %s kwargs %s", mod, args, kwargs)
167167
if not cls.filter_chain:
168-
cls.filter_chain = reduce(
169-
lambda acc, e: e(acc), cls.filter_stack, NullFilter(None)
170-
)
168+
cls.filter_chain = reduce(lambda acc, e: e(acc), cls.filter_stack, NullFilter(None))
171169

172170
def instrument_functions(filterable, selected_functions=None):
173171
logger.debug(" looking for members of %s", filterable.obj)
@@ -264,12 +262,26 @@ def wrapped_find_spec(find_spec, _, args, kwargs):
264262

265263

266264
def wrap_finder_find_spec(finder):
267-
find_spec = getattr(finder, "find_spec", None)
268-
if find_spec is None:
269-
logger.debug("no find_spec for finder %r", finder)
270-
return
265+
# Prior to 3.11, it worked fine to just grab find_spec from the finder and wrap it. The
266+
# implementation of builtin finders must have changed with 3.11, because we now need the same
267+
# kind of workaround we use above for exec_module.
268+
if sys.version_info[1] < 11:
269+
find_spec = getattr(finder, "find_spec", None)
270+
if find_spec is None:
271+
logger.debug("no find_spec for finder %r", finder)
272+
return
271273

272-
finder.find_spec = wrap_finder_function(find_spec, wrapped_find_spec)
274+
finder.find_spec = wrap_finder_function(find_spec, wrapped_find_spec)
275+
else:
276+
find_spec = inspect.getattr_static(finder, "find_spec", None)
277+
if find_spec is None:
278+
logger.debug("no find_spec for finder %r", finder)
279+
return
280+
281+
if isinstance(find_spec, (classmethod, staticmethod)):
282+
finder.find_spec = wrap_finder_function(find_spec, wrapped_find_spec)
283+
else:
284+
finder.find_spec = wrap_finder_function(finder.find_spec, wrapped_find_spec)
273285

274286

275287
class MetapathObserver(MutableSequence):

0 commit comments

Comments
 (0)