turbogears migration: tests: internationalization

Thomas De Schampheleire patrickdepinguin at gmail.com
Mon May 16 19:30:29 UTC 2016


Hi Alessandro,


On Mon, May 16, 2016 at 10:55 AM, Alessandro Molina
<alessandro.molina at gmail.com> wrote:
>
> On Mon, May 16, 2016 at 9:32 AM, Thomas De Schampheleire
> <patrickdepinguin at gmail.com> wrote:
>>
>> ../venv/kallithea-tg/lib/python2.7/site-packages/formencode/api.py:211:
>> in __classinit__
>>     cls._initialize_docstring()
>> ../venv/kallithea-tg/lib/python2.7/site-packages/formencode/api.py:302:
>> in _initialize_docstring
>>     default = re.sub(r'(%\(.*?\)[rsifcx])', r'``\1``', default)
>> ../venv/kallithea-tg/lib64/python2.7/re.py:155: in sub
>>     return _compile(pattern, flags).sub(repl, string, count)
>> E   TypeError: Error when calling the metaclass bases
>> E       expected string or buffer
>>
>> I tried investigating this but it is out of my league.
>> I don't know if it is still related to internationalization or not, or
>> to some other turbogears-specific thing.
>>
>> If you happen to have ideas here they are very welcome.
>>
>> Being stuck there, I have been working on further migration of the
>> test suite to pytest, which is now finished, so I will be looking back
>> at the turbogears migration.
>
>
> Yep, it's caused by lazy_ugettext in LoginForm messages.
> _() in FormEncode schemas is not required as translation is actually done by
> formencode itself ->
> https://github.com/formencode/formencode/blob/267f05e9ec6730806fc7c143abc468421cbf94bc/formencode/api.py#L243
>
> The purpose of having _() call in schemas is just for convenience for string
> collectors that look for all the _() calls to extract po files.
>
> For this reason formencode provides a formencode.api._ function which is
> actually just an identity function that does nothing but flag the string as
> to be collected ->
> https://github.com/formencode/formencode/blob/267f05e9ec6730806fc7c143abc468421cbf94bc/formencode/api.py#L74
>
> You should probably import that one instead of TG i18n one in model/forms.py
> as the only _() calls I see there are for formencode schemas.
>

With that changed:

diff --git a/kallithea/model/forms.py b/kallithea/model/forms.py
--- a/kallithea/model/forms.py
+++ b/kallithea/model/forms.py
@@ -37,8 +37,7 @@ import logging

 import formencode
 from formencode import All
-
-from tg.i18n import ugettext as _
+from formencode.api import _

 from kallithea import BACKENDS
 from kallithea.model import validators as v
diff --git a/kallithea/model/validators.py b/kallithea/model/validators.py
--- a/kallithea/model/validators.py
+++ b/kallithea/model/validators.py
@@ -20,10 +20,10 @@ import re
 import formencode
 import logging
 from collections import defaultdict
-from tg.i18n import ugettext as _
 from webhelpers.pylonslib.secure_form import authentication_token
 import sqlalchemy

+from formencode.api import _
 from formencode.validators import (
     UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set,
     NotEmpty, IPAddress, CIDR, String, FancyValidator


I no longer get the error at import, but new errors during actual test
execution:

$ py.test kallithea/tests/functional/test_pullrequests.py
No handlers could be found for logger "tg.appwrappers.transaction_manager"
Test session starts (platform: linux2, Python 2.7.10, pytest 2.9.1,
pytest-sugar 0.6.0)
rootdir: /home/tdescham/repo/contrib/kallithea/kallithea-tg, inifile: pytest.ini
plugins: sugar-0.6.0

 kallithea/tests/functional/test_pullrequests.py ✓✓✓

            23% ██▍

―――――――――――――――――――――――――――――――――――――――――――――――――――――
TestPullrequestsController.test_create_with_invalid_reviewer
―――――――――――――――――――――――――――――――――――――――――――――――――――――
kallithea/tests/functional/test_pullrequests.py:71: in
test_create_with_invalid_reviewer
    response.mustcontain('Invalid reviewer "%s" specified' %
invalid_user_name)
../venv/kallithea-tg/lib/python2.7/site-packages/webtest/response.py:363:
in mustcontain
    "Body does not contain string %r" % s)
E   IndexError: Body does not contain string 'Invalid reviewer
"invalid_user" specified'
-------------------------------------------------------------------------
Captured stderr call
-------------------------------------------------------------------------
Actual response (no 'Invalid reviewer "invalid_user" specified'):
Response: 400 Bad Request
Cache-Control: no-cache
Content-Type: text/plain; charset=UTF-8
Pragma: no-cache
400 Bad Request
The server could not comply with the request since it is either
malformed or otherwise incorrect.
 kallithea/tests/functional/test_pullrequests.py ✓✓✓⨯

            31% ███▏

―――――――――――――――――――――――――――――――――――――――――――――――――――――
TestPullrequestsController.test_update_with_invalid_reviewer
―――――――――――――――――――――――――――――――――――――――――――――――――――――
kallithea/tests/functional/test_pullrequests.py:108: in
test_update_with_invalid_reviewer
    response.mustcontain('Invalid reviewer "%s" specified' %
invalid_user_id)
../venv/kallithea-tg/lib/python2.7/site-packages/webtest/response.py:363:
in mustcontain
    "Body does not contain string %r" % s)
