Creating a setup.py for a plugin

37 views
Skip to first unread message

Christopher Nelson

unread,
Jan 21, 2013, 4:00:47 PM1/21/13
to trac...@googlegroups.com
I don't know if I'm dumb, ignorant, inexperienced, or asleep but while
I can sometimes beat a plugin into submission, once I have setup.py
working I treat it with superstition and reverence, unable to change
anything with a plan or with confidence that it will do the right
thing. I've looked and asked and I have never gotten a pointer to a
clear explanation of what to put in it. Help!

I'm working my IQueryPreprocessor
(http://trac.edgewall.org/ticket/10983) I'm now trying to port my
ExtensionPoint in 0.11.6 to an OrderedExtensionsOption in 1.0 (or 1.1
or whatever the development branch is). In 0.11.6, I can test my
changes to query.py with my TracPM code but that's not ported to or
tested in 1.0 yet so I figured I'd just put together a trivial
implementation to illustrate and test the interface (at the end of
this message). My example translates "foo" to "id" so
[[TicketQuery(foo=1)]] is the same as [[TicketQuery(id=1)]] and
[[TicketQuery(id=1|2,foo=3)]] is the same as
[[TicketQuery(id=1|2|3)]]. I put my code in
trac/sample-plugins/sampleQueryPreprocessor/sampleQueryPreprocessor.py
and tried and tried to create a setup.py in that directory. Nothing I
try works. I build my egg and deploy it and my trac.log says:

2013-01-21 15:45:27,463 Trac[loader] DEBUG: Adding plugin
SampleQueryPreprocessor 0.1 from
/opt/trac/trac1.0/plugins/SampleQueryPreprocessor-0.1-py2.7.egg
2013-01-21 15:45:27,470 Trac[loader] DEBUG: Loading
SampleQueryPreprocessor from
/opt/trac/trac1.0/plugins/SampleQueryPreprocessor-0.1-py2.7.egg
2013-01-21 15:45:27,473 Trac[loader] ERROR: Skipping
"SampleQueryPreprocessor = SampleQueryPreprocessor":
Traceback (most recent call last):
File "build/bdist.linux-x86_64/egg/trac/loader.py", line 68, in _load_eggs
entry.load(require=True)
File "build/bdist.linux-i686/egg/pkg_resources.py", line 1954, in load
entry = __import__(self.module_name, globals(),globals(), ['__name__'])
ImportError: No module named SampleQueryPreprocessor


My setup.py (modeled on something else I found on my disk that I think
works) is:

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

from setuptools import find_packages, setup

setup(
name = 'SampleQueryPreprocessor',
author = 'Chris Nelson',
author_email = 'Chris....@SIXNET.com',
description = 'Example of a IQueryPreprocessor implementation',
version = '0.1',
license='BSD',
packages=find_packages(exclude=['*tests*']),
entry_points = """
[trac.plugins]
SampleQueryPreprocessor=SampleQueryPreprocessor
""",
)

What should it be? Better yet, where can I find a tutorial or
reference so I can get this right next time. This is making me
insane!


----8<---- plugin source follows --->8-----

from trac.core import implements, Component
from trac.ticket import IQueryPreprocessor

# A sample implementation of IQueryPreprocessor
#
# This trivial example implements foo= as a synonym for id=. That is,
# [[TicketQuery(foo=1)]] is the same as [[TicketQuery(id=1)]]. Also,
# [[TicketQuery(id=1|2,foo=3)]] becomes [[TicketQuery(id=1|2|3)]].
class SampleQueryHelper(Component):
implements(IQueryPreprocessor)

def __init__(self):
self.myConstraint = 'foo'
self.env.log.info('SampleQueryHelper will translate "foo" to "id".')

# IQueryPreprocessor methods

# Return the list of constraints handled by process_constraints()
def custom_constraints(self):
self.env.log.info('SampleQueryPreprocessor.custom_constraints.')
return [ self.myConstraint ]

# Turn custom constraints (e.g., foo) into standard contraints (e.g., id)
#
# @param req the Trac web request object, may be None
# @param constraints hash indexed by contraint name (e.g., 'foo',
# 'id'). Each entry is a list of values.
#
# @return updated constraints.
def process_constraints(self, req, constraints):
self.env.log.info('SampleQueryPreprocessor.process_constraints.')
# constraint values are lists, TracPM.preQuery() expects
# pipe-delimited strings.
options = {}
for constraint in self.custom_constraints():
if constraint in constraints:
options[constraint] = "|".join(constraints[constraint])
del constraints[constraint]

# Our magic IDs are in 'foo'.
ids = constraints[ self.myConstraint ]

if len(ids):
if 'id' not in constraints:
constraints['id'] = []
for tid in ids:
if tid not in constraints['id']:
constraints['id'].append(tid)

return constraints

Olemis Lang

unread,
Jan 21, 2013, 11:42:04 PM1/21/13
to trac...@googlegroups.com
On 1/21/13, Christopher Nelson <chris.ne...@gmail.com> wrote:
>
[...]
> Help!
>
[...]
> In 0.11.6, I can test my
> changes to query.py with my TracPM code but that's not ported to or
> tested in 1.0 yet
[...]
> I put my code in
> trac/sample-plugins/sampleQueryPreprocessor/sampleQueryPreprocessor.py
> and tried and tried to create a setup.py in that directory. Nothing I
> try works. I build my egg and deploy it and my trac.log says:
>
> 2013-01-21 15:45:27,463 Trac[loader] DEBUG: Adding plugin
> SampleQueryPreprocessor 0.1 from
> /opt/trac/trac1.0/plugins/SampleQueryPreprocessor-0.1-py2.7.egg
> 2013-01-21 15:45:27,470 Trac[loader] DEBUG: Loading
> SampleQueryPreprocessor from
> /opt/trac/trac1.0/plugins/SampleQueryPreprocessor-0.1-py2.7.egg
> 2013-01-21 15:45:27,473 Trac[loader] ERROR: Skipping
> "SampleQueryPreprocessor = SampleQueryPreprocessor":
> Traceback (most recent call last):
> File "build/bdist.linux-x86_64/egg/trac/loader.py", line 68, in
> _load_eggs
> entry.load(require=True)
> File "build/bdist.linux-i686/egg/pkg_resources.py", line 1954, in load
> entry = __import__(self.module_name, globals(),globals(), ['__name__'])
> ImportError: No module named SampleQueryPreprocessor
>

Launch the Python interpreter and import that module i.e.
SampleQueryPreprocessor . Perhaps you'll notice any failure ?

>
> My setup.py (modeled on something else I found on my disk that I think
> works) is:
>
> #!/usr/bin/env python
> # -*- coding: iso-8859-1 -*-
>
> from setuptools import find_packages, setup
>
> setup(
> name = 'SampleQueryPreprocessor',
> author = 'Chris Nelson',
> author_email = 'Chris....@SIXNET.com',
> description = 'Example of a IQueryPreprocessor implementation',
> version = '0.1',
> license='BSD',
> packages=find_packages(exclude=['*tests*']),

I'm not sure of whether a single module will be listed here ...

> entry_points = """
> [trac.plugins]
> SampleQueryPreprocessor=SampleQueryPreprocessor
> """,
> )
>
> What should it be? Better yet, where can I find a tutorial or
> reference so I can get this right next time. This is making me
> insane!
>

This might not be related to Trac ...

[...]

--
Regards,

Olemis.

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:

Christopher Nelson

unread,
Jan 22, 2013, 8:23:06 AM1/22/13
to trac...@googlegroups.com
> ...
>> Traceback (most recent call last):
>> File "build/bdist.linux-x86_64/egg/trac/loader.py", line 68, in
>> _load_eggs
>> entry.load(require=True)
>> File "build/bdist.linux-i686/egg/pkg_resources.py", line 1954, in load
>> entry = __import__(self.module_name, globals(),globals(), ['__name__'])
>> ImportError: No module named SampleQueryPreprocessor
>>
>
> Launch the Python interpreter and import that module i.e.
> SampleQueryPreprocessor . Perhaps you'll notice any failure ?

Like a syntax error in my plugin source? Maybe but this really feels
like a namespace problem.

>...
>> What should it be? Better yet, where can I find a tutorial or
>> reference so I can get this right next time. This is making me
>> insane!
>
> This might not be related to Trac ...

My wife might agree. ;-)


