Open tpilz opened 2 years ago
This usually happens with an interactive interpreter. The following works for me in Bash on Linux with compiled 8.3 from main (it should be the same in 8.2):
PYTHONPATH="$(grass --config python_path):$PYTHONPATH" LD_LIBRARY_PATH="$(grass --config path)/lib:$LD_LIBRARY_PATH" python
Python 3.8.10 (default, Jun 22 2022, 20:18:18)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import grass.script.setup as gsetup
>>> session = gsetup.init("~/grassdata/nc_spm_08_grass7/user1/")
>>> session.finish()
However, doing some computation and not storing it in the variable breaks things:
>>> "a" * 3 # Anything which stores a result.
'aaa'
>>> session = gsetup.init("~/grassdata/nc_spm_08_grass7/user1/")
>>> session.finish()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../dist.x86_64-pc-linux-gnu/etc/python/grass/script/setup.py", line 416, in finish
finish(start_time=self._start_time)
File ".../dist.x86_64-pc-linux-gnu/etc/python/grass/script/setup.py", line 501, in finish
clean_temp()
File ".../dist.x86_64-pc-linux-gnu/etc/python/grass/script/setup.py", line 477, in clean_temp
gs.verbose(_("Cleaning up temporary files..."))
TypeError: 'str' object is not callable
>>> session = gsetup.init("~/grassdata/nc_spm_08_grass7/user1/")
>>> 42 # Anything which stores a result.
42
>>> session.finish()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../dist.x86_64-pc-linux-gnu/etc/python/grass/script/setup.py", line 416, in finish
finish(start_time=self._start_time)
File ".../dist.x86_64-pc-linux-gnu/etc/python/grass/script/setup.py", line 501, in finish
clean_temp()
File ".../dist.x86_64-pc-linux-gnu/etc/python/grass/script/setup.py", line 477, in clean_temp
gs.verbose(_("Cleaning up temporary files..."))
TypeError: 'int' object is not callable
Not using an interactive session should resolve the problem. The workaround for an interactive session is to restart it and always assign things to variables. This works:
>>> a = 42 # Doing computation, but storing the result in a variable.
>>> import grass.script.setup as gsetup
>>> session = gsetup.init("~/grassdata/nc_spm_08_grass7/user1/")
>>> session.finish()
What happens is that interactive Python interpreter stores (automatically assigns) the last not assigned result to a variable called _
:
>>> a = 42 # Standard assignment
>>> _ # This fails, there is no such variable.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '_' is not defined
>>> 42 # No explicit assignment
42
>>> _ # This variable now exists.
42
Underscore is also name used for the translation function in GRASS GIS and that function is added globally as an additional build-in which then conflicts with the assignment done by the interactive interpreter.
The ultimate fix in GRASS GIS is to explicitly import the translation function where it is needed instead of adding a build-in.
Thanks for the explanation and workaround!
I was actually using and initialising GRASS inside a python module and got the error when using that. Can't tell which other side-effects then might have caused the interference with the _
variable.
Anyway, my small workaround is sufficient now and it seems it is even not too complicated to fix it in GRASS.
...which other side-effects then might have caused the interference with the
_
variable.
doctest are using _
and definitively interfere too, although there is a workaround for that too, search for "doctest workaround" in GRASS GIS source code. Running your code through an execute function in an IDE may run run it in an interactive console, too.
...it seems it is even not too complicated to fix it in GRASS.
Yes, there is a lot of other pieces in place making the change easier than it was in the past (one place for initialization, lazy loading, code checks). I would be happy to review a PR for this.
Describe the bug
I want to use GRASS in a python module but get some errors when using certain functions of the
grass.script.setup
module.To Reproduce
Connect to a grass mapset in python as described in the docs, e.g.
System description (please complete the following information):
Tested on two Linux systems with GRASS 7.8 and GRASS 8.2 using python 3.6.2 and 3.9.10, respectively.
Additional context
Error is caused by
gcore.message(_("<message>"))
calls insetup.py
. I think #551 is related where the issue was discussed but never really solved.For the time being a workaround works for my case with
gutils.try_remove(os.environ["GISRC"])
which is basically what I need here.