E   IndexError: Body does not contain string 'Invalid reviewer
"99999" specified'
-------------------------------------------------------------------------
Captured stderr call
-------------------------------------------------------------------------
Actual response (no 'Invalid reviewer "99999" specified'):
Response: 400 Bad Request
Cache-Control: no-cache
Content-Type: text/plain; charset=UTF-8
Pragma: no-cache
400 Bad Request
The server could not comply with the request since it is either
malformed or otherwise incorrect.
 kallithea/tests/functional/test_pullrequests.py ✓✓✓⨯⨯

            38% ███▉

――――――――――――――――――――――――――――――――――――――――――――――――――――――
TestPullrequestsController.test_edit_with_invalid_reviewer
――――――――――――――――――――――――――――――――――――――――――――――――――――――
kallithea/tests/functional/test_pullrequests.py:144: in
test_edit_with_invalid_reviewer
    response.mustcontain('Invalid reviewer "%s" specified' %
invalid_user_id)
../venv/kallithea-tg/lib/python2.7/site-packages/webtest/response.py:363:
in mustcontain
    "Body does not contain string %r" % s)
E   IndexError: Body does not contain string 'Invalid reviewer
"99999" specified'
-------------------------------------------------------------------------
Captured stderr call
-------------------------------------------------------------------------
Actual response (no 'Invalid reviewer "99999" specified'):
Response: 400 Bad Request
Cache-Control: no-cache
Content-Type: text/plain; charset=UTF-8
Pragma: no-cache
400 Bad Request
The server could not comply with the request since it is either
malformed or otherwise incorrect.
 kallithea/tests/functional/test_pullrequests.py ✓✓✓⨯⨯⨯

            46% ████▋

――――――――――――――――――――――――――――――――――――――――――――――――――――――――
TestPullrequestsGetRepoRefs.test_repo_refs_empty_repo
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――
kallithea/tests/functional/test_pullrequests.py:161: in
test_repo_refs_empty_repo
    refs, default = self.c._get_repo_refs(self.main.scm_instance)
kallithea/controllers/pullrequests.py:172: in _get_repo_refs
    groups = [(specials, _("Special")),
../venv/kallithea-tg/lib/python2.7/site-packages/tg/i18n.py:89: in ugettext
    return tg.translator.ugettext(value)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/request_local.py:178:
in _current_obj
    return getattr(context, self.name)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/registry.py:72:
in _current_obj
    'thread' % self.____name__)
E   TypeError: No object (name: context) has been registered for this thread
 kallithea/tests/functional/test_pullrequests.py ✓✓✓⨯⨯⨯⨯✓

            62% ██████▎

――――――――――――――――――――――――――――――――――――――――――――――――――――
TestPullrequestsGetRepoRefs.test_repo_refs_one_commit_no_hints
――――――――――――――――――――――――――――――――――――――――――――――――――――
kallithea/tests/functional/test_pullrequests.py:169: in
test_repo_refs_one_commit_no_hints
    refs, default = self.c._get_repo_refs(self.main.scm_instance)
kallithea/controllers/pullrequests.py:172: in _get_repo_refs
    groups = [(specials, _("Special")),
../venv/kallithea-tg/lib/python2.7/site-packages/tg/i18n.py:89: in ugettext
    return tg.translator.ugettext(value)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/request_local.py:178:
in _current_obj
    return getattr(context, self.name)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/registry.py:72:
in _current_obj
    'thread' % self.____name__)
E   TypeError: No object (name: context) has been registered for this thread
 kallithea/tests/functional/test_pullrequests.py ✓✓✓⨯⨯⨯⨯✓⨯

            69% ██████▉

――――――――――――――――――――――――――――――――――――――――――――――――――――
TestPullrequestsGetRepoRefs.test_repo_refs_one_commit_rev_hint
――――――――――――――――――――――――――――――――――――――――――――――――――――
kallithea/tests/functional/test_pullrequests.py:179: in
test_repo_refs_one_commit_rev_hint
    refs, default = self.c._get_repo_refs(self.main.scm_instance,
rev=cs0.raw_id)
kallithea/controllers/pullrequests.py:172: in _get_repo_refs
    groups = [(specials, _("Special")),
../venv/kallithea-tg/lib/python2.7/site-packages/tg/i18n.py:89: in ugettext
    return tg.translator.ugettext(value)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/request_local.py:178:
in _current_obj
    return getattr(context, self.name)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/registry.py:72:
in _current_obj
    'thread' % self.____name__)
E   TypeError: No object (name: context) has been registered for this thread
 kallithea/tests/functional/test_pullrequests.py ✓✓✓⨯⨯⨯⨯✓⨯⨯

            77% ███████▊

