aboutsummaryrefslogtreecommitdiff
path: root/doc/bugs/autosetup_python_warnings.mdwn
blob: 5c081dac28cd85f04aed4bf202d5757c65b5db04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
## What I did

A friend reported this, and I'm seeing it too. With 3.20140916, on
a system with Python 2.7 and 3.4 (and little else) installed, I
tried to run the auto.setup:

    :; ikiwiki --setup /etc/pkg/ikiwiki/auto.setup
    What will the wiki be named? Import Errors
    What revision control system to use? git
    Which user (wiki account or openid) will be admin? schmonz
    
    
    Setting up Import Errors ...
    Importing /Users/schmonz/ImportErrors into git
    Initialized empty shared Git repository in /Users/schmonz/ImportErrors.git/
    Initialized empty Git repository in /Users/schmonz/ImportErrors/.git/
    [master (root-commit) 20b1128] initial commit
     1 file changed, 1 insertion(+)
     create mode 100644 .gitignore
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 230 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To /Users/schmonz/ImportErrors.git
     * [new branch]      master -> master
    Directory /Users/schmonz/ImportErrors is now a clone of git repository /Users/schmonz/ImportErrors.git
    Traceback (most recent call last):
      File "/usr/pkg/lib/ikiwiki/plugins/rst", line 45, in <module>
        from proxy import IkiWikiProcedureProxy
      File "/usr/pkg/lib/ikiwiki/plugins/proxy.py", line 41, in <module>
        import xml.parsers.expat
      File "/usr/pkg/lib/python3.4/xml/parsers/expat.py", line 4, in <module>
        from pyexpat import *
    ImportError: No module named 'pyexpat'
    
    
    Creating wiki admin schmonz ...
    Choose a password:
    [...]

## What I expected

I expected to get a basic site.

## What happened instead

I got a basic site with some Python error messages.

## Likely fix

Looks like `proxy.py` needs the trick from [[!debbug 637604]] so
that it can defer a few imports (at least `xml.parsers.expat` and
the XML-RPC libs) until the methods using them are called. --[[schmonz]]

-----

It's more complicated than I thought. Findings and questions:

### Failing to load an external plugin should be an error

When a typical Perl plugin fails to load (say, by failing to compile),
`IkiWiki::loadplugin()` throws an exception. For XML-RPC plugins
written in any language, ikiwiki assumes loading succeeded.

Let's take [[!iki plugins/rst]] as an example. It's written in
Python and uses `proxy.py` to handle XML-RPC communication with
ikiwiki. Let's say that `proxy.py` compiles, but `rst` itself
doesn't. We'd like ikiwiki to know the module isn't loaded, and
we'd like an error message about it (not just the Python errors).

Now let's say `rst` would be fine by itself, but `proxy.py` doesn't
compile because some of the Python modules it needs are missing
from the system. (This can't currently happen on Debian, where
`libpython2.7` includes `pyexpat.so`, but pkgsrc's `python27`
doesn't; it's in a separate `py-expat` package.) As before, we'd
like ikiwiki to know `rst` didn't load, but that's trickier when
the problem lies with the communication mechanism itself.

For the tricky case, what to do? Some ideas:

- Figure out where in `auto.setup` we're enabling `rst` by default,
  and stop doing that
- In pkgsrc's `ikiwiki` package, add a dependency on Python and
  `py-expat` just in case someone wants to enable `rst` or other
  Python plugins

For the simple case, I've tried the following:

[[!template id=gitbranch branch=schmonz/external-plugin-loading author="[[schmonz]]"]]

- In `IkiWiki::Plugin::external::import()`, capture stderr
- Before falling off the end of `IkiWiki::Plugin::external::rpc_call()`,
  if the command had been 'import' and stderr is non-empty, throw
  an exception
- In `IkiWiki::loadplugin()`, try/catch/throw just like we do with
  regular non-external plugins

With these changes, we have a test that fails when an external
plugin can't be loaded (and passes, less trivially, when it can).
Huzzah! (I haven't tested yet whether I've otherwise completely
broken the interface for external plugins. Not-huzzah!) --[[schmonz]]