# HG changeset patch # User Yuya Nishihara # Date 1471146681 -32400 # Node ID 45fa8de47a0f033428b29d4bb8a6291fb16019da # Parent 31d588fcd2b9453f6ffe062075f878a5885290ef py3: provide (del|get|has|set)attr wrappers that accepts bytes These functions will be imported automagically by our code transformer. getattr() and setattr() are widely used in our code. We wouldn't probably want to rewrite every single call of getattr/setattr. delattr() and hasattr() aren't that important, but they are functions of the same kind. diff -r 31d588fcd2b9 -r 45fa8de47a0f mercurial/pycompat.py --- a/mercurial/pycompat.py Sun Aug 14 12:44:13 2016 +0900 +++ b/mercurial/pycompat.py Sun Aug 14 12:51:21 2016 +0900 @@ -31,8 +31,22 @@ if sys.version_info[0] >= 3: import builtins + import functools builtins.xrange = range + def _wrapattrfunc(f): + @functools.wraps(f) + def w(object, name, *args): + if isinstance(name, bytes): + name = name.decode(u'utf-8') + return f(object, name, *args) + return w + + delattr = _wrapattrfunc(builtins.delattr) + getattr = _wrapattrfunc(builtins.getattr) + hasattr = _wrapattrfunc(builtins.hasattr) + setattr = _wrapattrfunc(builtins.setattr) + stringio = io.StringIO empty = _queue.Empty queue = _queue.Queue