――――――――――――――――――――――――――――――――――――――――――――――――――
TestPullrequestsGetRepoRefs.test_repo_refs_two_commits_branch_hint
――――――――――――――――――――――――――――――――――――――――――――――――――
kallithea/tests/functional/test_pullrequests.py:224: in
test_repo_refs_two_commits_branch_hint
    refs, default = self.c._get_repo_refs(self.main.scm_instance,
branch='default')
kallithea/controllers/pullrequests.py:172: in _get_repo_refs
    groups = [(specials, _("Special")),
../venv/kallithea-tg/lib/python2.7/site-packages/tg/i18n.py:89: in ugettext
    return tg.translator.ugettext(value)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/request_local.py:178:
in _current_obj
    return getattr(context, self.name)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/registry.py:72:
in _current_obj
    'thread' % self.____name__)
E   TypeError: No object (name: context) has been registered for this thread
 kallithea/tests/functional/test_pullrequests.py ✓✓✓⨯⨯⨯⨯✓⨯⨯⨯

            85% ████████▌

―――――――――――――――――――――――――――――――――――――――――――――――――――
TestPullrequestsGetRepoRefs.test_repo_refs_two_commits_no_hints
――――――――――――――――――――――――――――――――――――――――――――――――――――
kallithea/tests/functional/test_pullrequests.py:192: in
test_repo_refs_two_commits_no_hints
    refs, default = self.c._get_repo_refs(self.main.scm_instance)
kallithea/controllers/pullrequests.py:172: in _get_repo_refs
    groups = [(specials, _("Special")),
../venv/kallithea-tg/lib/python2.7/site-packages/tg/i18n.py:89: in ugettext
    return tg.translator.ugettext(value)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/request_local.py:178:
in _current_obj
    return getattr(context, self.name)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/registry.py:72:
in _current_obj
    'thread' % self.____name__)
E   TypeError: No object (name: context) has been registered for this thread
 kallithea/tests/functional/test_pullrequests.py ✓✓✓⨯⨯⨯⨯✓⨯⨯⨯⨯

            92% █████████▎

―――――――――――――――――――――――――――――――――――――――――――――――――――
TestPullrequestsGetRepoRefs.test_repo_refs_two_commits_rev_hints
―――――――――――――――――――――――――――――――――――――――――――――――――――
kallithea/tests/functional/test_pullrequests.py:205: in
test_repo_refs_two_commits_rev_hints
    refs, default = self.c._get_repo_refs(self.main.scm_instance,
rev=cs0.raw_id)
kallithea/controllers/pullrequests.py:151: in _get_repo_refs
    specials = [(selected, '%s: %s' % (_("Changeset"), rev[:12]))]
../venv/kallithea-tg/lib/python2.7/site-packages/tg/i18n.py:89: in ugettext
    return tg.translator.ugettext(value)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/request_local.py:178:
in _current_obj
    return getattr(context, self.name)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/objectproxy.py:19:
in __getattr__
    return getattr(self._current_obj(), attr)
../venv/kallithea-tg/lib/python2.7/site-packages/tg/support/registry.py:72:
in _current_obj
    'thread' % self.____name__)
E   TypeError: No object (name: context) has been registered for this thread
 kallithea/tests/functional/test_pullrequests.py ✓✓✓⨯⨯⨯⨯✓⨯⨯⨯⨯⨯

           100% ██████████
=======================================================================
short test summary info
========================================================================
FAIL kallithea/tests/functional/test_pullrequests.py::TestPullrequestsController::()::test_create_with_invalid_reviewer
FAIL kallithea/tests/functional/test_pullrequests.py::TestPullrequestsController::()::test_update_with_invalid_reviewer
FAIL kallithea/tests/functional/test_pullrequests.py::TestPullrequestsController::()::test_edit_with_invalid_reviewer
FAIL kallithea/tests/functional/test_pullrequests.py::TestPullrequestsGetRepoRefs::test_repo_refs_empty_repo
FAIL kallithea/tests/functional/test_pullrequests.py::TestPullrequestsGetRepoRefs::test_repo_refs_one_commit_no_hints
FAIL kallithea/tests/functional/test_pullrequests.py::TestPullrequestsGetRepoRefs::test_repo_refs_one_commit_rev_hint
FAIL kallithea/tests/functional/test_pullrequests.py::TestPullrequestsGetRepoRefs::test_repo_refs_two_commits_branch_hint
FAIL kallithea/tests/functional/test_pullrequests.py::TestPullrequestsGetRepoRefs::test_repo_refs_two_commits_no_hints
FAIL kallithea/tests/functional/test_pullrequests.py::TestPullrequestsGetRepoRefs::test_repo_refs_two_commits_rev_hints


Basically there are two types of failure:

- first one where a 400 status code is expected but with some message
"Invalid reviewer specified", and the real response is 400 without
that message. At first sight it looks unrelated to the translation.
Perhaps this is a new difference between pylons and turbogears?

- second one that is caused by translation problems in the class
TestPullrequestsRefs. What is specific to this test class is that no
application requests are made. An object of class
'PullrequestsController' is created in the setUp method explicitly. I
guess this is the reason that no translation can be made. Question is:
what is the appropriate solution here? Can we stub the translation in
an easy way? What do you suggest?

/Thomas


More information about the kallithea-general mailing list