| Package | Ready | Patches | Unavailable |
| lxml | X | ||
| python-dateutil | X | ||
| polib | X | ||
| (real) database connectors | X | ||
| Genshi | X(*) | ||
| relatorio | X | ||
| pywebdav | X | ||
| LDAP | X |
Most libraries are ported and those that are not have patches. One notable exception: python-ldap.
sql_format of fields.Char
def sql_format(value):
if value is None:
return None
- elif isinstance(value, str):
- return str(value, 'utf-8')
- assert isinstance(value, str)
return value
some bytes vs buffer
'minute': obj.minute,
'second': obj.second,
}
- elif isinstance(obj, buffer):
+ elif isinstance(obj, bytes):
return {'__class__': 'buffer',
- 'base64': base64.encodestring(obj),
+ 'base64': base64.encodestring(obj).decode('utf-8'),
}
elif isinstance(obj, Decimal):
return {'__class__': 'Decimal',
sqlite way to store NUMERIC
select += ' OFFSET %d' % offset
return select
-sqlite.register_converter('NUMERIC', lambda val: Decimal(val))
+sqlite.register_converter('NUMERIC', lambda val: Decimal(val.decode('utf-8')))
if sys.version_info[0] == 2:
sqlite.register_adapter(Decimal, lambda val: buffer(str(val)))
else:
- sqlite.register_adapter(Decimal, lambda val: bytes(str(val)))
+ sqlite.register_adapter(Decimal, lambda val: str(val).encode('utf-8'))
Should be OK since:
>>> x = Decimal(…) >>> Decimal(bytes(str(x)).decode('utf-8')) == x
e.g. trytond/protocols/jsonrpc.py
existing method through subclassing is the prefered means
of changing method dispatch behavior.
"""
- rawreq = json.loads(data, object_hook=object_hook)
+ rawreq = json.loads(data.decode('utf-8'), object_hook=object_hook)
req_id = rawreq.get('id', 0)
method = rawreq['method']
e.g. trytond/protocols/jsonrpc.py
# report exception back to server
response['error'] = (str(sys.exc_info()[1]), tb_s)
- return json.dumps(response, cls=JSONEncoder)
+ return json.dumps(response, cls=JSONEncoder).encode('utf-8')
- not so many issues
- patch for PY3 compatibility is ready for trytond
- modules migration: currently all modules up until stock are migrated
- There is the python-ldap problem
import timeit def avg(lst): return sum(lst) / len(lst) def std_dev(lst): return math.sqrt(sum((x - (sum(lst) / len(lst))) ** 2 for x in lst) / len(lst)) results = timeit.repeat('{}()'.format(sys.argv[1]), repeat=5, number=100, setup='from __main__ import {}'.format(sys.argv[1])) print('{0:.6}s ± {1:.5}'.format(avg(results), std_dev(results)))
| Test | python2.7 | python3.2 |
| test_stock | 28.5806s ± 0.3398 | 30.2421s ± 0.4267 |
This benchmarks mainly test the initialization of the database.
≃ 6% slower
def pool_initialization(): dbname = 'db_py3' Pool.start() pool = Pool(dbname) with Transaction().start(dbname, 0): pool.init()
| Test | python2.7 | python3.2 |
| pool init | 9.11617s ± 0.0768 | 9.35978s ± 0.0950 |
≃ 3% slower
def test_module_list(): dbname = 'db_py3' Pool.start() pool = Pool(dbname) with Transaction().start(dbname, 0, context={}): pool.init() module_obj = pool.get('ir.module.module') module_obj.search([('state', '=', 'installed')])
| Test | python2.7 | python3.2 |
| list modules | 9.2981s ± 0.064182 | 9.75338s ± 0.06838 |
≃ 5% slower
shipments = [] for _ in range(30): ship_id = shipment_in_obj.create({ 'supplier': supplier, 'company': company, 'incoming_moves': [('create', { 'product': product, 'quantity': 50, 'uom': unit, 'from_location': supplier_location, 'to_location': input_location, 'company': company, 'unit_price': Decimal(4), })]}) shipments.append(ship_id) received_ids = [x for x in shipments if x % 2] done_ids = [x for x in received_ids if x % 3] cancel_received_ids = [x for x in received_ids if not x % 3] cancel_other_ids = [x for x in shipments if not x % 2] shipment_in_obj.receive(received_ids) shipment_in_obj.done(done_ids) shipment_in_obj.cancel(cancel_received_ids) shipment_in_obj.cancel(cancel_other_ids)
| Test | python2.7 | python3.2 |
| use stock move | 2200.21s ± 15.273 | 2195.2s ± 70.102 |
≃ no difference
| Table of Contents | t |
|---|---|
| Exposé | ESC |
| Full screen slides | e |
| Presenter View | p |
| Source Files | s |
| Slide Numbers | n |
| Toggle screen blanking | b |
| Show/hide slide context | c |
| Notes | 2 |
| Help | h |