Trying this methodically with code that is presumably known good, I go
to http://trac.edgewall.org/wiki/TracDev/PluginDevelopment for an
example. In my Trac 1.0 development area I create
trac/sample-plugins/test. In that directory I create helloworld.py and
setup.py with the code from the page mentioned above. Then I do:

python setup.py bdist_egg
sudo cp dist/*.egg /opt/trac/trac1.0/plugins

and restart tracd. The log shows:

------------------------
2013-01-22 08:17:52,805 Trac[loader] DEBUG: Adding plugin
TracHelloWorld 1.0 from
/opt/trac/trac1.0/plugins/TracHelloWorld-1.0-py2.7.egg
2013-01-22 08:17:52,819 Trac[loader] DEBUG: Loading helloworld from
/opt/trac/trac1.0/plugins/TracHelloWorld-1.0-py2.7.egg
2013-01-22 08:17:52,823 Trac[loader] ERROR: Skipping "helloworld =
myplugs.helloworld":
Traceback (most recent call last):
File "build/bdist.linux-x86_64/egg/trac/loader.py", line 68, in _load_eggs
entry.load(require=True)
File "build/bdist.linux-i686/egg/pkg_resources.py", line 1954, in load
entry = __import__(self.module_name, globals(),globals(), ['__name__'])
ImportError: No module named myplugs.helloworld
------------------------

so, I move helloworld.py to trac/sample-plugins/test/myplugs and
repeat. This time I see:

------------------------
2013-01-22 08:17:52,805 Trac[loader] DEBUG: Adding plugin
TracHelloWorld 1.0 from
/opt/trac/trac1.0/plugins/TracHelloWorld-1.0-py2.7.egg
2013-01-22 08:17:52,819 Trac[loader] DEBUG: Loading helloworld from
/opt/trac/trac1.0/plugins/TracHelloWorld-1.0-py2.7.egg
2013-01-22 08:17:52,823 Trac[loader] ERROR: Skipping "helloworld =
myplugs.helloworld":
Traceback (most recent call last):
File "build/bdist.linux-x86_64/egg/trac/loader.py", line 68, in _load_eggs
entry.load(require=True)
File "build/bdist.linux-i686/egg/pkg_resources.py", line 1954, in load
entry = __import__(self.module_name, globals(),globals(), ['__name__'])
ImportError: No module named myplugs.helloworld
------------------------

Where should the files from the example be placed so that the example works?

RjOllos

unread,
Jan 23, 2013, 12:48:46 AM1/23/13
to trac...@googlegroups.com
On Tuesday, January 22, 2013 5:23:06 AM UTC-8, Chris Nelson wrote:
> Launch the Python interpreter and import that module i.e.
> SampleQueryPreprocessor . Perhaps you'll notice any failure ?

Like a syntax error in my plugin source?  Maybe but this really feels
like a namespace problem.

Any chance you are missing __init__.py in your package directory? You need at least an empty __init__.py file. There have been several occasions when I omitted it, and I think that I saw the same error that you are seeing, though I can't be sure. I just recall that the error didn't point me directly to a solution, as least given my moderate experience with Python.

RjOllos

unread,
Jan 23, 2013, 12:57:38 AM1/23/13
to trac...@googlegroups.com
On Monday, January 21, 2013 1:00:47 PM UTC-8, Chris Nelson wrote:
[...]

trac/sample-plugins/sampleQueryPreprocessor/sampleQueryPreprocessor.py
and tried and tried to create a setup.py in that directory.  Nothing I
try works.

Also, unless you put a `from sampleQueryPreprocessor import *` in your `__init__.py`, if your files/directory structure is like this:

setup.py
sampleQueryPreprocessor/sampleQueryPreprocessor.py

Then you'll need:

entry_points = """
    [trac.plugins]
        SampleQueryPreprocessor=sampleQueryPreprocessor.SampleQueryPreprocessor
""",

in your `setup.py` ... or something like that.

RjOllos

unread,
Jan 23, 2013, 1:10:03 AM1/23/13
to trac...@googlegroups.com


On Tuesday, January 22, 2013 9:57:38 PM UTC-8, RjOllos wrote:
[...]

Also, unless you put a `from sampleQueryPreprocessor import *` in your `__init__.py`, ...

Sorry, I think that should be  `import sampleQueryPreprocessor`. I'll shut-up and go to sleep now though ...

Christopher Nelson

unread,
Jan 23, 2013, 8:05:55 AM1/23/13
to trac...@googlegroups.com
> Any chance you are missing __init__.py in your package directory? You need
> at least an empty __init__.py file. There have been several occasions when I
> omitted it, and I think that I saw the same error that you are seeing,
> though I can't be sure. I just recall that the error didn't point me
> directly to a solution, as least given my moderate experience with Python.

That is exactly it! I owe you a beer. I would *never* have gotten
that from http://trac.edgewall.org/wiki/TracDev/PluginDevelopment.
(When I get this working, I'll update that page.) Thank you!

Olemis Lang

unread,
Jan 23, 2013, 9:35:01 AM1/23/13
to trac...@googlegroups.com
On 1/23/13, Christopher Nelson <chris.ne...@gmail.com> wrote:
>> Any chance you are missing __init__.py in your package directory? You
>> need
>> at least an empty __init__.py file. There have been several occasions when
>> I
>> omitted it, and I think that I saw the same error that you are seeing,
>> though I can't be sure. I just recall that the error didn't point me
>> directly to a solution, as least given my moderate experience with
>> Python.
>
> That is exactly it!

That reinforces my initial impression that the issue was not related
to Trac itself .

On 1/22/13, Christopher Nelson <chris.ne...@gmail.com> wrote:
>>...
>>> What should it be? Better yet, where can I find a tutorial or
>>> reference so I can get this right next time. This is making me
>>> insane!
>>
>> This might not be related to Trac ...
>
> My wife might agree. ;-)
>

so send her my greetings ;-)
Reply all
Reply to author
Forward
0 new messages