A short reproducible example:
import twisted.internet.base
from libcst.codemod import CodemodContext
from libcst.codemod.visitors import AddImportsVisitor, ImportItem
AddImportsVisitor(CodemodContext(), [ImportItem("os")])
This crashes:
Traceback (most recent call last):
File "<python-input-3>", line 1, in <module>
AddImportsVisitor(CodemodContext(), [ImportItem("os", "path", None)])
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".env/lib/python3.13/site-packages/libcst/codemod/visitors/_add_imports.py", line 151, in __init__
super().__init__(context)
~~~~~~~~~~~~~~~~^^^^^^^^^
File ".env/lib/python3.13/site-packages/libcst/codemod/_visitor.py", line 29, in __init__
MatcherDecoratableTransformer.__init__(self)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File ".env/lib/python3.13/site-packages/libcst/matchers/_visitors.py", line 456, in __init__
] = _gather_constructed_visit_funcs(self)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File ".env/lib/python3.13/site-packages/libcst/matchers/_visitors.py", line 314, in _gather_constructed_visit_funcs
possible_func = getattr(obj, funcname)
AttributeError: __provides__
There is various magic in Twisted/zope.interface that leads to some inconsistency about abc.ABC, __provides__ and descriptors that I can't wrap my head around which evidently leads to _gather_constructed_visit_funcs() seeing '__provides__' in dir(obj) but not being able to access it (direct hasattr() there also returns False).
libcst==1.8.6
Twisted==26.4.0
zope.interface==8.5
>>> '__provides__' in dir(AddImportsVisitor)
True
>>> hasattr(AddImportsVisitor, '__provides__')
False
>>> import abc
>>> hasattr(abc.ABC, '__provides__')
True
>>> issubclass(AddImportsVisitor, abc.ABC)
True
A short reproducible example:
This crashes:
There is various magic in Twisted/zope.interface that leads to some inconsistency about
abc.ABC,__provides__and descriptors that I can't wrap my head around which evidently leads to_gather_constructed_visit_funcs()seeing'__provides__'indir(obj)but not being able to access it (directhasattr()there also returnsFalse).