Implementing a plug-in mechanism

Loris Bennett loris.bennett at fu-berlin.de
Thu Mar 16 12:02:37 EDT 2023


Simon Ward <simon+python at bleah.co.uk> writes:

> On Thu, Mar 16, 2023 at 07:45:18AM +1300, dn via Python-list wrote:
>> There is a PyPi library called pluggy (not used it). I've used
>> informal approaches using an ABC as a framework/reminder (see
>> @George's response).
>
> typing.Protocol is also useful here as the plugin interface can be
> defined separately not requiring inheriting from an ABC.

Thanks to all for the helpful suggestions.   I realise that I don't
actually need to be able to load a bunch of arbitrary plugins, but
merely to be able to override one (or, perhaps later, more) piece of
default behaviour.

Therefore I think the following very simple scheme will work for me:

  $ tree -L 3
  .
  └── myproj
      ├── __init__.py
      ├── mailer.py
      ├── main.py
      └── plugins
          └── normanmailer.py

Where main.py is

  #!/usr/bin/env python3
  # -*- coding: utf-8 -*-

  if __name__ == "__main__":

      try:
          import plugin.mailer as mailer
          print("Found plugin.mailer")
      except ModuleNotFoundError:
          import mailer
          print("Found mailer")

      m = mailer.Mailer('abc')
      m.run()

mailer.py is

  class Mailer():

      def run(self):
          print("This is a generic Mailer object!")

and plugins/normanmailer.py is

  class Mailer():

      def run(self):
          print("This is a customized Mailer object!")

This then gives me

  $ poetry run myproj\/main.py
  Found mailer
  This is a generic Mailer object!

  $ mv myproj/plugins/{norman,}mailer.py

  $ poetry run myproj\/main.py
  Found plugins.mailer
  This is a customized Mailer object!

I suspect I was using slightly incorrect/misleading terminology.  I
don't want to be able to load arbitrary functionality via plugins,
e.g. sending an email, dumping to a database, uploading to a cloud.
That would, I far as I can tell, necessitate having some mechanism to
select the functionality.

Instead I just want to modify the behaviour of a piece of fixed
functionality. e.g. sending a mail.  So am I really talking about
customisation here.

Cheers,

Loris

--
This signature is currently under constuction.


More information about the Python-list mailing list