PKK4~7zope/__init__.py# namespace package boilerplate try: __import__('pkg_resources').declare_namespace(__name__) except ImportError, e: from pkgutil import extend_path __path__ = extend_path(__path__, __name__) PKM4w Czope/__init__.pyc; 3Dc@sOyedieWn1ej o%ZdklZeeeZnXdS(s pkg_resources(s extend_pathN(s __import__sdeclare_namespaces__name__s ImportErrorsespkgutils extend_paths__path__(ses extend_paths__path__((s+build/bdist.linux-i686/egg/zope/__init__.pys?s PKKM4-(Mzope/thread/__init__.py############################################################################## # # Copyright (c) 2004 Zope Corporation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Thread-local objects Thread-local objects support the management of thread-local data. If you have data that you want to be local to a thread, simply create a thread-local object and use it's attributes: >>> import zope.thread >>> mydata = zope.thread.local() >>> mydata.__class__.__name__ 'local' >>> mydata.number = 42 >>> mydata.number 42 You can also access the local-object's dictionary: >>> mydata.__dict__ {'number': 42} >>> mydata.__dict__.setdefault('widgets', []) [] >>> mydata.widgets [] What's important about thread-local objects is that their data are local to a thread. If we access the data in a different thread: >>> log = [] >>> def f(): ... items = mydata.__dict__.items() ... items.sort() ... log.append(items) ... mydata.number = 11 ... log.append(mydata.number) >>> import threading >>> thread = threading.Thread(target=f) >>> thread.start() >>> thread.join() >>> log [[], 11] we get different data. Furthermore, changes made in the other thread don't affect data seen in this thread: >>> mydata.number 42 Of course, values you get from a local object, including a __dict__ attribute, are for whatever thread was current at the time the attribute was read. For that reason, you generally don't want to save these values across threads, as they apply only to the thread they came from. You can create custom local objects by subclassing the local class: >>> class MyLocal(zope.thread.local): ... number = 2 ... initialized = False ... def __init__(self, **kw): ... if self.initialized: ... raise SystemError('__init__ called too many times') ... self.initialized = True ... self.__dict__.update(kw) ... def squared(self): ... return self.number ** 2 This can be useful to support default values, methods and initialization. Note that if you define an __init__ method, it will be called each time the local object is used in a separate thread. This is necessary to initialize each thread's dictionary. Now if we create a local object: >>> mydata = MyLocal(color='red') Now we have a default number: >>> mydata.number 2 an initial color: >>> mydata.color 'red' >>> del mydata.color And a method that operates on the data: >>> mydata.squared() 4 As before, we can access the data in a separate thread: >>> log = [] >>> thread = threading.Thread(target=f) >>> thread.start() >>> thread.join() >>> log [[('color', 'red'), ('initialized', True)], 11] without effecting this threads data: >>> mydata.number 2 >>> mydata.color Traceback (most recent call last): ... AttributeError: 'MyLocal' object has no attribute 'color' Note that subclasses can define slots, but they are not thread local. They are shared across threads: >>> class MyLocal(zope.thread.local): ... __slots__ = 'number' >>> mydata = MyLocal() >>> mydata.number = 42 >>> mydata.color = 'red' So, the separate thread: >>> thread = threading.Thread(target=f) >>> thread.start() >>> thread.join() affects what we see: >>> mydata.number 11 $Id: __init__.py 27165 2004-08-17 11:20:31Z hdima $ """ try: import _zope_thread except ImportError: from threading import currentThread, enumerate, RLock class _localbase(object): __slots__ = '_local__key', '_local__args', '_local__lock' def __new__(cls, *args, **kw): self = object.__new__(cls) key = '_local__key', 'thread.local.' + str(id(self)) object.__setattr__(self, '_local__key', key) object.__setattr__(self, '_local__args', (args, kw)) object.__setattr__(self, '_local__lock', RLock()) if args or kw and (cls.__init__ is object.__init__): raise TypeError("Initialization arguments are not supported") # We need to create the thread dict in anticipation of # __init__ being called, to make sire we don't cal it # again ourselves. dict = object.__getattribute__(self, '__dict__') currentThread().__dict__[key] = dict return self def _patch(self): key = object.__getattribute__(self, '_local__key') d = currentThread().__dict__.get(key) if d is None: d = {} currentThread().__dict__[key] = d object.__setattr__(self, '__dict__', d) # we have a new instance dict, so call out __init__ if we have # one cls = type(self) if cls.__init__ is not object.__init__: args, kw = object.__getattribute__(self, '_local__args') cls.__init__(self, *args, **kw) else: object.__setattr__(self, '__dict__', d) class local(_localbase): def __getattribute__(self, name): lock = object.__getattribute__(self, '_local__lock') lock.acquire() try: _patch(self) return object.__getattribute__(self, name) finally: lock.release() def __setattr__(self, name, value): lock = object.__getattribute__(self, '_local__lock') lock.acquire() try: _patch(self) return object.__setattr__(self, name, value) finally: lock.release() def __delattr__(self, name): lock = object.__getattribute__(self, '_local__lock') lock.acquire() try: _patch(self) return object.__delattr__(self, name) finally: lock.release() def __del__(): threading_enumerate = enumerate __getattribute__ = object.__getattribute__ def __del__(self): key = __getattribute__(self, '_local__key') try: threads = list(threading_enumerate()) except: # if enumerate fails, as it seems to do during # shutdown, we'll skip cleanup under the assumption # that there is nothing to clean up return for thread in threads: try: __dict__ = thread.__dict__ except AttributeError: # Thread is dying, rest in peace continue if key in __dict__: try: del __dict__[key] except KeyError: pass # didn't have nything in this thread return __del__ __del__ = __del__() else: local = _zope_thread.local del _zope_thread PKKM4;<+bzope/thread/tests.py############################################################################## # # Copyright (c) 2004 Zope Corporation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Unit tests for zope.thread. $Id: tests.py 26084 2004-07-02 22:34:30Z jim $ """ def test_suite(): import unittest from doctest import DocTestSuite suite = unittest.TestSuite() suite.addTest(DocTestSuite('zope.thread')) return suite if __name__ == '__main__': unittest.main(defaultTest='test_suite') PKM4TnUUzope/thread/_zope_thread.soELFp 4F4 (# !!`t!!Qtd%)'& (# "!$% ,p     !!!@#H$!zH@m .,YZjH$q %"AH$\$4 _DYNAMIC__gmon_start___init_fini__cxa_finalize_Jv_RegisterClassesPyBaseObject_TypePyObject_IsTruePyExc_TypeErrorPyErr_SetStringPyString_FromFormatPyDict_NewPyThreadState_GetDictPyDict_SetItemPyExc_SystemErrorPyThreadState_GetPyInterpreterState_ThreadHeadPyDict_GetItemPyDict_DelItemPyThreadState_NextPyObject_GenericGetAttrPyObject_GenericSetAttrPyExc_AttributeErrorinit_zope_threadPyType_ReadyPy_InitModule4PyModule_AddObjectlibpthread.so.0libc.so.6_edata__bss_start_endGLIBC_2.1.3si @#D#l#x######## $$$,$"""""!"'"(" " """### ##### #!$#"(#%,#&U9o hhhhh h($h0(h8p,h@`0hHP4hP@8hX0<h` @hhDhpHhxLhUS[gRtX[ÐUSQ[6huDt' `PQ&dҋduƃh]Í'USP[tt P҃]ÐUWVS [Âu} 9uat= WHt-PP1e[^_]Ð&Et EPujVƃt~ EtEEFFVsPFt[FtOt WNQVRP x0e[^_]ÃPPt&'Ht 1e[^_]à FVP1'UWVu}F u&Fu5FtWPU x1e^_]ÃWPU y˸WPU y͍UVPuVtFHV tF HtfVtFHt?VtFHt1uÐ BRP1uÍ BRP벐 BRP닐 BRPa&'UWVS [}OtqPth@ta PƃtO F@t'WRPtOQV@R9 V ƃu WG<$e[^_]UWVS ["(Et\wVMQ1ƃtbW9ttGHtwe[^_]Ív' BRP؃P8W 1ƅu1RPGPEPEHtuEx׋WtGHtiwG;SPGPG PW҃<WuV1" FVPy BRP UWVS [òu} n…tH9FtWVe[^_]Ð&WRte[^_]Ðt&1e[^_]ÍUVS[6ut!PEPE PVe[^]Ð&e[^]Ít&USP[EPt @]ÃTPP'1]É'UVS[Ö Vx? hjPlPPƒ tPV. O## ## # ### # A#$ #(#,#0u #4B "O#8Q&O#<3(o#@,3#Dp -A#F .#G2#H7;#LA>#TB>#XDO#\F#`F @>] i > D  g# # :O#pi3O: ?f gO# g g# g O# g # O# # O# ] O# { # F# # T #  #$  #( #,  #0g  #4 #8  #</ V#@1  #D z #H #L #P*z#TT#XQ x#\#`e! #d$z#hQ( #l)( #p%,#t7-]#xJ .#|j/#0*#813 #2> # 3z#j4I #5 #J 6T #B 7 #8#9*#:*#;*#<*#.=*#` > #h~** * ;AV* * *ag* * * *NO * O  *u* * Or* * O O*0JO * O *U[zO * O O *O * * *O * O QbO *   ,O * O K'7=RO * *]cxO * > O * R >  0# 0# 0# G0# r0# 0# rV# E # T  #  #$ 7 #( $ #, 0#0 0#4 V0#8 0#< 0#@ O#D t #H  #L  #P = #T ( #X 0#\ ' 0#` 0#d +0#h 20#l  V#p 0#t  0#x  0#| 0# 0# {0# 0# 0# 20#ãf ( ] Ɓ# 0# v # # # # dJ# + ,# 0# #$    ԁ# 0# z#q   L ڥ# # I# Y# ޯ + W  #  *. 4 N O * N O _ e z * * K;   O * *  7     z *    * * * OY a_ e  *  * *   *  O f   Y, "# ## $O#  %#  ]- (# j )O# 8*O# +O# doc,# .  #get #set#doc# )>#c-GB;* * >E   %O * * >c_is$  h #  # *#  *#  *#  *#  *# ? *# X O# 6_tsT h 3#  4G# j 6;# 7O#  8O#  9O# ; # < #  =*#  >*#$  @*#( % A*#, 0 B*#0  D*#4 ( E*#8 3 F*#<  H*#@  JO#D  KO#H e M*#L Nz#Pm !6 );O * ; O *Ai  RM O# g #key*# [*# kw*# *# ^`#%  $ L$?o Xf !* 4*O 6*] *P Uj 0[*Bkw*u]!W"*errL $ SO $ U]R ERRu !argR>P_O0 U]^"`#t`*"s#ta*"0#tb*$H#tc*%4 i U]hjXK|}* U]|HW~*ul}~*"$`#t*";x&iO$#t** U]) *}*,*%qOU]N *u v*u}*-O*7U] )>u '!@U(m"*'/build/buildd/glibc-2.3.5/build-tree/i386-libc/csu/crtn.S/build/buildd/glibc-2.3.5/build-tree/glibc-2.3.5/csuGNU AS 2.16.1%% $ > $ > : ; I I : ;  : ;I8  &I ' I : ; : ; I8 I!I/ ' I : ;  : ; : ; I8 : ;I : ; < 4: ; I 4: ;I 4: ; I? < 4: ;I? < .: ; ' I@ : ; I: ; I 4: ; I : ;  : ; I !: ; I" U#4: ; I$ U%.: ; ' @ &4: ; I'.? : ;' @ (4: ;I%M /build/buildd/glibc-2.3.5/build-tree/i386-libc/csucrti.S3,Wd,#,:p  ,Wdd,,- src/zope/thread/home/tseaver/projects/PyCon2006/eggification/sandbox/include/python2.3/usr/include/usr/include/bits_zope_thread.cobject.hstdio.hlibio.htypes.hmethodobject.hstructmember.hdescrobject.hpyerrors.hpystate.hP (#9U Ԭd:dr,tJVMX0ss ӫ}sstyqo2dde}( sfX(yfMqr:,=z9]ZsGgGud,;2o"Jyu-q+Y&uuM /build/buildd/glibc-2.3.5/build-tree/i386-libc/csucrtn.S A | (P gAB Fn.._. dAB B`.0 AB As. AB Fj.( aAB Fe.p.Y. zAB Fo.LAB Bd.GAB At.$@mAB BV.k. X.PyMemberDeflocal_traversesq_ass_itemobjobjprocnb_inplace_remaindernb_dividetp_iterPyMethodDeftp_richcomparenb_inttp_dealloc_IO_save_endlocal_getattrovisitproctp_reprsq_item_IO_write_base_lockrecursion_depthnb_add_zope_thread_methodsnb_subtractnb_xornb_multiplytp_is_gctp_methodscurexc_traceback_IO_save_baselocal_getdictselfgetwritebufferproc_chain_ldictPyExc_AttributeError_cur_columnPyExc_SystemErrornb_absolutetp_name_modeprintfunc_objectgettertp_mroternaryfuncmp_ass_subscriptob_refcntnb_inplace_multiplynb_inplace_dividenb_oct_IO_markerPyExc_TypeErrorshort unsigned intintintargfuncnb_inplace_orgilstate_counterdescrgetfuncnb_divmodnb_true_dividecurexc_type_IO_FILEtp_subclassesPyBufferProcslocaltypeunsigned charinit_zope_thread_sbufcurexc_valuenb_inplace_true_dividebf_getsegcountPyBaseObject_Typetp_basenb_remainderbf_getwritebufferPy_tracefunctp_descr_set_IO_lock_ttp_weaklistoffsettp_hashlocal_clearml_flagstp_as_buffercodec_search_cache_IO_read_ptrnb_floatcodec_search_pathPyTypeObject_posstdinvisitgetattrofuncdlopenflagssq_ass_slicelocal_setattrotp_getattrosq_slice_markersgetreadbufferprocintintobjargproctp_dictnb_lshiftunaryfuncnewfunctp_as_mappingtp_setattrnb_inplace_addtraverseprocnb_inplace_xorclosuretp_strtp_descr_getnb_negative_flags2getiterfuncasync_exc/home/tseaver/projects/PyCon2006/eggification/sandbox/src/zope.threadtp_bases_IO_buf_base_IO_read_basesq_concatsysdictdestructor_unused2__quad_tPyNumberMethodssq_inplace_repeattp_flags_old_offsetcodec_error_registrytp_docargsGNU C 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu9)long long inttstate_headnb_inplace_lshiftml_meth_IO_write_endc_profileobjob_sizePyObjectgetsegcountprocgetcharbufferproctp_iternextnb_hextp_calltp_membersPyCFunctioninquirynb_andlocal_new_nextPyInterpreterStatetp_basicsize__pad1__pad2tick_counterdescrsetfuncuse_tracingobjobjargprocsetattrfuncPyMappingMethodstp_setattrotstatetp_cachesq_inplace_concatallocfuncnb_inverttp_weaklistlong doubletp_printnb_coercebf_getcharbuffertp_initnb_powernb_floor_dividemp_subscriptlong long unsigned intbuiltinstp_comparetp_clearinterpinitproc__off_tPyGetSetDeftp_allocnb_rshift_typeobjectlocal_getsetnb_inplace_andfreefunclocal_dealloctp_freetp_getsetnb_positivetp_deltp_as_sequencesrc/zope/thread/_zope_thread.cbinaryfunc_IO_backup_base_shortbufiternextfuncnb_longcoercion__off64_trichcmpfunchashfunctp_getattr_IO_buf_endPyThreadStatec_traceobjnb_inplace_subtractshort intsetterbf_getreadbuffertp_itemsize_frame_vtable_offsetnb_inplace_rshifttp_as_numberc_profilefuncnb_inplace_floor_dividereprfuncsetattrofuncgetattrfuncnb_orPySequenceMethodsmodulesnb_inplace_powerml_doc_IO_read_endsq_containsnb_nonzero_filenotp_newtp_traversesq_lengthob_typestdoutsq_repeat_IO_write_ptrc_tracefuncmp_lengthml_nametp_dictoffsetthread_idlocalobject//`V`hhVg/ /fWfh hW 5W5I IQWQg `eVVPVPVSgV P#PpVVpWWMVMOObVbddV^W^`PVP@V@IPIIV`|P|WWWWVPVVVP V PVVp  ppV8V8;;GVGJ W 9W9; ;HWHJ RP R*R;BPBJR P-3PBBPPooVVkoPPPP=DRDDPDSRV]P !1p8HP] 29I.symtab.strtab.shstrtab.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_frame.debug_str.debug_loc.debug_ranges@!  )1oR>o M V  _,,ZDD ep p kq2y!!!!""P@#@ H$HH@x''o,7. 1\043 ?$)(DD7K "D Q,D p     !!!!""@#H$ !" Fp  Va!o!}!H$D#    V!! !  FUL$j`#t   z L  d 0   $(P g G  a @#" !#2DV@m gv, )H$5DY _"{H$\$  initfini.c/build/buildd/glibc-2.3.5/build-tree/i386-libc/csu/crti.Scall_gmon_startcrtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST__completed.4463p.4462__do_global_dtors_auxframe_dummy__CTOR_END____DTOR_END____FRAME_END____JCR_END____do_global_ctors_aux/build/buildd/glibc-2.3.5/build-tree/i386-libc/csu/crtn.S_zope_thread.c_zope_thread_methodslocaltypelocal_dealloclocal_getattrolocal_setattrolocal_traverselocal_clearlocal_getsetlocal_newlocal_getdict_ldict__dso_handle_GLOBAL_OFFSET_TABLE__DYNAMICPyErr_SetStringPyDict_SetItemPyThreadState_GetPyBaseObject_Typeinit_zope_threadPy_InitModule4PyThreadState_Next_initPyObject_GenericSetAttrPyDict_DelItemPyModule_AddObjectPyObject_IsTruePyExc_SystemErrorPyDict_NewPyThreadState_GetDictPyExc_TypeErrorPyType_Ready__bss_startPyDict_GetItemPyExc_AttributeError_fini__cxa_finalize@@GLIBC_2.1.3PyObject_GenericGetAttr_edata_endPyString_FromFormatPyInterpreterState_ThreadHead_Jv_RegisterClasses__gmon_start__PKM4g::zope/thread/__init__.pyc; ?3Dc@sdZy dkZWnaej oUdklZlZlZdefdYZdZ defdYZ nXei Z [dS(s Thread-local objects Thread-local objects support the management of thread-local data. If you have data that you want to be local to a thread, simply create a thread-local object and use it's attributes: >>> import zope.thread >>> mydata = zope.thread.local() >>> mydata.__class__.__name__ 'local' >>> mydata.number = 42 >>> mydata.number 42 You can also access the local-object's dictionary: >>> mydata.__dict__ {'number': 42} >>> mydata.__dict__.setdefault('widgets', []) [] >>> mydata.widgets [] What's important about thread-local objects is that their data are local to a thread. If we access the data in a different thread: >>> log = [] >>> def f(): ... items = mydata.__dict__.items() ... items.sort() ... log.append(items) ... mydata.number = 11 ... log.append(mydata.number) >>> import threading >>> thread = threading.Thread(target=f) >>> thread.start() >>> thread.join() >>> log [[], 11] we get different data. Furthermore, changes made in the other thread don't affect data seen in this thread: >>> mydata.number 42 Of course, values you get from a local object, including a __dict__ attribute, are for whatever thread was current at the time the attribute was read. For that reason, you generally don't want to save these values across threads, as they apply only to the thread they came from. You can create custom local objects by subclassing the local class: >>> class MyLocal(zope.thread.local): ... number = 2 ... initialized = False ... def __init__(self, **kw): ... if self.initialized: ... raise SystemError('__init__ called too many times') ... self.initialized = True ... self.__dict__.update(kw) ... def squared(self): ... return self.number ** 2 This can be useful to support default values, methods and initialization. Note that if you define an __init__ method, it will be called each time the local object is used in a separate thread. This is necessary to initialize each thread's dictionary. Now if we create a local object: >>> mydata = MyLocal(color='red') Now we have a default number: >>> mydata.number 2 an initial color: >>> mydata.color 'red' >>> del mydata.color And a method that operates on the data: >>> mydata.squared() 4 As before, we can access the data in a separate thread: >>> log = [] >>> thread = threading.Thread(target=f) >>> thread.start() >>> thread.join() >>> log [[('color', 'red'), ('initialized', True)], 11] without effecting this threads data: >>> mydata.number 2 >>> mydata.color Traceback (most recent call last): ... AttributeError: 'MyLocal' object has no attribute 'color' Note that subclasses can define slots, but they are not thread local. They are shared across threads: >>> class MyLocal(zope.thread.local): ... __slots__ = 'number' >>> mydata = MyLocal() >>> mydata.number = 42 >>> mydata.color = 'red' So, the separate thread: >>> thread = threading.Thread(target=f) >>> thread.start() >>> thread.join() affects what we see: >>> mydata.number 11 $Id: __init__.py 27165 2004-08-17 11:20:31Z hdima $ N(s currentThreads enumeratesRLocks _localbasecBs tZdddfZdZRS(Ns _local__keys _local__argss _local__lockcOsti|}ddtt|f}ti|d|ti|d||fti|dt |p|o|i ti jot dnti |d}|ti|<|SdS(Ns _local__keys thread.local.s _local__argss _local__locks*Initialization arguments are not supporteds__dict__(sobjects__new__sclssselfsstrsidskeys __setattr__sargsskwsRLocks__init__s TypeErrors__getattribute__sdicts currentThreads__dict__(sclssargsskwsselfskeysdict((s2build/bdist.linux-i686/egg/zope/thread/__init__.pys__new__s!(s__name__s __module__s __slots__s__new__(((s2build/bdist.linux-i686/egg/zope/thread/__init__.pys _localbasescCsti|d}tii|}|tjo{h}|ti| PKM4fzope/thread/tests.pyc; ?3Dc@s4dZdZedjoeiddndS(sLUnit tests for zope.thread. $Id: tests.py 26084 2004-07-02 22:34:30Z jim $ cCs=dk}dkl}|i}|i|d|SdS(N(s DocTestSuites zope.thread(sunittestsdoctests DocTestSuites TestSuitessuitesaddTest(ssuitesunittests DocTestSuite((s/build/bdist.linux-i686/egg/zope/thread/tests.pys test_suites    s__main__s defaultTests test_suiteN(s__doc__s test_suites__name__sunittestsmain(s test_suite((s/build/bdist.linux-i686/egg/zope/thread/tests.pys?s  PKM4&zope/thread/_zope_thread.pydef __bootstrap__(): global __bootstrap__, __loader__, __file__ import sys, pkg_resources, imp __file__ = pkg_resources.resource_filename(__name__,'_zope_thread.so') del __bootstrap__, __loader__ imp.load_dynamic(__name__,__file__) __bootstrap__() PKM4u;;zope/thread/_zope_thread.pyc; 3Dc@sdatdS(cCsGdk}dk}dk}|itdabb|ittdS(Ns_zope_thread.so( ssyss pkg_resourcessimpsresource_filenames__name__s__file__s __bootstrap__s __loader__s load_dynamic(s pkg_resourcesssyssimp((s6build/bdist.linux-i686/egg/zope/thread/_zope_thread.pys __bootstrap__s N(s __bootstrap__(((s6build/bdist.linux-i686/egg/zope/thread/_zope_thread.pys?s PKM4MEGG-INFO/PKG-INFOMetadata-Version: 1.0 Name: zope.thread Version: 3.0.0 Summary: Zope3 Thread-Local Storage Home-page: http://svn.zope.org/zope.thread Author: Zope Corporation and Contributors Author-email: zope3-dev@zope.org License: ZPL 2.1 Description: This package supplies a mechoanism for storing "thread-local" values, such as the site manager discovered during URL traversal. Platform: UNKNOWN PKL4EGG-INFO/not-zip-safePKM4EGG-INFO/namespace_packages.txtzope PKM4EGG-INFO/top_level.txtzope PKM4,c~EGG-INFO/SOURCES.txtCHANGES.txt INSTALL.txt README.txt develop.py setup.cfg setup.cfg.in setup.py test.py src/zope/__init__.py src/zope.thread.egg-info/PKG-INFO src/zope.thread.egg-info/SOURCES.txt src/zope.thread.egg-info/namespace_packages.txt src/zope.thread.egg-info/not-zip-safe src/zope.thread.egg-info/top_level.txt src/zope/thread/DEPENDENCIES.cfg src/zope/thread/SETUP.cfg src/zope/thread/__init__.py src/zope/thread/_zope_thread.c src/zope/thread/tests.py workspace/__init__.py workspace/develop.py PKM4Q]lEGG-INFO/native_libs.txtzope/thread/_zope_thread.so PKK4~7zope/__init__.pyPKM4w Czope/__init__.pycPKKM4-(Mzope/thread/__init__.pyPKKM4;<+b zope/thread/tests.pyPKM4TnUU큀$zope/thread/_zope_thread.soPKM4g::Mzzope/thread/__init__.pycPKM4fzope/thread/tests.pycPKM4&Λzope/thread/_zope_thread.pyPKM4u;;zope/thread/_zope_thread.pycPKM4MEGG-INFO/PKG-INFOPKL43EGG-INFO/not-zip-safePKM4fEGG-INFO/namespace_packages.txtPKM4EGG-INFO/top_level.txtPKM4,c~EGG-INFO/SOURCES.txtPKM4Q]lEGG-INFO/native_libs.txtPKN