Description
If you create a Group page: EampleGroup and then rename that page, because of fixing a typo to ExampleGroup the dicts cache is not refreshed on that action.
pagename = "ExampleGroup" members, groups = request.dicts.expand_group(pagename)
fails with a KeyError u'ExampleGroup' and you do see in the list the wrong written name.
I tried to write a test for that and got another problem may be the test is not well done but the result is such strange so I think there is another bug involved too.
1 def testRenameGroupPage(self):
2 # tests if the dict cache for groups is refreshed after renaming a page
3 gain_superuser_rights(self.request)
4 pagename = u'SomeGroup'
5 page = PageEditor(self.request, pagename, do_editor_backup=0)
6 body = " * ExampleUser"
7 page.saveText(body, 0)
8 page = PageEditor(self.request, pagename, do_editor_backup=0)
9 page.renamePage(u'AnotherGroup')
10
11 group = wikidicts.Group(self.request, '')
12 isgroup = self.request.cfg.cache.page_group_regex.search
13 grouppages = self.request.rootpage.getPageList(user='', filter=isgroup)
14
15 members, groups = self.request.dicts.expand_group(u'AnotherGroup')
16
17 page = PageEditor(self.request, u'AnotherGroup', do_editor_backup=0)
18 page.deletePage()
19 assert u'ExampleUser' in members
this gives a traceback
1 test_wikidicts.py[9] ........F
2
3 ___________________________________________________________________________________________________
4 ________________________ entrypoint: TestGroupDicts().testRenameGroupPage _________________________
5
6 def testRenameGroupPage(self):
7 # tests if the dict cache for groups is refreshed after renaming a page
8 gain_superuser_rights(self.request)
9 pagename = u'SomeGroup'
10 page = PageEditor(self.request, pagename, do_editor_backup=0)
11 body = " * ExampleUser"
12 page.saveText(body, 0)
13 page = PageEditor(self.request, pagename, do_editor_backup=0)
14 > page.renamePage(self.request, u'AnotherGroup')
15
16 [/home/workspace/moin-1.7/MoinMoin/_tests/test_wikidicts.py:127]
17 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
18
19 def renamePage(self, newpagename, comment=None):
20 """ Rename the current version of the page (making a backup before deletion
21 and keeping the backups, logs and attachments).
22
23 @param comment: Comment given by user
24 @rtype: unicode
25 @return: success flag, error message
26 """
27 request = self.request
28 _ = self._
29
30 if not (request.user.may.delete(self.page_name)
31 and request.user.may.write(newpagename)):
32 msg = _('You are not allowed to rename this page!')
33 raise self.AccessDenied, msg
34
35 if not newpagename:
36 return False, _("You can't rename to an empty pagename.")
37
38 newpage = PageEditor(request, newpagename)
39
40 pageexists_error = _("""'''A page with the name {{{'%s'}}} already exists.'''
41
42 Try a different name.""") % (wikiutil.escape(newpagename), )
43
44 # Check whether a page with the new name already exists
45 if newpage.exists(includeDeleted=1):
46 return False, pageexists_error
47
48 # Get old page text
49 savetext = self.get_raw_body()
50
51 oldpath = self.getPagePath(check_create=0)
52 newpath = newpage.getPagePath(check_create=0)
53
54 # Rename page
55
56 # NOTE: might fail if another process created newpagename just
57 # NOW, while you read this comment. Rename is atomic for files -
58 # but for directories, rename will fail if the directory
59 # exists. We should have global edit-lock to avoid this.
60 # See http://docs.python.org/lib/os-file-dir.html
61 try:
62 os.rename(oldpath, newpath)
63 self.error = None
64 # Save page text with a comment about the old name
65 savetext = u"## page was renamed from %s\n%s" % (self.page_name, savetext)
66 > newpage.saveText(savetext, 0, comment=comment, extra=self.page_name, action='SAVE/RENAME', notify=False)
67
68 [/home/workspace/moin-1.7/MoinMoin/PageEditor.py:609]
69 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
70
71 def saveText(self, newtext, rev, **kw):
72 """ Save new text for a page.
73
74 @param newtext: text to save for this page
75 @param rev: revision of the page
76 @keyword trivial: trivial edit (default: 0)
77 @keyword extra: extra info field (e.g. for SAVE/REVERT with revno)
78 @keyword comment: comment field (when preview is true)
79 @keyword action: action for editlog (default: SAVE)
80 @keyword index: needs indexing, not already handled (default: 1)
81 @keyword deleted: if True, then don't save page content (used by DeletePage, default: False)
82 @keyword notify: if False (default: True), don't send a PageChangedEvent
83 @rtype: unicode
84 @return: error msg
85 """
86 request = self.request
87 _ = self._
88 > self._save_draft(newtext, rev, **kw)
89
90 [/home/workspace/moin-1.7/MoinMoin/PageEditor.py:1024]
91 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
92
93 def _save_draft(self, text, rev, **kw):
94 """ Save an editor backup to the drafts cache arena.
95
96 @param text: draft text of the page
97 (if None, the draft gets removed from the cache)
98 @param rev: the revision of the page this draft is based on
99 @param kw: no keyword args used currently
100 """
101 request = self.request
102 if not request.user.valid or not self.do_editor_backup:
103 return None
104
105 arena = 'drafts'
106 key = request.user.id
107 cache = caching.CacheEntry(request, arena, key, scope='wiki', use_pickle=True)
108 if cache.exists():
109 cache_data = cache.content()
110 else:
111 cache_data = {}
112 pagename = self.page_name
113 if text is None:
114 try:
115 del cache_data[pagename]
116 except:
117 pass
118 else:
119 timestamp = int(time.time())
120 cache_data[pagename] = (timestamp, rev, text)
121 > cache.update(cache_data)
122
123 [/home/workspace/moin-1.7/MoinMoin/PageEditor.py:836]
124 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
125
126 def update(self, content):
127 try:
128 fname = self._filename()
129 if self.use_pickle:
130 content = pickle.dumps(content, PICKLE_PROTOCOL)
131 elif self.use_encode:
132 content = content.encode(config.charset)
133 if not self.locking or self.locking and self.wlock.acquire(1.0):
134 try:
135 # we do not write content to old inode, but to a new file
136 # so we don't need to lock when we just want to read the file
137 # (at least on POSIX, this works)
138 tmp_handle, tmp_fname = tempfile.mkstemp('.tmp', self.key, self.arena_dir)
139 os.write(tmp_handle, content)
140 os.close(tmp_handle)
141 # this is either atomic or happening with real locks set:
142 filesys.rename(tmp_fname, fname)
143 filesys.chmod(fname, 0666 & config.umask) # fix mode that mkstemp chose
144 finally:
145 if self.locking:
146 self.wlock.release()
147 else:
148 print self.lock_dir
149 self.request.log("Can't acquire write lock in %s" % self.lock_dir)
150 except (pickle.PicklingError, OSError, IOError, ValueError), err:
151 E raise CacheError(str(err))
152 > CacheError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
153
154 [/home/workspace/moin-1.7/MoinMoin/caching.py:150]
155 ___________________________________________________________________________________________________
156 ======================= tests finished: 8 passed, 1 failed in 0.83 seconds ========================
Steps to reproduce
- do this...
Example
Component selection
- general
Details
MoinMoin Version |
1.7dev |
OS and Version |
|
Python Version |
|
Server Setup |
|
Server Details |
|
Language you are using the wiki in (set in the browser/UserPreferences) |
|
Workaround
Discussion
Plan
- Priority:
- Assigned to:
- Status: fixed in 1.7 2874:de20fd4e2352