<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" >

  <channel>
    <title><![CDATA[Комментарии к публикации «Trafaret — библиотека для проверки и преобразования данных»]]></title>
    <link>https://habr.com/ru/articles/139927/</link>
    <description><![CDATA[Комментарии к публикации «Trafaret — библиотека для проверки и преобразования данных»]]></description>
    <language>ru</language>
    <managingEditor>editor@habr.com</managingEditor>
    <generator>habr.com</generator>
    <pubDate>Wed, 21 Oct 2026 08:29:56 GMT</pubDate>
    
    
      <image>
        <link>https://habr.com/ru/</link>
        <url>https://habrastorage.org/webt/ym/el/wk/ymelwk3zy1gawz4nkejl_-ammtc.png</url>
        <title>Хабр</title>
      </image>
    

    
      

      
        
  
    <item>
      <title>29.05.2012 13:05:24 Deepwalker</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/139927/#comment_4863421</guid>
      <link>https://habr.com/ru/articles/139927/#comment_4863421</link>
      <description><![CDATA[Черт, а почему я не видел этот комментарий раньше?<br/>
Добавлю в мастер.]]></description>
      <pubDate>Tue, 29 May 2012 13:05:24 GMT</pubDate>
      <dc:creator><![CDATA[Deepwalker]]></dc:creator>
    </item>
  

  
    <item>
      <title>16.05.2012 11:10:40 Astynax</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/139927/#comment_4828476</guid>
      <link>https://habr.com/ru/articles/139927/#comment_4828476</link>
      <description><![CDATA[Библиотечка очень понравилась. Предложу ещё добавить:<br/>
<pre><code class="python">import itertools
import trafaret as t

class Tuple(t.Trafaret):

    def __init__(self, *args):
        self._trafarets = map(self._trafaret, args)
        self._traf_cnt = len(self._trafarets)

    def _check(self, value):
        try:
            value = tuple(value)
        except TypeError:
            self._failure('value must be convertable to tuple')

        if len(value) != self._traf_cnt:
            self._failure('value must contain exact %s items' % self._traf_cnt)

        result = []
        errors = {}
        for idx, item, traf in itertools.izip(itertools.count(), value, self._trafarets):
            try:
                result.append(traf.check(item))
            except t.DataError as err:
                errors[idx] = err

        if errors:
            self._failure(errors)
        return tuple(result)


if __name__ == '__main__':
    pair = t.Or(Tuple(int, str), Tuple(str, str)) &gt;&gt; (lambda x: '%s%s' % x)
    print pair.check((1, 'a'))
    print pair.check(('2', 'b'))

</code></pre>]]></description>
      <pubDate>Wed, 16 May 2012 11:10:40 GMT</pubDate>
      <dc:creator><![CDATA[Astynax]]></dc:creator>
    </item>
  

  
    <item>
      <title>15.03.2012 13:35:30 Deepwalker</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/139927/#comment_4679250</guid>
      <link>https://habr.com/ru/articles/139927/#comment_4679250</link>
      <description><![CDATA[Вы можете взять идею и применить ее к FormEncode, я думаю. Я бы посмотрел на результат.]]></description>
      <pubDate>Thu, 15 Mar 2012 13:35:30 GMT</pubDate>
      <dc:creator><![CDATA[Deepwalker]]></dc:creator>
    </item>
  

  
    <item>
      <title>14.03.2012 23:11:14 Ghostwriter</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/139927/#comment_4677662</guid>
      <link>https://habr.com/ru/articles/139927/#comment_4677662</link>
      <description><![CDATA[Мне кажется, что примерно одинаково. API шире, да. Но никто не заставляет лезть глубоко вовнутрь.<br/>
<br/>
<code><pre><code class="python">from formencode import Schema, validators as v
from pprint import pprint
import hashlib



MD5Password = v.Wrapper(
    not_empty=True,
    to_python=lambda d: hashlib.md5(d).hexdigest()
)

RolesList = v.Wrapper(
    to_python=lambda d: [s.strip() for s in d.split(',')]
)


class RequiredString(v.UnicodeString):
    not_empty = True


class MapFields(v.FormValidator):
    _fields_mapping = {
        'userNameFirst': 'name',
        'userNameSecond': 'second_name',
        'userPassword': 'password',
        'userEmail': 'email',
        'userTitle': 'title',
        'userRoles':'roles'
    }

    def _to_python(self, fields, state):
    	result = {}
    	for key, value in self._fields_mapping.iteritems():
            result[value] = fields[key]
    	return result


class Converter(Schema):
    # FormEncode's Declarative API attributes
    allow_extra_fields = True
    filter_extra_fields = True

    # Our own attributes and fields
    userNameFirst = RequiredString
    userNameSecond = RequiredString
    userPassword = MD5Password
    userEmail = v.Email
    userTitle = v.UnicodeString(if_missing='Bachelor')
    userRoles = RolesList

    chained_validators = [MapFields]



# Test the module
if __name__ == '__main__':
    sample_data = {
        'userNameFirst': 'Adam',
        'userNameSecond': 'Smith',
        'userPassword': 'supersecretpassword',
        'userEmail': 'adam@smith.math.edu',
        'userRoles': 'teacher, worker, admin',
    }

    desired_data = {
        'name': 'Adam',
        'second_name': 'Smith',
        'password': hashlib.md5('supersecretpassword').hexdigest(),
        'email': 'adam@smith.math.edu',
        'title': 'Bachelor',
        'roles': ['teacher', 'worker', 'admin'],
    }
    data = Converter.to_python(sample_data)
    assert data == desired_data
    pprint(data)

</code></pre></code><br/>
<br/>
Мне нравится, что в вашем примере библиотека избавляет вас от необходимости дублировать названия полей в нескольких местах. Также, нравится наличие fold/unfold утилит.<br/>
Но мне кажется, что вы не совсем удачно выбрали Contract в качестве базовой библиотеки. Сейчас б<i>о</i>льшая функциональность Trafaret, связанная с проверкой и конвертацией, дублирует то, что есть в схемах FormEncode. Однако я не могу использовать схемы FormEncode для тех утилит, которые есть в Trafaret помимо этого. В итоге — плохая интероперабельность, связанная с выбором Contract, которая взамен не предоставляет разработчику никаких плюсов.<br/>
]]></description>
      <pubDate>Wed, 14 Mar 2012 23:11:14 GMT</pubDate>
      <dc:creator><![CDATA[Ghostwriter]]></dc:creator>
    </item>
  

  
    <item>
      <title>14.03.2012 18:59:30 Deepwalker</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/139927/#comment_4677187</guid>
      <link>https://habr.com/ru/articles/139927/#comment_4677187</link>
      <description><![CDATA[Они все таки о разном. Trafaret предлагает легкий путь разобрать некие данные прилетевшие извне, и частично декларативно перегнать их во внутреннюю форму.<br/>
<br/>
А FormEncode это хорошие валидаторы плюс формы. У нее круг задач другой, и шире, и там все сложнее. Поэтому в своем классе задач каждая из библиотек хороша. ]]></description>
      <pubDate>Wed, 14 Mar 2012 18:59:30 GMT</pubDate>
      <dc:creator><![CDATA[Deepwalker]]></dc:creator>
    </item>
  

  
    <item>
      <title>14.03.2012 15:22:40 Ghostwriter</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/139927/#comment_4676584</guid>
      <link>https://habr.com/ru/articles/139927/#comment_4676584</link>
      <description><![CDATA[Какие преимущества перед FormEncode?]]></description>
      <pubDate>Wed, 14 Mar 2012 15:22:40 GMT</pubDate>
      <dc:creator><![CDATA[Ghostwriter]]></dc:creator>
    </item>
  

  
    <item>
      <title>14.03.2012 11:04:43 Deepwalker</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/139927/#comment_4675362</guid>
      <link>https://habr.com/ru/articles/139927/#comment_4675362</link>
      <description><![CDATA[Вернусь с прогулки — допишу.]]></description>
      <pubDate>Wed, 14 Mar 2012 11:04:43 GMT</pubDate>
      <dc:creator><![CDATA[Deepwalker]]></dc:creator>
    </item>
  

  
    <item>
      <title>14.03.2012 10:56:38 nimnull</title>
      <guid isPermaLink="true">https://habr.com/ru/articles/139927/#comment_4675318</guid>
      <link>https://habr.com/ru/articles/139927/#comment_4675318</link>
      <description><![CDATA[Миш, я бы еще добавил чуть про ошибки валидации — это чуть ли не самая интересная тема после самой декларации структуры данных.]]></description>
      <pubDate>Wed, 14 Mar 2012 10:56:38 GMT</pubDate>
      <dc:creator><![CDATA[nimnull]]></dc:creator>
    </item>
  


      

      

    
  </channel>
</rss>
