209 lines
9.3 KiB
ReStructuredText
209 lines
9.3 KiB
ReStructuredText
===================
|
|
1.0.0 Porting Guide
|
|
===================
|
|
|
|
The 0.1 through 1.0.0 releases focused on bringing in functions from yum and
|
|
python-fedora. This porting guide tells how to port from those APIs to their
|
|
kitchen replacements.
|
|
|
|
-------------
|
|
python-fedora
|
|
-------------
|
|
|
|
=================================== ===================
|
|
python-fedora kitchen replacement
|
|
----------------------------------- -------------------
|
|
:func:`fedora.iterutils.isiterable` :func:`kitchen.iterutils.isiterable` [#f1]_
|
|
:func:`fedora.textutils.to_unicode` :func:`kitchen.text.converters.to_unicode`
|
|
:func:`fedora.textutils.to_bytes` :func:`kitchen.text.converters.to_bytes`
|
|
=================================== ===================
|
|
|
|
.. [#f1] :func:`~kitchen.iterutils.isiterable` has changed slightly in
|
|
kitchen. The :attr:`include_string` attribute has switched its default value
|
|
from :data:`True` to :data:`False`. So you need to change code like::
|
|
|
|
>>> # Old code
|
|
>>> isiterable('abcdef')
|
|
True
|
|
>>> # New code
|
|
>>> isiterable('abcdef', include_string=True)
|
|
True
|
|
|
|
---
|
|
yum
|
|
---
|
|
|
|
================================= ===================
|
|
yum kitchen replacement
|
|
--------------------------------- -------------------
|
|
:func:`yum.i18n.dummy_wrapper` :meth:`kitchen.i18n.DummyTranslations.ugettext` [#y1]_
|
|
:func:`yum.i18n.dummyP_wrapper` :meth:`kitchen.i18n.DummyTanslations.ungettext` [#y1]_
|
|
:func:`yum.i18n.utf8_width` :func:`kitchen.text.display.textual_width`
|
|
:func:`yum.i18n.utf8_width_chop` :func:`kitchen.text.display.textual_width_chop`
|
|
and :func:`kitchen.text.display.textual_width` [#y2]_ [#y4]_
|
|
:func:`yum.i18n.utf8_valid` :func:`kitchen.text.misc.byte_string_valid_encoding`
|
|
:func:`yum.i18n.utf8_text_wrap` :func:`kitchen.text.display.wrap` [#y3]_
|
|
:func:`yum.i18n.utf8_text_fill` :func:`kitchen.text.display.fill` [#y3]_
|
|
:func:`yum.i18n.to_unicode` :func:`kitchen.text.converters.to_unicode` [#y5]_
|
|
:func:`yum.i18n.to_unicode_maybe` :func:`kitchen.text.converters.to_unicode` [#y5]_
|
|
:func:`yum.i18n.to_utf8` :func:`kitchen.text.converters.to_bytes` [#y5]_
|
|
:func:`yum.i18n.to_str` :func:`kitchen.text.converters.to_unicode`
|
|
or :func:`kitchen.text.converters.to_bytes` [#y6]_
|
|
:func:`yum.i18n.str_eq` :func:`kitchen.text.misc.str_eq`
|
|
:func:`yum.misc.to_xml` :func:`kitchen.text.converters.unicode_to_xml`
|
|
or :func:`kitchen.text.converters.byte_string_to_xml` [#y7]_
|
|
:func:`yum.i18n._` See: :ref:`yum-i18n-init`
|
|
:func:`yum.i18n.P_` See: :ref:`yum-i18n-init`
|
|
:func:`yum.i18n.exception2msg` :func:`kitchen.text.converters.exception_to_unicode`
|
|
or :func:`kitchen.text.converter.exception_to_bytes` [#y8]_
|
|
================================= ===================
|
|
|
|
.. [#y1] These yum methods provided fallback support for :mod:`gettext`
|
|
functions in case either ``gaftonmode`` was set or :mod:`gettext` failed
|
|
to return an object. In kitchen, we can use the
|
|
:class:`kitchen.i18n.DummyTranslations` object to fulfill that role.
|
|
Please see :ref:`yum-i18n-init` for more suggestions on how to do this.
|
|
|
|
.. [#y2] The yum version of these functions returned a byte :class:`str`. The
|
|
kitchen version listed here returns a :class:`unicode` string. If you
|
|
need a byte :class:`str` simply call
|
|
:func:`kitchen.text.converters.to_bytes` on the result.
|
|
|
|
.. [#y3] The yum version of these functions would return either a byte
|
|
:class:`str` or a :class:`unicode` string depending on what the input
|
|
value was. The kitchen version always returns :class:`unicode` strings.
|
|
|
|
.. [#y4] :func:`yum.i18n.utf8_width_chop` performed two functions. It
|
|
returned the piece of the message that fit in a specified width and the
|
|
width of that message. In kitchen, you need to call two functions, one
|
|
for each action::
|
|
|
|
>>> # Old way
|
|
>>> utf8_width_chop(msg, 5)
|
|
(5, 'く ku')
|
|
>>> # New way
|
|
>>> from kitchen.text.display import textual_width, textual_width_chop
|
|
>>> (textual_width(msg), textual_width_chop(msg, 5))
|
|
(5, u'く ku')
|
|
|
|
.. [#y5] If the yum version of :func:`~yum.i18n.to_unicode` or
|
|
:func:`~yum.i18n.to_utf8` is given an object that is not a string, it
|
|
returns the object itself. :func:`kitchen.text.converters.to_unicode` and
|
|
:func:`kitchen.text.converters.to_bytes` default to returning the
|
|
``simplerepr`` of the object instead. If you want the yum behaviour, set
|
|
the :attr:`nonstring` parameter to ``passthru``::
|
|
|
|
>>> from kitchen.text.converters import to_unicode
|
|
>>> to_unicode(5)
|
|
u'5'
|
|
>>> to_unicode(5, nonstring='passthru')
|
|
5
|
|
|
|
.. [#y6] :func:`yum.i18n.to_str` could return either a byte :class:`str`. or
|
|
a :class:`unicode` string In kitchen you can get the same effect but you
|
|
get to choose whether you want a byte :class:`str` or a :class:`unicode`
|
|
string. Use :func:`~kitchen.text.converters.to_bytes` for :class:`str`
|
|
and :func:`~kitchen.text.converters.to_unicode` for :class:`unicode`.
|
|
|
|
.. [#y7] :func:`yum.misc.to_xml` was buggy as written. I think the intention
|
|
was for you to be able to pass a byte :class:`str` or :class:`unicode`
|
|
string in and get out a byte :class:`str` that was valid to use in an xml
|
|
file. The two kitchen functions
|
|
:func:`~kitchen.text.converters.byte_string_to_xml` and
|
|
:func:`~kitchen.text.converters.unicode_to_xml` do that for each string
|
|
type.
|
|
|
|
.. [#y8] When porting :func:`yum.i18n.exception2msg` to use kitchen, you
|
|
should setup two wrapper functions to aid in your port. They'll look like
|
|
this:
|
|
|
|
.. code-block:: python
|
|
|
|
from kitchen.text.converters import EXCEPTION_CONVERTERS, \
|
|
BYTE_EXCEPTION_CONVERTERS, exception_to_unicode, \
|
|
exception_to_bytes
|
|
def exception2umsg(e):
|
|
'''Return a unicode representation of an exception'''
|
|
c = [lambda e: e.value]
|
|
c.extend(EXCEPTION_CONVERTERS)
|
|
return exception_to_unicode(e, converters=c)
|
|
def exception2bmsg(e):
|
|
'''Return a utf8 encoded str representation of an exception'''
|
|
c = [lambda e: e.value]
|
|
c.extend(BYTE_EXCEPTION_CONVERTERS)
|
|
return exception_to_bytes(e, converters=c)
|
|
|
|
The reason to define this wrapper is that many of the exceptions in yum
|
|
put the message in the :attr:`value` attribute of the :exc:`Exception`
|
|
instead of adding it to the :attr:`args` attribute. So the default
|
|
:data:`~kitchen.text.converters.EXCEPTION_CONVERTERS` don't know where to
|
|
find the message. The wrapper tells kitchen to check the :attr:`value`
|
|
attribute for the message. The reason to define two wrappers may be less
|
|
obvious. :func:`yum.i18n.exception2msg` can return a :class:`unicode`
|
|
string or a byte :class:`str` depending on a combination of what
|
|
attributes are present on the :exc:`Exception` and what locale the
|
|
function is being run in. By contrast,
|
|
:func:`kitchen.text.converters.exception_to_unicode` only returns
|
|
:class:`unicode` strings and
|
|
:func:`kitchen.text.converters.exception_to_bytes` only returns byte
|
|
:class:`str`. This is much safer as it keeps code that can only handle
|
|
:class:`unicode` or only handle byte :class:`str` correctly from getting
|
|
the wrong type when an input changes but it means you need to examine the
|
|
calling code when porting from :func:`yum.i18n.exception2msg` and use the
|
|
appropriate wrapper.
|
|
|
|
.. _yum-i18n-init:
|
|
|
|
Initializing Yum i18n
|
|
=====================
|
|
|
|
Previously, yum had several pieces of code to initialize i18n. From the
|
|
toplevel of :file:`yum/i18n.py`::
|
|
|
|
try:.
|
|
'''
|
|
Setup the yum translation domain and make _() and P_() translation wrappers
|
|
available.
|
|
using ugettext to make sure translated strings are in Unicode.
|
|
'''
|
|
import gettext
|
|
t = gettext.translation('yum', fallback=True)
|
|
_ = t.ugettext
|
|
P_ = t.ungettext
|
|
except:
|
|
'''
|
|
Something went wrong so we make a dummy _() wrapper there is just
|
|
returning the same text
|
|
'''
|
|
_ = dummy_wrapper
|
|
P_ = dummyP_wrapper
|
|
|
|
With kitchen, this can be changed to this::
|
|
|
|
from kitchen.i18n import easy_gettext_setup, DummyTranslations
|
|
try:
|
|
_, P_ = easy_gettext_setup('yum')
|
|
except:
|
|
translations = DummyTranslations()
|
|
_ = translations.ugettext
|
|
P_ = translations.ungettext
|
|
|
|
.. note:: In :ref:`overcoming-frustration`, it is mentioned that for some
|
|
things (like exception messages), using the byte :class:`str` oriented
|
|
functions is more appropriate. If this is desired, the setup portion is
|
|
only a second call to :func:`kitchen.i18n.easy_gettext_setup`::
|
|
|
|
b_, bP_ = easy_gettext_setup('yum', use_unicode=False)
|
|
|
|
The second place where i18n is setup is in :meth:`yum.YumBase._getConfig` in
|
|
:file:`yum/__init_.py` if ``gaftonmode`` is in effect::
|
|
|
|
if startupconf.gaftonmode:
|
|
global _
|
|
_ = yum.i18n.dummy_wrapper
|
|
|
|
This can be changed to::
|
|
|
|
if startupconf.gaftonmode:
|
|
global _
|
|
_ = DummyTranslations().ugettext()
|