8000 varLib.interpolatable --json with scipy installed: Object of type int64 is not JSON serializable · Issue #3522 · fonttools/fonttools · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

varLib.interpolatable --json with scipy installed: Object of type int64 is not JSON serializable #3522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
PeterDekkers opened this issue May 24, 2024 · 5 comments · Fixed by #3526

Comments

@PeterDekkers
Copy link
Contributor

Hello.

It seems that, the moment I install scipy into my project, varLib.interpolatable starts using it, and then fails outputting JSON with:

TypeError: ('Object of type int64 is not JSON serializable')

To clarify, the above happens when running the following with scipy installed:

fonttools varLib.interpolatable font1.ttf font2.ttf --json

I assume this may be due to some conditional scipy imports? E.g.:

try:
from scipy.optimize import linear_sum_assignment
min_cost_perfect_bipartite_matching = min_cost_perfect_bipartite_matching_scipy
except ImportError:
try:
from munkres import Munkres
min_cost_perfect_bipartite_matching = (
min_cost_perfect_bipartite_matching_munkres
)
except ImportError:
min_cost_perfect_bipartite_matching = (
min_cost_perfect_bipartite_matching_bruteforce
)

# Form a minimum spanning tree of the locations
try:
from scipy.sparse.csgraph import minimum_spanning_tree

Happy to dig deeper, and maybe provide a minimal reproduction, with some guidance on how to best supply that?

Thank you :)

@PeterDekkers
Copy link
Contributor Author
PeterDekkers commented May 24, 2024

I assume that the solution here would be, when scipy is installed, to supply a custom JSON encoder that can handle numpy types?

So here:

print(json.dumps(problems), file=f)

You could do something like...

json_encoder = None
try:
    import scipy
    import numpy

    class NumpyEncoder(json.JSONEncoder):
        def default(self, obj):
            if isinstance(obj, numpy.integer):
                return int(obj)
            if isinstance(obj, numpy.floating):
                return float(obj)
            if isinstance(obj, numpy.ndarray):
                return obj.tolist()
            return super(NumpyEncoder, self).default(obj)
   
    json_encoder = NumpyEncoder
except ImportError:
    pass

print(json.dumps(problems, cls=json_encoder), file=f) 

@PeterDekkers
Copy link
Contributor Author

I can confirm that the above approach resolves the issue. Should I put together a PR?

@behdad
Copy link
Member
behdad commented May 24, 2024

I think we want to convert back to regular Python types or whatever it is that the non-scipy path is using. Thanks for the report!

@behdad
Copy link
Member
behdad commented May 24, 2024

Would be great if you can send a PR with the approach I suggested.

@PeterDekkers
Copy link
Contributor Author

Ah, yes, that would keep all the scipy/numpy code contained to the conditional import blocks. Much tidier. Will set up a PR in the coming days, thank you.

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 a pull request may close this issue.

2 participants
0