Skip to content

Fix callable detection to support functools.partial and all callable objects#3121

Merged
davisking merged 3 commits into
davisking:masterfrom
ssam18:fix-callable-detection-issue-2008
Nov 22, 2025
Merged

Fix callable detection to support functools.partial and all callable objects#3121
davisking merged 3 commits into
davisking:masterfrom
ssam18:fix-callable-detection-issue-2008

Conversation

@ssam18

@ssam18 ssam18 commented Nov 14, 2025

Copy link
Copy Markdown
Contributor

Fixes #2008

Problem

The find_max_global and find_min_global functions failed with an AttributeError when used with functools.partial objects and other callable objects that don't have a __code__ attribute.

Example of the issue:

from functools import partial
import dlib

def f(arg0):
    return 0

# This would fail with: AttributeError: 'functools.partial' object has no attribute '__code__'
dlib.find_max_global(partial(f, 2), [0.], [1.], 100)

Solution

Changed the num_function_arguments function to use Python's inspect.signature() which properly works with all callable objects:

  • Regular functions
  • Lambda functions
  • functools.partial objects
  • Class methods
  • Any object with a __call__ method

The implementation includes a fallback to the original __code__ method for backward compatibility if inspect.signature() fails for any reason.

Testing

I've included a test script (test_callable_fix.py) that verifies the fix works with:

  • functools.partial objects
  • Regular functions
  • Lambda functions

Let me know if you'd like me to add any additional tests or make any changes

…tial, etc)

Fixes davisking#2008

The old implementation checked for __code__ attribute directly, which
doesn't exist for callable objects like functools.partial. This caused
an AttributeError when trying to use such objects with find_max_global
and find_min_global functions.

Changed to use Python's inspect.signature() which properly handles all
callable objects including:
- Regular functions
- Lambda functions
- functools.partial objects
- Class methods
- Any object with __call__ method

The fix includes a fallback to the old __code__ method for backward
compatibility in case inspect.signature fails for any reason.
@ssam18

ssam18 commented Nov 14, 2025

Copy link
Copy Markdown
Contributor Author

I ran into this issue while using dlib for optimization in one of my projects. I was trying to use functools.partial to partially apply some parameters to my objective function before passing it to find_max_global, and kept getting the AttributeError about the missing __code__ attribute.

After digging into the source code, I realized the issue was with how callable detection was implemented. Since inspect.signature() is the standard way to introspect callable objects in Python and works with all types of callables, I figured this would be a good fix that maintains backward compatibility.

Hope this helps others who might run into the same issue

…elf, since parameters is a dictionary-like object. The earlier code tried to access .second on the iterator, which isn’t valid when working with dict values

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>
The previous code was counting VAR_POSITIONAL (*args) and VAR_KEYWORD
(**kwargs) parameters in the total count, which caused functions like
'lambda a, b, c, *args' to be counted as having 4 parameters instead
of 3. Now only regular parameters are counted, while still checking
for the presence of *args to allow variable argument functions.

Also removed test_callable_fix.py as it was causing pytest errors.

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>
@davisking davisking merged commit 23d73be into davisking:master Nov 22, 2025
9 checks passed
@davisking

Copy link
Copy Markdown
Owner

Nice, thanks for the PR :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Don't use __code__ to detect Python callable object

2 participants