Optional plugin dependency

25 views
Skip to first unread message

Chris Nelson

unread,
Feb 20, 2012, 4:46:04 PM2/20/12
to trac...@googlegroups.com
Can someone point me to an example of where one plugin *may* make use of
another plugin? That is, I want one plugin to use another if it is
present but not to *require* it. It this just putting the `import` in a
`try` or is there a better idiom?

Chris
--
Christopher Nelson, Software Engineering Manager
SIXNET - Solutions for Your Industrial Networking Challenges
331 Ushers Road, Ballston Lake, NY 12019
Tel: +1.518.877.5173, Fax: +1.518.877.8346 www.sixnet.com

Steffen Hoffmann

unread,
Feb 20, 2012, 5:20:36 PM2/20/12
to trac...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Am 20.02.2012 22:46, wrote Chris Nelson:
> Can someone point me to an example of where one plugin *may* make use of
> another plugin? That is, I want one plugin to use another if it is
> present but not to *require* it. It this just putting the `import` in a
> `try` or is there a better idiom?

Seen that in a couple if occasions, i.e. ScreenshotsPlugin implementing
the DefaultTagProvider interface [1], if TagsPlugin is installed. No
conditional import, you'll just miss the whole tracscreenshots.tags
after import failure on plugin load time. Likewise the TracAnnouncer aka
AnnouncerPlugin [2] implementing IAccountChangeListener from
AccountManagerPlugin.

I'm sure, that the try..except ImportError is done a lot more, but
ironically I can't remember an example right-away.

Steffen Hoffmann
(hasienda)


[1]
http://trac-hacks.org/browser/screenshotsplugin/0.12/tracscreenshots/tags.py
[2]
http://trac-hacks.org/browser/announcerplugin/trunk/announcer/opt/acct_mgr/announce.py
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk9CxzIACgkQ31DJeiZFuHdvFACgvVWJBMMHcPDGOsBc6uaSaczF
SPIAn3GkouFW7ibQt6En4ENC/1eRCs6V
=okTk
-----END PGP SIGNATURE-----

osimons

unread,
Feb 20, 2012, 7:00:20 PM2/20/12
to Trac Development
On Feb 20, 10:46 pm, Chris Nelson <Chris.Nel...@SIXNET.com> wrote:
> Can someone point me to an example of where one plugin *may* make use of
> another plugin?  That is, I want one plugin to use another if it is
> present but not to *require* it.  It this just putting the `import` in a
> `try` or is there a better idiom?
>
>                                                  Chris

See for instance setup.py for my FullBlogPlugin that optionally will
support tagsplugin and spamfilterplugin if present. Notice the [tags]
and [spamfilter] markers in entry_points + extras_require conditions.
The conditional entry points will only be declared when extras match:

http://trac-hacks.org/browser/fullblogplugin/0.11/setup.py

You obviously need to structure your code so that the particular
extras code are not loaded when not needed. Like in the example from
my plugin that means that when the entry_point condition isn't
matched, there is nothing else trying to import that particular file.
For my 'tracfullblog/tags.py' for example that means I can just
'import tractags' without having to write try-except handling as
nothing should attempt to load the file unless the dependency is
available.


:::simon

https://www.coderesort.com
http://trac-hacks.org/wiki/osimons

Chris Nelson

unread,
Feb 21, 2012, 8:56:18 AM2/21/12
to trac...@googlegroups.com
On 02/20/2012 07:00 PM, osimons wrote:
> On Feb 20, 10:46 pm, Chris Nelson<Chris.Nel...@SIXNET.com> wrote:
>> Can someone point me to an example of where one plugin *may* make use of
>> another plugin? That is, I want one plugin to use another if it is
>> present but not to *require* it. It this just putting the `import` in a
>> `try` or is there a better idiom?
>
> See for instance setup.py for my FullBlogPlugin that optionally will
> support tagsplugin and spamfilterplugin if present. Notice the [tags]
> and [spamfilter] markers in entry_points + extras_require conditions.
> The conditional entry points will only be declared when extras match:
>
> http://trac-hacks.org/browser/fullblogplugin/0.11/setup.py
>
> You obviously need to structure your code so that the particular
> extras code are not loaded when not needed. Like in the example from
> my plugin that means that when the entry_point condition isn't
> matched, there is nothing else trying to import that particular file.
> For my 'tracfullblog/tags.py' for example that means I can just
> 'import tractags' without having to write try-except handling as
> nothing should attempt to load the file unless the dependency is
> available.

That's pretty code. I like that. But I'm not sure how to use it. What
I'm trying to do is extend Estimation Tools to use TracPM when installed
so I can, for example, do:

[[WorkloadChart(root=self)]]

in a ticket description and have ET defer to TracPM (my project
management shim) to figure out what "root=self" means (expand it to the
list of IDs of all descendant tickets). Following your example, I think
I need to:

* Make PM an extra in setup.py
* Add pmutil.py or something (which imports TracPM) to ET
* In utils.py, call a PM wrapper function from pmutil.py when appropriate:

if options.get('root'):
ids = pmutil.expandRoot(options)

I might go so far as

if options.get('root'):
try:
ids = pmutil.expandRoot(options)
except:
raise TracError('PM support not installed')

Since you own ET, I guess you opinion matters. ;-)

Reply all
Reply to author
Forward
0 new messages