RSS/Atom feed Twitter
Site is read-only, email is disabled

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

This discussion is connected to the gimp-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.

This is a read-only list on gimpusers.com so this discussion thread is read-only, too.

lloyd konneker
2010-02-27 20:35:22 UTC (about 15 years ago)

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

This is an enhancement request. Repeated calls to gimp_env_init should yield warnings and not fatal errors. It has benefits for gimp plugins written in Python.

Currently gimp_env_init() calls g_error (fatal) if called a second time. Instead, pygimp_main(), which calls gimp_env_init(), should check whether this is a repeated call and issue a warning then return an error. (I'm not sure if any changes are needed for ScriptFu, whether Pygimp should check the return from gimp_main and raise a warning exception, etc.)

Currently, you can't import a plugin from another plugin unless the imported plugin guards the call to main() to prevent it from being called unless this is a top level invocation:

if __name__=='__main__': main()

It could be sufficient to have a convention for plugins to guard the call to main(), but the convention is not usually followed. Or you could have a convention that any shared code needs to be in a separate module from the top plugin module, but again, that convention is not often followed.

If you could import a plugin from within a Gimp plugin, then you could share more code. You could use classes etc. from imported plugins. You could also invoke the imported plugin's top function without invoking it as a registered PDB procedure. Neither reason is compelling.

I am not that familiar with the gimp source. I am guessing that gimp_main() can't be called twice to avoid redundant io channels, and that gimp_env_init() is doing the guarding. But does it need to be fatal, is there any real harm done if they return a warning to the caller? Apparently not. I built a version of gimp in which gimp_main returned a warning on second invocations. It didn't seem to hurt gimp.

Context: I was exploring whether you could use pydoc to document plugins. I tried to invoke the python pydoc module on a plugin from within another plugin, an 'inspector' plugin. Pydoc imports a module and introspectively documents it using the python inspect module. It fails to import (fatal error: gimp_env_init must only be called once) unless the call to main() is guarded. This enhancement fixes that problem. (You can't typically invoke pydoc as a command from the shell on a plugin because the shell environment typically does not include the path to the gimpfu module.) Documentation produced by pydoc might be of marginal use, and then only to programmers, and sometimes only if the plugin writer has provided docstrings, self documentation in the code.

Sven Neumann
2010-02-28 11:23:57 UTC (about 15 years ago)

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

On Sat, 2010-02-27 at 14:35 -0500, lloyd konneker wrote:

This is an enhancement request. Repeated calls to gimp_env_init should yield warnings and not fatal errors. It has benefits for gimp plugins written in Python.

Currently gimp_env_init() calls g_error (fatal) if called a second time. Instead, pygimp_main(), which calls gimp_env_init(), should check whether this is a repeated call and issue a warning then return an error. (I'm not sure if any changes are needed for ScriptFu, whether Pygimp should check the return from gimp_main and raise a warning exception, etc.)

We would definitely have to change gimp_main() then as it must not be called more than once. I have a bad feeling about doing this change.

Currently, you can't import a plugin from another plugin unless the imported plugin guards the call to main() to prevent it from being called unless this is a top level invocation:

if __name__=='__main__': main()

It could be sufficient to have a convention for plugins to guard the call to main(), but the convention is not usually followed. Or you could have a convention that any shared code needs to be in a separate module from the top plugin module, but again, that convention is not often followed.

If you could import a plugin from within a Gimp plugin, then you could share more code. You could use classes etc. from imported plugins. You could also invoke the imported plugin's top function without invoking it as a registered PDB procedure. Neither reason is compelling.

Importing a plug-in from within a GIMP plug-in only makes sense for Python. So I would suggest that we seek for a solution that only involves changes to the GIMP Python bindings but does not require a change to libgimp or libgimpbase. I haven't looked at the code, but it should be possible to deal with this in pygimp_main().

Sven

lloyd konneker
2010-02-28 15:43:43 UTC (about 15 years ago)

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

On Sun, 2010-02-28 at 11:23 +0100, Sven Neumann wrote:

On Sat, 2010-02-27 at 14:35 -0500, lloyd konneker wrote:

This is an enhancement request. Repeated calls to gimp_env_init should yield warnings and not fatal errors. It has benefits for gimp plugins written in Python.

Currently gimp_env_init() calls g_error (fatal) if called a second time. Instead, pygimp_main(), which calls gimp_env_init(), should check whether this is a repeated call and issue a warning then return an error. (I'm not sure if any changes are needed for ScriptFu, whether Pygimp should check the return from gimp_main and raise a warning exception, etc.)

We would definitely have to change gimp_main() then as it must not be called more than once. I have a bad feeling about doing this change.

Currently, you can't import a plugin from another plugin unless the imported plugin guards the call to main() to prevent it from being called unless this is a top level invocation:

if __name__=='__main__': main()

It could be sufficient to have a convention for plugins to guard the call to main(), but the convention is not usually followed. Or you could have a convention that any shared code needs to be in a separate module from the top plugin module, but again, that convention is not often followed.

If you could import a plugin from within a Gimp plugin, then you could share more code. You could use classes etc. from imported plugins. You could also invoke the imported plugin's top function without invoking it as a registered PDB procedure. Neither reason is compelling.

Importing a plug-in from within a GIMP plug-in only makes sense for Python. So I would suggest that we seek for a solution that only involves changes to the GIMP Python bindings but does not require a change to libgimp or libgimpbase. I haven't looked at the code, but it should be possible to deal with this in pygimp_main().

Sven

That seems reasonable.

Here is proposed addition for plug-ins/gimpmodule.c in pygimp_main() that I have lightly tested. Note it raises a warning (Python prints warning on stderr once, on the second call), not an exception. Note it compiles with a C90 warning about mixing declarations and code.

if (query == Py_None) { PyErr_SetString(pygimp_error, "a query procedure must be provided");
return NULL;
}

/* lkk 2010 begin enhancement*/
static int was_called_previously = 0;
if (was_called_previously) {
PyErr_WarnEx(PyExc_RuntimeWarning, "main() should only be called once", 1);
Py_INCREF(Py_None);
return Py_None;
}
else {
/* OK to set this here since following code either succeeds in initializing plugin, or fails hard. */ was_called_previously = 1;
}
/* lkk 2010 end enhancement*/

Omari Stephens
2010-02-28 18:18:05 UTC (about 15 years ago)

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

On 02/28/2010 02:43 PM, lloyd konneker wrote: ::snip? SNIP!::

Here is proposed addition for plug-ins/gimpmodule.c in pygimp_main() that I have lightly tested. Note it raises a warning (Python prints warning on stderr once, on the second call), not an exception. Note it compiles with a C90 warning about mixing declarations and code.

Just move the variable declaration to the top of the function. We should strive to make the codebase compile with as few meaningful warnings as possible.

Also, is that proper code style?

--xsdg

if (query == Py_None) {
PyErr_SetString(pygimp_error, "a query procedure must be provided");
return NULL;
}

/* lkk 2010 begin enhancement*/ static int was_called_previously = 0;

if (was_called_previously) { PyErr_WarnEx(PyExc_RuntimeWarning, "main() should only be called once", 1);
Py_INCREF(Py_None);
return Py_None;
}
else {
/* OK to set this here since following code either succeeds in initializing plugin, or fails hard. */ was_called_previously = 1;
}
/* lkk 2010 end enhancement*/

Sven Neumann
2010-03-02 08:49:03 UTC (about 15 years ago)

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

On Sun, 2010-02-28 at 17:18 +0000, Omari Stephens wrote:

On 02/28/2010 02:43 PM, lloyd konneker wrote: ::snip? SNIP!::

Here is proposed addition for plug-ins/gimpmodule.c in pygimp_main() that I have lightly tested. Note it raises a warning (Python prints warning on stderr once, on the second call), not an exception. Note it compiles with a C90 warning about mixing declarations and code.

Just move the variable declaration to the top of the function. We should strive to make the codebase compile with as few meaningful warnings as possible.

Also, is that proper code style?

No, it isn't. First of all, a gboolean should be used instead of an int and the code should use the macros TRUE and FALSE. And of course it should follow the GIMP coding style guidelines. We can certainly adjust the few lines ourselves. But it would make our life easier if you could submit a proper patch.

Thanks, Sven

lloyd konneker
2010-03-02 14:01:56 UTC (about 15 years ago)

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

Yes, I will submit a proper patch. I'm new but I can figure it out.

I mainly wanted to get feedback whether it was desirable. I'm not clear when a discussion of an enhancement should move to Bugzilla.

More testing reveals other issues and test cases:

First, most plugins have unguarded calls to register(), so importing some plugins from a plugin ends up reregistering a plugin, with a warning to stderr from the Gimp PDB but apparently harmlessly. I'm still exploring, eg whether the order in which plugins are loaded matters, whether the warning is only for local plugins, whether Gimp supports multiple registrations of different plugins from the same Python source, etc.

Second, what paths to plugins are set when a plugin is invoked? Apparently only to local plugins, and not to plugins distributed with Gimp. So to import a distributed plugin from any plugin requires the importing plugin to extend the path. Not difficult but annoying.

On Tue, 2010-03-02 at 08:49 +0100, Sven Neumann wrote:

On Sun, 2010-02-28 at 17:18 +0000, Omari Stephens wrote:

On 02/28/2010 02:43 PM, lloyd konneker wrote: ::snip? SNIP!::

Here is proposed addition for plug-ins/gimpmodule.c in pygimp_main() that I have lightly tested. Note it raises a warning (Python prints warning on stderr once, on the second call), not an exception. Note it compiles with a C90 warning about mixing declarations and code.

Just move the variable declaration to the top of the function. We should strive to make the codebase compile with as few meaningful warnings as possible.

Also, is that proper code style?

No, it isn't. First of all, a gboolean should be used instead of an int and the code should use the macros TRUE and FALSE. And of course it should follow the GIMP coding style guidelines. We can certainly adjust the few lines ourselves. But it would make our life easier if you could submit a proper patch.

Thanks, Sven

Sven Neumann
2010-03-02 18:58:37 UTC (about 15 years ago)

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

On Tue, 2010-03-02 at 08:01 -0500, lloyd konneker wrote:

Yes, I will submit a proper patch. I'm new but I can figure it out.

I mainly wanted to get feedback whether it was desirable. I'm not clear when a discussion of an enhancement should move to Bugzilla.

More testing reveals other issues and test cases:

First, most plugins have unguarded calls to register(), so importing some plugins from a plugin ends up reregistering a plugin, with a warning to stderr from the Gimp PDB but apparently harmlessly. I'm still exploring, eg whether the order in which plugins are loaded matters, whether the warning is only for local plugins, whether Gimp supports multiple registrations of different plugins from the same Python source, etc.

I wonder if importing a plug-in from another plug-in is really something that we want to support. If the goal is to share code, then perhaps the code that is worth sharing should be factored out into a Python module that the plug-ins can import.

Sven

Joao S. O. Bueno
2010-03-03 12:46:13 UTC (about 15 years ago)

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

On Tue, Mar 2, 2010 at 2:58 PM, Sven Neumann wrote:

On Tue, 2010-03-02 at 08:01 -0500, lloyd konneker wrote:

Yes, I will submit a proper patch.  I'm new but I can figure it out.

I mainly wanted to get feedback whether it was desirable.  I'm not clear when a discussion of an enhancement should move to Bugzilla.

More testing reveals other issues and test cases:

First, most plugins have unguarded calls to register(), so importing some plugins from a plugin ends up reregistering a plugin, with a warning to stderr from the Gimp PDB but apparently harmlessly.  I'm still exploring, eg whether the order in which plugins are loaded matters, whether the warning is only for local plugins, whether Gimp supports multiple registrations of different plugins from the same Python source, etc.

I wonder if importing a plug-in from another plug-in is really something that we want to support. If the goal is to share code, then perhaps the code that is worth sharing should be factored out into a Python module that the plug-ins can import.

Every Python program is also able to be a python module that plug-ins can import. We should preserve this feature of the language.

(For example, one can implement an app with a comand line interface, and then just add a GUI in another file that uses the functions defined on the stand-alone first file).

Sven

__________

Sven Neumann
2010-03-03 13:07:12 UTC (about 15 years ago)

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

On Wed, 2010-03-03 at 08:46 -0300, Joao S. O. Bueno wrote:

I wonder if importing a plug-in from another plug-in is really something that we want to support. If the goal is to share code, then perhaps the code that is worth sharing should be factored out into a Python module that the plug-ins can import.

Every Python program is also able to be a python module that plug-ins can import. We should preserve this feature of the language.

What exactly does that statement mean for the problem at hand?

Sven

Joao S. O. Bueno
2010-03-03 13:42:57 UTC (about 15 years ago)

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

On Wed, Mar 3, 2010 at 9:07 AM, Sven Neumann wrote:

On Wed, 2010-03-03 at 08:46 -0300, Joao S. O. Bueno wrote:

I wonder if importing a plug-in from another plug-in is really something that we want to support. If the goal is to share code, then perhaps the code that is worth sharing should be factored out into a Python module that the plug-ins can import.

Every Python program is also able to be a python module that plug-ins can import. We should preserve this feature of the language.

What exactly does that statement mean for the problem at hand?

Means that the language has a feature to make development easier: that is it eases up reuse of the code by requiring less source code fiels to achieve the same tasks.

So - it is not usual for a Python developer to be required do factor out a fully working source code file, that can be used as a stand alone piece, in order to re-use parts of the code in that file in other applications. The language has a trivial, elegant and seamless mechanism to allow this.

The "problem at hand" as I see is exactly to preserve this Python language feature in GIMP plug-ins.

On the other hand, simply putting a python module that is not a fully functional plug-in in GIMP's plug-ins directory, would cause GIMP to issue error messages on start-up , due to failed plug-in initialization. All GIMP will see is an executable ".py" file along with the plug-ins.

Having to provide a directory structure, hacking with import paths, etc...just because one wants to share, say a couple RGBHSV functions in a set of 2 or 3 plug-ins is overkill.

js ->

Sven

David Gowers
2010-03-03 14:20:27 UTC (about 15 years ago)

enhancement: warnings instead of fatal error for duplicate calls to gimp_env_init

On Wed, Mar 3, 2010 at 10:16 PM, Joao S. O. Bueno wrote:

On Tue, Mar 2, 2010 at 2:58 PM, Sven Neumann wrote:

On Tue, 2010-03-02 at 08:01 -0500, lloyd konneker wrote:

I wonder if importing a plug-in from another plug-in is really something that we want to support. If the goal is to share code, then perhaps the code that is worth sharing should be factored out into a Python module that the plug-ins can import.

Every Python program is also able to be a python module that plug-ins can import. We should preserve this feature of the language.

(For example, one can implement an app with a comand line interface, and then just add a GUI in another file that uses the functions defined on the stand-alone first file).

I've considered this problem a fair bit, and my opinion is that if you want this functionality, you should simply guard your register()s. We cannot safely 'co-opt' python plugins that are not written with this functionality in mind, as they are designed to be run always in an independent process (hence they may do initialization which confuses the calling program, or vice versa); there is no modification to GIMP which could permit that, it is a logistical problem not a technical one.

Allowing python plugins to make separate modules available on installation, similar to Sven's suggestion, seems to me the most practical suggestion. This means we would add two items to sys.path -- one the site modules* directory, and the other the modules* directory belonging to the specific user, which the installation of the plugin package could put modules into.

We could further postulate that the normal python modules directory should be the destination of modules that do not require GIMP running in order to function, and only GIMP-requiring modules would be installed in it's modules* directory. I make this distinction because there are various good reasons not to install gimp-dependent modules in the global namespace (for example, pydoc and the general help() facility get confused because the imports of gimp modules fail.. so you can look up a specific module, but not search.)

* I realize 'modules' is a term already used in the gimp directory structure. This is meant as a placeholder for something else...python-modules?