Re: sane.py return incorrect value for options with same name as scanDev attribute

Anders Blomdell <[email protected]> Thu, 13 Sep 2012 13:19:09 +0200
Newsgroups gmane.comp.python.image
Message-ID <[email protected]>
On 2012-09-12 19:06, Anders Blomdell wrote:
> sane.py return incorrect value for options with same name as scanDev
> attribute (found while trying to get the value for the 'scan' button on
> a Canon Lide 110 scanner).
>
> A simple patch is provided, but IMHO the sane.py module could do with
> some cleaning up (how about making it more object oriented...)?
>
>
> --- sane.py 2012-09-12 18:44:41.279360763 +0200
> +++ Imaging-1.1.7/Sane/sane.py 2009-11-01 01:44:12.000000000 +0100
> @@ -70,7 +70,7 @@
> settable = 'no'
> if self.is_active():
> active = 'yes'
> - curValue = repr(self.scanDev.__getattr__(self.py_name))
> + curValue = repr(getattr(self.scanDev, self.py_name))
> else:
> active = 'no'
> curValue = '<not available, inactive option>'

Attached is a non-reversed diff, fixing some more calls, and making 
'open' and 'get_devices' automatically calling '_sane.init'.




-- 
Anders Blomdell                  Email: [email protected]
Department of Automatic Control
Lund University                  Phone:    +46 46 222 4625
P.O. Box 118                     Fax:      +46 46 138118
SE-221 00 Lund, Sweden

_______________________________________________
Image-SIG maillist  -  [email protected]
http://mail.python.org/mailman/listinfo/image-sig
sane.diff (text/x-patch, 2.2 KB)
--- Imaging-1.1.7/Sane/sane.py	2009-11-01 01:44:12.000000000 +0100
+++ sane.py	2012-09-13 13:00:18.053080537 +0200
@@ -11,7 +11,10 @@
 from PIL import Image
 
 import _sane
-from _sane import *
+for n in filter(lambda s:s.isupper(), dir(_sane)):
+    # Import all uppercase names from _sane
+    globals()[n] = getattr(_sane, n)
+
 
 TYPE_STR = { TYPE_BOOL:   "TYPE_BOOL",   TYPE_INT:    "TYPE_INT",
              TYPE_FIXED:  "TYPE_FIXED",  TYPE_STRING: "TYPE_STRING",
@@ -61,8 +64,16 @@
 
     def is_active(self):
         return _sane.OPTION_IS_ACTIVE(self.cap)
+
     def is_settable(self):
         return _sane.OPTION_IS_SETTABLE(self.cap)
+
+    def get_value(self):
+        try:
+            return self.scanDev.__getattr__(self.py_name)
+        except AttributeError:
+            return None
+
     def __repr__(self):
         if self.is_settable():
             settable = 'yes'
@@ -70,7 +81,10 @@
             settable = 'no'
         if self.is_active():
             active = 'yes'
-            curValue = repr(getattr(self.scanDev, self.py_name))
+            try:
+                curValue = repr(self.scanDev.__getattr__(self.py_name))
+            except AttributeError, e:
+                curValue = '<%s>' % e.message
         else:
             active = 'no'
             curValue = '<not available, inactive option>'
@@ -277,13 +291,40 @@
 
     def fileno(self):
         "Return the file descriptor for the scanning device"
-        return self.dev.fileno()
+        return  self.__dict__['dev'].fileno()
 
     def close(self):
-        self.dev.close()
+        return  self.__dict__['dev'].close()
+
+#
+# Class to handle init and exit
+#
+class INIT_EXIT:
+    def __init__(self):
+        self.inited = None
+        pass
+
+    def init(self):
+        if self.inited == None:
+            self.inited = _sane.init()
+            pass
+        return self.inited
+
+    def exit(self):
+        if self.inited != None:
+            self.inited = None
+            _sane.exit()
+            pass
+        pass
 
+init, exit = (lambda i: (i.init, i.exit))(INIT_EXIT())
 
 def open(devname):
     "Open a device for scanning"
+    init()
     new=SaneDev(devname)
     return new
+
+def get_devices():
+    init()
+    return _sane.get_devices()