Skip to content

Commit ec93224

Browse files
authored
Merge pull request #59 from mdickinson/fix/annotation-of-anonymous-function
Fix annotation of anonymous functions.
2 parents 6dec93a + 72e3b6e commit ec93224

2 files changed

Lines changed: 32 additions & 4 deletions

File tree

refcycle/annotations.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,14 +180,21 @@ def object_annotation(obj):
180180
im_class_name = "<None>"
181181
else:
182182
im_class_name = im_class.__name__
183+
184+
try:
185+
func_name = obj.__func__.__name__
186+
except AttributeError:
187+
func_name = "<anonymous>"
183188
return "instancemethod\\n{}.{}".format(
184189
im_class_name,
185-
obj.__func__.__name__,
190+
func_name,
186191
)
187192
else:
188-
return "instancemethod\\n{}".format(
189-
obj.__func__.__qualname__
190-
)
193+
try:
194+
func_name = obj.__func__.__qualname__
195+
except AttributeError:
196+
func_name = "<anonymous>"
197+
return "instancemethod\\n{}".format(func_name)
191198
elif isinstance(obj, list):
192199
return "list[{}]".format(len(obj))
193200
elif isinstance(obj, tuple):

refcycle/test/test_annotations.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
import ctypes
1415
import gc
1516
import inspect
1617
import sys
@@ -315,6 +316,26 @@ def my_method(self):
315316
"instancemethod\\n<None>.my_method",
316317
)
317318

319+
def test_annotate_instancemethod_with_nameless_function(self):
320+
# Regression test for mdickinson/refcycle#25.
321+
322+
# Create a nameless function: comparison_function.__name__
323+
# raise AttributeError.
324+
comparison_function_type = ctypes.CFUNCTYPE(
325+
ctypes.c_int,
326+
ctypes.POINTER(ctypes.c_int),
327+
ctypes.POINTER(ctypes.c_int),
328+
)
329+
comparison_function = comparison_function_type(lambda a, b: 0)
330+
331+
method = types.MethodType(comparison_function, NewStyle())
332+
if six.PY2:
333+
expected = "instancemethod\\n<None>.<anonymous>"
334+
else:
335+
expected = "instancemethod\\n<anonymous>"
336+
337+
self.assertEqual(object_annotation(method), expected)
338+
318339
def test_annotate_weakref(self):
319340
a = set()
320341
ref = weakref.ref(a)

0 commit comments

Comments
 (0)