Python - how to call function from another py file?

I can’t figure out how to separate my python macros into different files/modules. What I am trying to do is:

Have a LibreOffice button call: foo() and be able to call a function from another file (in the same directory)

foo.py → foo.py$foo (user, Python)

from bar import bar
def foo():
    bar()

bar.py

def bar():
    print("Why does this not work?")

I keep getting different variations of:
Message: <class ‘ImportError’>: No module named ‘bar’
Message: <class ‘ImportError’>: attempted relative import with no known parent package (or ‘.bar’ is unknown)

What I have tried:
(They are in the same directory for all of these)

  • have the files in ~/.config/libreoffice/4/user/Scripts/python/
  • have the files in /opt/libreoffice6.1/share/Scripts/python/
  • All different types of from * import
  • add empty _init_.py
  • make bar a class and import it as and object

Full error I am getting:
File “/opt/libreoffice6.1/program/pythonscript.py”, line 1021, in getScript
mod = self.provCtx.getModuleByUrl( fileUri )
File “/opt/libreoffice6.1/program/pythonscript.py”, line 458, in getModuleByUrl
exec(code, entry.module._dict_)
File “~/.config/libreoffice/4/user/Scripts/python/foo.py”, line 19, in
from . import bar
File “/opt/libreoffice6.1/program/uno.py”, line 425, in _uno_import
raise uno_import_exc
File “/opt/libreoffice6.1/program/uno.py”, line 347, in _uno_import
return _builtin_import(name, *optargs, **kwargs)

Hello,

You could add these lines:

import sys
sys.path.append("/home/YOUR_DIRECTORY/.config/libreoffice/4/user/Scripts/python")

before your ‘bar’ import (note this is a Linux directory) but the proper method is to add to pythonpath. See answer ( and links) in this answer → import from second, embedded in document, python module

Your test seems to be from a button on a calc sheet. If so, foo needs *args as an argument. Also in bar, the print will be to the console only.

This may be a better test for you:

foo.py

from bar import bar
def foo(*args):
    oDoc = XSCRIPTCONTEXT.getDocument()
    oSheet = oDoc.CurrentController.ActiveSheet
    oCell = oSheet.getCellRangeByName('B1')
    oCell.setString("Hello There!")
    oCell = oSheet.getCellRangeByName('B2')
    oCell.setString(str(bar()))

bar.py

def bar():
    my_str = "Hello Back 2 U!"
    return my_str

This will place text in cells B1 & B2 of the current sheet.

Worked like a charm. Thanks as always

It does not work when adding new functions to another file (bar) unless restarted. I’m assuming this is because the script is read at boot up so the import only takes the current functions. Is there any way to get the calc file to re-import other files/functions? reload() does not work

@UserRyan Don’t recall off-hand a workaround for that issue. However, if you are going to be doing a lot of interactive testing, take a look at this post → Christopher Bourez’s blog
.