TJc@szddkZddkZddkZddklZddklZddklZlZl Z l Z l Z l Z ddk lZddkZddklZlZlZlZlZlZlZlZlZeddkZddkTddklZlZd d d d d ddddg Zei e!Z"ede#e$Z%ede&e'Z(dZ)ei*dZ+ei*dZ,dZ-eZ.d ei/fdYZ0e0i1i2Z1de3fdYZ4e5ddddddgZ6d e3fdYZ7de7fd YZ8d e0fd!YZ9d e0fd"YZ:e!d#jo*ddk;Z;e;i<d$e;i=e;i>BndS(%iN(tcopy(twarn(tifiltertcounttchaintiziptislicet ifilterfalse(tisclass( tassert_bool_attrtcallable_wo_argstunflatten_argst OrderedSett make_bunchtinstall_frameworktThreadSafeDescriptortRequestLocalDescriptortLRUCache(t*(t WidgetTypet WidgetsListtWidgetRtWidgetRepeatertRepeatedWidgett WidgetBunchtRepeatingWidgetBunchtChildtvalid_idt adapt_valuet_is_initializedcsfd}|S(NcsNt|i|d}t|t o|io tn|||dS(N(tgetattrt __class__tNonet isinstanceRt _is_lockedt WidgetLocked(tselftktargst descriptor(tfunc(s0/usr/lib/python2.6/site-packages/tw/core/base.pyt __setattr__,s ((R(R)((R(s0/usr/lib/python2.6/site-packages/tw/core/base.pytonly_if_unlocked+ss^[a-zA-Z][\w\-\_\:\.]*$s^\w+$cCsXti|otS|djotSti|otd|tdtStSdS(Nt_methodspThe id %s will no longer be supported since it doesn't conform to the W3C Spec: http://www.w3.org/TR/xhtml1/#C_8i(t valid_id_retmatchtTruet_deprecated_id_reRtDeprecationWarningtFalse(ts((s0/usr/lib/python2.6/site-packages/tw/core/base.pyR8s  cBseZdZeZd6Zd6Zhdd6dd6dd6ZgZ gZ gZ e Z e ZdZeedd Zd Zeedd Zd Zeedd ZdZeeddZedZdZeeddZdZeeddZd6d6gdZedZedZd6d6gdZdZdZd6edZddZ edZ!edZ"ed Z#d!Z$d"Z%d6d#Z&d6d$Z'd6d%Z(d&Z)ed'Z*ed(Z+d)Z,d*Z-d+Z.d,Z/e0d-Z1ed6d.Z2e3d/Z4e3d0Z5d1Z6d2Z7d3Z8d4Z9e:d5Z;RS(7sD Base class for all widgets. Example: .. sourcecode:: python >>> w = Widget('foo') >>> w.id 'foo' >>> w = Widget('foo', children=[Widget('c1'), Widget('c2')]) >>> [c.id for c in w.children] ['foo_c1', 'foo_c2'] >>> [c.parent.id for c in w.children] ['foo', 'foo'] It is a **must** that all initial state is entirely determined by the arguments to this function. This means that two widgets (of the same class) that receive the same parameters must behave in exactly the same way. You should not rely on external sources inside __init__ to set initial state. If you need to fetch data from external sources, do it at :meth:`update_params` instead. Essential pre, and post initialization is done in :meth:`__new__` and :meth:`post_init` respectively. :meth:`post_init` is guaranteed to run after the instance finishes initialization and it's behavior is rather special as all post_init's in mro will be called to have a chance to set final state in the instance. Basic pre-initialization consists of binding all kw arguments to the widget instance, attaching the widget to it's parent (if given), attaching the children and copying mutable arguments listed at :attr:`params` from the class to the instance to avoid accidental manipulation. .. sourcecode:: python >>> w = Widget('foo', a=1, b=2) >>> w.id 'foo' >>> w.a 1 >>> w.b 2 Basic post-initialization consists of caching required CSS and JS resources and setting the widget as initialized preventing further modification of it's attributes. .. sourcecode:: python >>> w = Widget('foo', a='1', b='2') >>> w.a = 'bar' Traceback (most recent call last): ... WidgetLocked: The widget is locked. It's unthread-safe to alter it's attributes after initialization. Widget attributes can only be modified in this method because widgets should behave in a state-less way as they are shared among threads for multiple requests. Per request modification of variables sent to the template should be done inside :meth:`update_params` and all state flowing from parent to children should occur inside that dict. Widgets should be instantiated at import time and reused among requests, most widgets allow overriding most of their parameters (not neccesarily all of them) at display time to change behavior. You should try avoiding instantiating widgets for every request as their initialization could be quite expensive for heavily nested widgets. Request-local storage provided by the hosting framework in ``tw.framework.request`` can be used to pass state among widgets which don't share the same root. sThe id of this widget. This id is used to reference a widget from its parent ``children`` attribute and is usually the DOM id of outermost HTML tag of the widget.tidsMain CSS class for this widgett css_classs-A list with extra css classes for the widget.t css_classescCs#|io tiiS|iiSdS(N(tis_rootttwt frameworkt default_viewtparentt engine_name(R$((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt displays_ons  tdocs7 Where the widget is being displayed on cCsIditg}|iD]}|io||iqq~pdS(Nt_(tjointreversedtpatht id_path_elemR (R$t_[1]tw((s0/usr/lib/python2.6/site-packages/tw/core/base.pyR3s <s The calculated id of the widget. This string will provide a unique id for each widget in the tree in a format which allows to re-recreate the nested structure. Example:: >>> A = Widget("A", children=[ ... Widget("B", children=[ ... Widget("C") ... ]) ... ]) ... >>> C = A.c.B.c.C >>> C.id 'A_B_C' cCsQdditg}|iD]}|io||iqq~d pdS(Nt.i(R?R@RARBR (R$RCRD((s0/usr/lib/python2.6/site-packages/tw/core/base.pytkeys As A string that can be used as a key to index the dictionary of parameters sent to the root widget so it reaches this widget when displaying. Example:: >>> A = Widget("A", children=[ ... Widget("B", children=[ ... Widget("C") ... ]) ... ]) ... >>> C = A.c.B.c.C >>> C.key '.B.C' ccs'|}x|o|V|i}q WdS(N(R:(R$titem((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRAs sI Iterates a walk from this widget to the root of the tree cCs|iS(N(t_id(R$((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRBscCst|idS(Ni(tlistRA(R$((s0/usr/lib/python2.6/site-packages/tw/core/base.pytrootssThe root of this widget treecCs |idjS(N(R:R (R$((s0/usr/lib/python2.6/site-packages/tw/core/base.pyR6ss(True if the widget doesn't have a parentcKstii|||||}xZ|iD]L\}}|idp0yt|||Wqwtj o }qwXq+q+W|i|_|dj o"t | ot d|n||_ t i|_|dj o=|io tnti||_|iii|nt|_|_t|ot|to |}ng} |D]} | |i| qc~ p_|i} t| ot| to | } ng} | D]} | |i| q~ nxt|iddgD]h} yLt || d}t!|t"t#fot|}nt|| |Wqtj oqXqWg|_$t%|_&t |ddp|i'i(i)|_*n|S(si Takes care of Widget instances creation. Should not need to be overrien likely. R>s!%r is not a valid id for a Widgettcsst javascriptR4N(+tviewt Renderablet__new__t iteritemst startswithtsetattrtAttributeErrorRtorig_kwR Rt ValueErrorRHtserial_generatortnextt_serialRtWidgetInitializedtweakreftproxyR:tchildrentappendRtcRt issubclassRt _append_childt _cls_childrenRtparamsRR!RItdictt _js_callsR t _resourcesRt__name__tlowerR4(tclsR3R:R\tkwtobjR%tvteRCR^t cls_childrent_[2]tnametattr((s0/usr/lib/python2.6/site-packages/tw/core/base.pyROsP       +  ,   cOs+t|i|id|i|i||S(s Returns a cloned version of the widget instance, optionally overriding initialization parameters. This is the only way to safely "modify" a widget instance. Example:: >>> w = Widget('foo', a=2) >>> w.id, w.a ('foo', 2) >>> w2 = w.clone(a=3) >>> w2.id, w2.a ('foo', 3) R\(RRRHR\RT(R$R&Ri((s0/usr/lib/python2.6/site-packages/tw/core/base.pytclone=scOsV|i}d|i}t|t|fh}t||id|i|i||S(NtRepeatedR\(RRfttypeRRRHR\RT(R$R&RiRhtnew_namet new_class((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt _as_repeatedUs   cKsdS(sInitializes a Widget instance. `id` The widget's id. All widgets in the same level of nested widgets trees should have distinct ids. `parent` A reference to the widget's parent. This parent needs to be in an uninitialized state which means it can only be passed to a child inside the parent's __init__ method. `children` A list, or WidgetsList (instance or class) or any other iterable with a reference to the children this widget should have. `\*\*kw` Any other extra keyword arguments for the widget. All of these will get bound to the Widget instance. N((R$R3R:R\Ri((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt__init__bsc Cs|i}|itg}|iD]}||iq ~|itg}|iD]}||iqT~|itg}|iD]}||iq~dS(s-picks up resources from self and all childrenN(Retadd_allRRKRLR\(R$tosetRCR^Rnt_[3]((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt_collect_resources|s 44cOst|idjo0ddkl}|ii|d|in|i|i ptt |_|i ptt |_ dS(s This method is called for all :class:`tw.api.Widget` base classes to perform final setup after the widget is initialized but before it is locked. ii(tJSFunctionCallstfunction_callsN( tlenRdttw.core.resourcesR|RLR]R{RtAssertionErrorR.R"(R$R&RiR|((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt post_inits   cs4fd}ot|S|S(s Does a pre-order walk on widget tree rooted at self optionally applying a filter on them. Example:: >>> W = Widget >>> w = W('a', children=[W('b', children=[W('c')]), W('d')]) >>> ''.join(i._id for i in w.walk()) 'abcd' >>> ''.join(i._id for i in w.walk(lambda x: not x.is_root)) 'bcd' >>> ''.join(i._id for i in w.walk(lambda x: x._id == 'c')) 'c' Recursion can be prevented on children that not match filter. >>> ''.join(i._id for i in w.walk(lambda x: x._id == 'c', False)) '' c3smVti}o oi}nx0|D](}x|iD] }|VqVWq=WdS(N(titerR\tifilter_childrentwalk(titeratorR^RD(R$tfiltertrecur_if_filtered(s0/usr/lib/python2.6/site-packages/tw/core/base.pyt_walks(R(R$RRR((RR$Rs0/usr/lib/python2.6/site-packages/tw/core/base.pyRst bodybottomcCsH|io$ddkl}|i||n|iit|dS(so Adds a :func:`tw.api.js_function` call that will be made when the widget is rendered. i(tdynamic_js_callsN(RRRt inject_callRdR]tstr(R$tcalltlocationR((s0/usr/lib/python2.6/site-packages/tw/core/base.pytadd_calls cCstdtdgS(NsZretrieve_css is deprecated. Please use retrieve_resources instead and filter them yourselfi(RR0(R$((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt retrieve_csss cCstdtdgS(Nsaretrieve_javascript is deprecated. Please use retrieve_resources instead and filter them yourselfi(RR0(R$((s0/usr/lib/python2.6/site-packages/tw/core/base.pytretrieve_javascripts cCsRddkl}td|D}x%|iD]}||ii|q0W|S(s Returns a dict keyed by location with ordered collections of resources from this widget and its children as values. i(t locationscss"x|]}|tfVqWdS(N(R (t.0R%((s0/usr/lib/python2.6/site-packages/tw/core/base.pys s (ttw.apiRRcReRtadd(R$Rt resourcestr((s0/usr/lib/python2.6/site-packages/tw/core/base.pytretrieve_resourcess  cCst|doVx|iiD];\}}t|djo|d||>> class MyWidget(Widget): ... params = ["foo", "bar", "null"] ... foo = "foo" ... >>> w = MyWidget('test', bar=lambda: "bar") >>> d = {} >>> w.update_params(d) >>> d['bar'] 'bar' >>> d['foo'] 'foo' >>> d['null'] is None True >>> d = {'foo':'overriden'} >>> w.update_params(d) >>> d['foo'] 'overriden' sAutocalling param '%s'N( Rt __contains__RbRR R!RIRcRRR tlogtdebug(R$RR%Rp((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRXs* cCst||iS(s Returns an iterator for all children applying a filter to them. .. sourcecode:: python >>> class Widgets(WidgetsList): ... aa = Widget() ... ab = Widget() ... ba = Widget() ... bb = Widget() ... >>> w = Widget(children=Widgets) >>> [c.id for c in w.ifilter_children(lambda w: w.id.startswith('a'))] ['aa', 'ab'] (RR\(R$R((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRscsfd}|S(Ncsot|dotto |i}n.t|totto |i}ny |SWqttt fj o dqXndS(Nt repetition( RR!RIRRRcRHt IndexErrortKeyErrort TypeErrorR (tchild_id(R(s0/usr/lib/python2.6/site-packages/tw/core/base.pyt value_getters    ((R$RR((Rs0/usr/lib/python2.6/site-packages/tw/core/base.pyRs cs3ttotnfd}|S(Ncst|dotto |i}n.t|totto |i}ny |SWnttt fj ohSXdS(NR( RR!RIRRRcRHRRR(R(R(s0/usr/lib/python2.6/site-packages/tw/core/base.pyt args_getters   (R!RcR (R$RR((Rs0/usr/lib/python2.6/site-packages/tw/core/base.pyRs cCsSt|to|i|n/t|to||ntd|dS(sAppend an object as a childs)Can only append Widgets or Childs, not %rN(R!Rt _append_toRRU(R$Rj((s0/usr/lib/python2.6/site-packages/tw/core/base.pyR`s cCs |i|S(N(Rq(R$R:((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRscCsti|||dS(N(tobjectR)(R$R%Rk((s0/usr/lib/python2.6/site-packages/tw/core/base.pyR)scCsti||dS(N(Rt __delattr__(R$R%((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRscCs)|ii}d||i|i|ifS(Ns%s(%r, children=%r, **%r)(RRfRHR\RT(R$Ro((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt__repr__s cCs |iS(N(R(R$((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt__str__scCs ||j S(N((R$tother((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt__ne__scCsRt|dd|ijo6|i|ijo#|i|ijo|i|ijS(NR(RR RRHR\RT(R$R((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt__eq__scsfd}|S(NcsSt|ttfo|}n|}|i||i||S(N(R!t basestringtinttupdateR(twidgetRitchild_kw(RRR\(s0/usr/lib/python2.6/site-packages/tw/core/base.pyRs   ((R\RRR((RR\Rs0/usr/lib/python2.6/site-packages/tw/core/base.pyRsN(<Rft __module__t__doc__Rt __metaclass__R R:RRbRKRLR5R1RR"R<tpropertyR3RFRARBRJR6ROtonly_if_initializedRqRvRwR{RR.RRRRRRRRRRRRRRRRRtonly_if_uninitializedR`RR*R)RRRRRt staticmethodR(((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRIs~O               D  "       ( 7        cBs/eZdZdZdgdZddZRS( s Prepares a Widget to being attached to a parent Widget. Creates a Widget instance with supplied arguments to the constructor when called (optionally overriding default arguments). >>> c = Child(Widget, 'foo') >>> w = c() >>> w.id 'foo' Parameters can be overriden when called. >>> w = c(id='bar') >>> w.id 'bar' t widget_classR3R\RicKs*|||_|_|||_|_dS(N(RR3R\Ri(R$RR3R\Ri((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRwscKsK|ii}|id|id|d|i|i||i|S(NR3R:R\(RiRRR3R\R(R$R:Ritkw_((s0/usr/lib/python2.6/site-packages/tw/core/base.pyR s" (s widget_classsidschildrenskwN(RfRRt __slots__R RwR(((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRst _widget_lstt _widget_dctt_widgett _repetitionst_parentt_repetition_cachecBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d d ddZdZdZdZdZdZdZe ZdZRS(s An ordered collection of widgets. >>> from tw.core import Widget >>> wb = WidgetBunch(Widget('foo'), Widget('bar')) >>> wb[0].id == 'foo' True >>> wb[1].id == 'bar' True Exposes a mixed dict/list interface which permits indexing both by widget id and position. >>> wb['foo'] == wb[0] True >>> wb['bar'] == wb[1] True Also permits attribute access as long as the attribute doesn't conflict with an internal attribute, in case of conflict the internal attrbute will prevail. >>> wb.foo.id == 'foo' True >>> wb.append(Widget('append')) >>> wb.append.id Traceback (most recent call last): ... AttributeError: 'function' object has no attribute 'id' >>> wb['append'].id == 'append' True Iteration is also supported >>> [w.id for w in wb] ['foo', 'bar', 'append'] Some dict-like iterators too >>> [id for id in wb.iterkeys()] ['foo', 'bar', 'append'] >>> [id for id in wb.keys()] ['foo', 'bar', 'append'] >>> [w.id for w in wb.itervalues()] ['foo', 'bar', 'append'] >>> [w.id for w in wb.values()] ['foo', 'bar', 'append'] cGs4g|_h|_x|D]}|i|qWdS(N(RRR](R$R&twid((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRwcs   cCs|i|i|dS(N(R)RH(R$R((s0/usr/lib/python2.6/site-packages/tw/core/base.pyR]iscCs1t}x!|D]}|i|iqW|S(N(R RxR(R$Rytchild((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRls  cCs1t}x!|D]}|i|iqW|S(N(R RxR(R$RyR((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRrs  cCsTddkl}l}td|D}x!|D]}|||iq3W|S(Ni(tmerge_resourcesRcss"x|]}|tfVqWdS(N(R (RR%((s0/usr/lib/python2.6/site-packages/tw/core/base.pys zs (RRRRcR(R$RRRRD((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRxs cCsIt|to |i|St|to |i|Std|dS(NsNo widget by %r(R!RRRRR(R$RG((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt __getitem__s   cCsQ|tjoti||Sy ||SWn tj otd|nXdS(NsNo widget by %r(t_WidgetBunch_attrsRt__getattribute__RRS(R$Ro((s0/usr/lib/python2.6/site-packages/tw/core/base.pyt __getattr__s   cCsB|tjoti|||S|ii|||i||djo |i}nxt|D]}||Vq'WdS(N(R Rtxrange(R$trepsti((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRs    cCst|tptdny|i|}WnKtj o?|iid|}ti|d|i||i|}||i ||d |i t |dj||q~}d id |D|d s toutput(RRRRRR RR0RtmaxR~RRRR?(R$Rtv_fta_fRCRDtoutputs((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRs  lN(RfRRbR RRRRRBttemplateRRFROR(((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRs cBs5eZdgZdZedZedZRS(RicCsd|i|ipdfS(Ns%s-%di(RHR(R$((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRBscOs|i||S(N(Rq(R$R&Ri((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRvs(RfRRbRRRBRRv(((s0/usr/lib/python2.6/site-packages/tw/core/base.pyRs t__main__t optionflags(?treRZtloggingRtwarningsRt itertoolsRRRRRRtinspectRR7tutilR R R R R RRRRRMt exceptionstmetaRRt__all__t getLoggerRfRR.tWidgetUninitializedRR1RYRR*tcompileR,R/RRVRNRRtim_funcRRt frozensetRRRRRtdoctestttestmodtELLIPSIStNORMALIZE_WHITESPACE(((s0/usr/lib/python2.6/site-packages/tw/core/base.pytsV$. @       '  ,