Mercurial > hg
view mercurial/pycompat.py @ 29837:5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
We sometimes need to build nested items by formatter, but there was no
convenient way other than building and putting them manually by fm.data():
exts = []
for n, v in extensions:
fm.plain('%s %s\n' % (n, v))
exts.append({'name': n, 'ver': v})
fm.data(extensions=exts)
This should work for simple cases, but doing this would make it harder to
change the underlying data type for better templating support.
So this patch provides fm.nested(field), which returns new nested formatter
(or self if items aren't structured and just written to ui.) A nested formatter
stores items which will later be rendered by the parent formatter.
fn = fm.nested('extensions')
for n, v in extensions:
fn.startitem()
fn.write('name ver', '%s %s\n', n, v)
fn.end()
Nested items are directly exported to a template for now:
{extensions % "{name} {ver}\n"}
There's no {extensions} nor {join(extensions, sep)} yet. I have a plan for
them by extending fm.nested() API, but I want to revisit it after trying
out this API in the real world.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 13 Mar 2016 19:59:39 +0900 |
parents | c63ab0524db7 |
children | 0f6d6fdd3c2a |
line wrap: on
line source
# pycompat.py - portability shim for python 3 # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. """Mercurial portability shim for python 3. This contains aliases to hide python version-specific details from the core. """ from __future__ import absolute_import import sys if sys.version_info[0] < 3: import cPickle as pickle import cStringIO as io import httplib import Queue as _queue import SocketServer as socketserver import urlparse import xmlrpclib else: import http.client as httplib import io import pickle import queue as _queue import socketserver import urllib.parse as urlparse import xmlrpc.client as xmlrpclib if sys.version_info[0] >= 3: import builtins import functools 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 # these wrappers are automagically imported by hgloader delattr = _wrapattrfunc(builtins.delattr) getattr = _wrapattrfunc(builtins.getattr) hasattr = _wrapattrfunc(builtins.hasattr) setattr = _wrapattrfunc(builtins.setattr) xrange = builtins.range stringio = io.StringIO empty = _queue.Empty queue = _queue.Queue class _pycompatstub(object): def __init__(self): self._aliases = {} def _registeraliases(self, origin, items): """Add items that will be populated at the first access""" self._aliases.update((item.replace('_', '').lower(), (origin, item)) for item in items) def __getattr__(self, name): try: origin, item = self._aliases[name] except KeyError: raise AttributeError(name) self.__dict__[name] = obj = getattr(origin, item) return obj httpserver = _pycompatstub() urlreq = _pycompatstub() urlerr = _pycompatstub() if sys.version_info[0] < 3: import BaseHTTPServer import CGIHTTPServer import SimpleHTTPServer import urllib2 import urllib urlreq._registeraliases(urllib, ( "addclosehook", "addinfourl", "ftpwrapper", "pathname2url", "quote", "splitattr", "splitpasswd", "splitport", "splituser", "unquote", "url2pathname", "urlencode", )) urlreq._registeraliases(urllib2, ( "AbstractHTTPHandler", "BaseHandler", "build_opener", "FileHandler", "FTPHandler", "HTTPBasicAuthHandler", "HTTPDigestAuthHandler", "HTTPHandler", "HTTPPasswordMgrWithDefaultRealm", "HTTPSHandler", "install_opener", "ProxyHandler", "Request", "urlopen", )) urlerr._registeraliases(urllib2, ( "HTTPError", "URLError", )) httpserver._registeraliases(BaseHTTPServer, ( "HTTPServer", "BaseHTTPRequestHandler", )) httpserver._registeraliases(SimpleHTTPServer, ( "SimpleHTTPRequestHandler", )) httpserver._registeraliases(CGIHTTPServer, ( "CGIHTTPRequestHandler", )) else: import urllib.request urlreq._registeraliases(urllib.request, ( "AbstractHTTPHandler", "addclosehook", "addinfourl", "BaseHandler", "build_opener", "FileHandler", "FTPHandler", "ftpwrapper", "HTTPHandler", "HTTPSHandler", "install_opener", "pathname2url", "HTTPBasicAuthHandler", "HTTPDigestAuthHandler", "HTTPPasswordMgrWithDefaultRealm", "ProxyHandler", "quote", "Request", "splitattr", "splitpasswd", "splitport", "splituser", "unquote", "url2pathname", "urlopen", )) import urllib.error urlerr._registeraliases(urllib.error, ( "HTTPError", "URLError", )) import http.server httpserver._registeraliases(http.server, ( "HTTPServer", "BaseHTTPRequestHandler", "SimpleHTTPRequestHandler", "CGIHTTPRequestHandler", ))