← Back to team overview

sikuli-driver team mailing list archive

Re: [Question #210973]: Sikuli code organization / code reuse

 

Question #210973 on Sikuli changed:
https://answers.launchpad.net/sikuli/+question/210973

    Status: Answered => Open

David is still having a problem:
I sat down this evening and did a fresh install of Sikuli
X-1.0rc3(r905), Python 3.3, and Java 6.0.310 (x86). I tested out various
methods of importing. Here's my results. This suggests that the only way
to do a correct import is to use the "from module import *" method, and
that other methods fail. Furthermore, this does NOT create namespace
conflicts.

Project Structure:
C:\Users\User\Documents\
C:\Users\User\Documents\sub.sikuli
C:\Users\User\Documents\test.sikuli

sub.sikuli
--------
from sikuli import *
class sub:
    def doSomething(self):
        popup("it worked")

Test #1: Can we import from the same directory with a straight import?
Result #1: Yes, but this does not allow us to instantiate Python objects correctly.

test.sikuli
-------
import sub

if __name__ == '__main__':
    sub().doSomething()  #TypeError: 'module' object is not callable


Test #2: Can we import from the same directory using from?
Result #2: Yes, and it works.

test.sikuli
-------
from sub import *

if __name__ == '__main__':
    sub().doSomething()  #It works

Test #3: Can we import using from and call doSomething() directly?
Result #3: No.

test.sikuli
-------
import sub

if __name__ == '__main__':
    doSomething()   #NameError: name 'doSomething' is not defined

Test #4: Will importing multiple modules cause namespace conflicts if we have multiple doSomething() methods?
Result #4: No namespace conflicts will occur. The local call will always prefer either the local module. If the method does not exist there, it will use the last imported module's method. (This is expected Python behavior.)

sub.sikuli
-------
from sikuli import *

def doSomething():
     popup("this is sub")

class sub:
    def doSomething(self):
        popup("this is sub class")

hub.sikuli
-------
from sikuli import *

def doSomething():
     popup("this is hub")

class hub:
    def doSomething(self):
        popup("this is hub class")

test.sikuli
-------
import sub
import hub

def doSomething():
     popup("this is test")

class test:
    def doSomething(self):
        popup("this is test class")

if __name__ == '__main__':
    sub().doSomething()  #this is sub class
    hub().doSomething() #this is hub class
    sub().doSomething() #this is sub class
    s = sub()
    h = hub()
    s.doSomething() #this is sub class
    h.doSomething() #this is hub class
    t = test()
    t.doSomething() #this is test class
    doSomething()  #this is test
    #if test.sikuli did not have doSomething()
    doSomething() #this is hub


This suggests a few things:
#1: Sikuli's automatic import using the form "import module" is broken because it does not allow you to use Python objects correctly.
#2: Using the form "from module import *" works just fine, without namespace conflicts. Namespaces resolve as expected in Python.
#3: There only good way to create a sikuli project is a flat structure. It might make sense to use Python's package management instead as J suggested. I've yet to experiment with this, but it sounds promising because it side-steps Sikuli's odd importing.
--------------------------------------------
If you don't store your images in the submodules you could get rid of the .sikuli directories and store everything in a python module structure like this:

parent/
parent/module1/
parent/module1/__init__.py
parent/module1/submodule1.py
parent/module1/submodule2/__init__.py

Then you only need to add
sys.path.append(path/to/parent)
because python scans the underlying package structure itself.

The problem ist, you then need to explicitly specify your image
locations because sikuli will not search in those subdirectories and you
have to add the "from sikuli import*" to every python file to use the
Sikuli features, but everything else should work.

-- 
You received this question notification because you are a member of
Sikuli Drivers, which is an answer contact for Sikuli.