question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`getattr(pyvips.Image, anything)` returns `True` when it should raise `AttributeError`

See original GitHub issue

I’m working on making it more convenient to work with pyvips images with numpy. Numpy offers a way for foreign objects to be interpreted as arrays: a class need only define the __array__ method, whereupon np.array(im) will call this. This is how Pillow does it, for example.

The problem is that if I define this __array__ method on pyvips.Image, it never gets called because numpy has some complex behavior where it looks for the most efficient ways to turn something into an array (without copying, e.g.), so it first looks up __array_struct__ to attempt C-struct access and then falls back to trying other things (see The Array Interface). Ok, no problem except that the way pyvips is setup, when numpy goes looking for __array_struct__, it can’t see that it doesn’t exist because of this behavior:

import pyvips
print(hasattr(pyvips.Image, 'doesntexist'))
# True  # (wat)

So I guess somehow due to the way it interfaces with libvips, pyvips is deferring method resolution until it’s actually called, but by then it’s too late for numpy to figure out that it should have used __array__ instead.

im = pyvips.Image.black(4, 4)
ai = im.__array_interface__  #  The bug is here.  Should raise AttributeError immediately but doesn't.
print('Ready to call')
ai() # the **call** is what raises, but not AttributeError

#  Ready to call
#  Error: no such operation __array_interface__
#   VipsOperation: class "__array_interface__" not found

I think this is a bug insofar as it violates the usual semantics of how to deal with presence of methods, etc. As the Python documentation says, hasattr

… is implemented by calling getattr(object, name) and seeing whether it raises an AttributeError or not.

If you have any ideas on how to fix this, I’m happy to give it a try, though the various ways that pyvips interfaces with libvips is sort of “here be dragons” territory for me so I doubt I’d be very useful.

Thanks in advance!

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
jcupittcommented, Mar 26, 2022

Yes, that sounds extremely useful!

I added toarray() a short while ago, but it’s terrible. A better toarray() method would be great too.

0reactions
erdmanncommented, Apr 5, 2022

Ok, #316 adds functionality to go to/from numpy and array-like things, and also provides an efficient implementation of what is now called .tolist() to turn single-band images of any type into lists of lists. Thanks for the help in getting this in!

Read more comments on GitHub >

github_iconTop Results From Across the Web

pyvips/vimage.py at master · libvips/pyvips - GitHub
first serious error in the image. By default, libvips will. attempt to read everything it can from a damaged image. Returns: A new...
Read more >
Source code for pyvips.vimage
By default, libvips will attempt to read everything it can from a damaged image. Returns: A new :class:`.Image`. Raises: :class:`.
Read more >
Python: Why is __getattr__ catching AttributeErrors?
I just changed the code to class A(object): @property def a(self): print "trying property..." raise AttributeError('lala') def __getattr__(self, ...
Read more >
Problem related to .tif and .scn while extracting images from ...
Hi, I have downloaded some trestle .tif and .scn images from here ... line 93, in __getattr__ raise AttributeError() AttributeError python- ...
Read more >
Issue 8722: Documentation for __getattr__ - Python tracker
1 I'm thinking something along the lines of: If the attribute search encounters an AttributeError (perhaps due to a @property raising the error) ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found