rubyfox-server 2.3.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (993) hide show
  1. data/.gitignore +17 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +23 -0
  6. data/Rakefile +1 -0
  7. data/bin/smartfox +7 -0
  8. data/lib/rubyfox/server/cli.rb +59 -0
  9. data/lib/rubyfox/server/data/config/.keep +0 -0
  10. data/lib/rubyfox/server/data/config/_backups/.keep +0 -0
  11. data/lib/rubyfox/server/data/config/ascii/boot.txt +5 -0
  12. data/lib/rubyfox/server/data/config/ascii/ready.txt +9 -0
  13. data/lib/rubyfox/server/data/config/core.xml +44 -0
  14. data/lib/rubyfox/server/data/config/crossdomain.xml +10 -0
  15. data/lib/rubyfox/server/data/config/descriptors/.keep +0 -0
  16. data/lib/rubyfox/server/data/config/descriptors/config_room.txt +323 -0
  17. data/lib/rubyfox/server/data/config/descriptors/config_server.txt +621 -0
  18. data/lib/rubyfox/server/data/config/descriptors/config_zone.txt +1021 -0
  19. data/lib/rubyfox/server/data/config/descriptors/runtime_game.txt +63 -0
  20. data/lib/rubyfox/server/data/config/descriptors/runtime_room.txt +377 -0
  21. data/lib/rubyfox/server/data/config/descriptors/runtime_user.txt +589 -0
  22. data/lib/rubyfox/server/data/config/descriptors/runtime_zone.txt +354 -0
  23. data/lib/rubyfox/server/data/config/jetty/.keep +0 -0
  24. data/lib/rubyfox/server/data/config/jetty/jetty.xml +214 -0
  25. data/lib/rubyfox/server/data/config/jetty/realm.properties +21 -0
  26. data/lib/rubyfox/server/data/config/jetty/webdefault.xml +410 -0
  27. data/lib/rubyfox/server/data/config/log4j.properties +75 -0
  28. data/lib/rubyfox/server/data/config/myprop.properties +5 -0
  29. data/lib/rubyfox/server/data/config/server.xml +65 -0
  30. data/lib/rubyfox/server/data/config/templates/sfs2x.unix.txt +12 -0
  31. data/lib/rubyfox/server/data/config/templates/sfs2x.windows.txt +1 -0
  32. data/lib/rubyfox/server/data/config/templates/vmoptions.txt +3 -0
  33. data/lib/rubyfox/server/data/config/wordsFile.txt +13 -0
  34. data/lib/rubyfox/server/data/data/bannedusers/.keep +0 -0
  35. data/lib/rubyfox/server/data/data/bannedusers/users.bin +0 -0
  36. data/lib/rubyfox/server/data/data/buddylists/.keep +0 -0
  37. data/lib/rubyfox/server/data/data/buddylists/BasicExamples/7364666773646667 +0 -0
  38. data/lib/rubyfox/server/data/extensions/.keep +0 -0
  39. data/lib/rubyfox/server/data/extensions/__lib__/.keep +0 -0
  40. data/lib/rubyfox/server/data/lib/Jetty/.keep +0 -0
  41. data/lib/rubyfox/server/data/lib/Jetty/ant-1.6.5.jar +0 -0
  42. data/lib/rubyfox/server/data/lib/Jetty/core-3.1.1.jar +0 -0
  43. data/lib/rubyfox/server/data/lib/Jetty/jetty-6.1.26.jar +0 -0
  44. data/lib/rubyfox/server/data/lib/Jetty/jetty-util-6.1.26.jar +0 -0
  45. data/lib/rubyfox/server/data/lib/Jetty/jsp-2.1-glassfish-2.1.v20091210.jar +0 -0
  46. data/lib/rubyfox/server/data/lib/Jetty/jsp-2.1-jetty-6.1.26.jar +0 -0
  47. data/lib/rubyfox/server/data/lib/Jetty/jsp-api-2.1-glassfish-2.1.v20091210.jar +0 -0
  48. data/lib/rubyfox/server/data/lib/Jetty/servlet-api-2.5-20081211.jar +0 -0
  49. data/lib/rubyfox/server/data/lib/Lib/BaseHTTPServer.py +484 -0
  50. data/lib/rubyfox/server/data/lib/Lib/CGIHTTPServer.py +325 -0
  51. data/lib/rubyfox/server/data/lib/Lib/ConfigParser.py +472 -0
  52. data/lib/rubyfox/server/data/lib/Lib/Cookie.py +742 -0
  53. data/lib/rubyfox/server/data/lib/Lib/HTMLParser.py +383 -0
  54. data/lib/rubyfox/server/data/lib/Lib/MimeWriter.py +181 -0
  55. data/lib/rubyfox/server/data/lib/Lib/Queue.py +151 -0
  56. data/lib/rubyfox/server/data/lib/Lib/SimpleHTTPServer.py +198 -0
  57. data/lib/rubyfox/server/data/lib/Lib/SimpleXMLRPCServer.py +274 -0
  58. data/lib/rubyfox/server/data/lib/Lib/SocketServer.py +576 -0
  59. data/lib/rubyfox/server/data/lib/Lib/StringIO.py +239 -0
  60. data/lib/rubyfox/server/data/lib/Lib/UserDict$py.class +0 -0
  61. data/lib/rubyfox/server/data/lib/Lib/UserDict.py +60 -0
  62. data/lib/rubyfox/server/data/lib/Lib/UserList.py +94 -0
  63. data/lib/rubyfox/server/data/lib/Lib/UserString.py +182 -0
  64. data/lib/rubyfox/server/data/lib/Lib/__future__$py.class +0 -0
  65. data/lib/rubyfox/server/data/lib/Lib/__future__.py +104 -0
  66. data/lib/rubyfox/server/data/lib/Lib/aifc.py +961 -0
  67. data/lib/rubyfox/server/data/lib/Lib/anydbm.py +86 -0
  68. data/lib/rubyfox/server/data/lib/Lib/atexit.py +50 -0
  69. data/lib/rubyfox/server/data/lib/Lib/base64.py +77 -0
  70. data/lib/rubyfox/server/data/lib/Lib/bdb.py +563 -0
  71. data/lib/rubyfox/server/data/lib/Lib/binhex.py +531 -0
  72. data/lib/rubyfox/server/data/lib/Lib/bisect.py +78 -0
  73. data/lib/rubyfox/server/data/lib/Lib/calendar.py +246 -0
  74. data/lib/rubyfox/server/data/lib/Lib/cgi.py +1040 -0
  75. data/lib/rubyfox/server/data/lib/Lib/chunk.py +167 -0
  76. data/lib/rubyfox/server/data/lib/Lib/cmd.py +336 -0
  77. data/lib/rubyfox/server/data/lib/Lib/code$py.class +0 -0
  78. data/lib/rubyfox/server/data/lib/Lib/code.py +311 -0
  79. data/lib/rubyfox/server/data/lib/Lib/codecs$py.class +0 -0
  80. data/lib/rubyfox/server/data/lib/Lib/codecs.py +636 -0
  81. data/lib/rubyfox/server/data/lib/Lib/codeop$py.class +0 -0
  82. data/lib/rubyfox/server/data/lib/Lib/codeop.py +131 -0
  83. data/lib/rubyfox/server/data/lib/Lib/colorsys.py +123 -0
  84. data/lib/rubyfox/server/data/lib/Lib/commands.py +84 -0
  85. data/lib/rubyfox/server/data/lib/Lib/compileall.py +148 -0
  86. data/lib/rubyfox/server/data/lib/Lib/copy.py +330 -0
  87. data/lib/rubyfox/server/data/lib/Lib/copy_reg$py.class +0 -0
  88. data/lib/rubyfox/server/data/lib/Lib/copy_reg.py +78 -0
  89. data/lib/rubyfox/server/data/lib/Lib/datetime$py.class +0 -0
  90. data/lib/rubyfox/server/data/lib/Lib/datetime.py +2007 -0
  91. data/lib/rubyfox/server/data/lib/Lib/dbexts.py +726 -0
  92. data/lib/rubyfox/server/data/lib/Lib/difflib.py +1088 -0
  93. data/lib/rubyfox/server/data/lib/Lib/dircache.py +44 -0
  94. data/lib/rubyfox/server/data/lib/Lib/doctest.py +1173 -0
  95. data/lib/rubyfox/server/data/lib/Lib/dospath.py +341 -0
  96. data/lib/rubyfox/server/data/lib/Lib/dumbdbm.py +170 -0
  97. data/lib/rubyfox/server/data/lib/Lib/email/Charset.py +393 -0
  98. data/lib/rubyfox/server/data/lib/Lib/email/Encoders.py +94 -0
  99. data/lib/rubyfox/server/data/lib/Lib/email/Errors.py +26 -0
  100. data/lib/rubyfox/server/data/lib/Lib/email/Generator.py +378 -0
  101. data/lib/rubyfox/server/data/lib/Lib/email/Header.py +515 -0
  102. data/lib/rubyfox/server/data/lib/Lib/email/Iterators.py +25 -0
  103. data/lib/rubyfox/server/data/lib/Lib/email/MIMEAudio.py +71 -0
  104. data/lib/rubyfox/server/data/lib/Lib/email/MIMEBase.py +24 -0
  105. data/lib/rubyfox/server/data/lib/Lib/email/MIMEImage.py +45 -0
  106. data/lib/rubyfox/server/data/lib/Lib/email/MIMEMessage.py +32 -0
  107. data/lib/rubyfox/server/data/lib/Lib/email/MIMEMultipart.py +37 -0
  108. data/lib/rubyfox/server/data/lib/Lib/email/MIMENonMultipart.py +24 -0
  109. data/lib/rubyfox/server/data/lib/Lib/email/MIMEText.py +45 -0
  110. data/lib/rubyfox/server/data/lib/Lib/email/Message.py +837 -0
  111. data/lib/rubyfox/server/data/lib/Lib/email/Parser.py +292 -0
  112. data/lib/rubyfox/server/data/lib/Lib/email/Utils.py +340 -0
  113. data/lib/rubyfox/server/data/lib/Lib/email/__init__.py +72 -0
  114. data/lib/rubyfox/server/data/lib/Lib/email/_compat21.py +69 -0
  115. data/lib/rubyfox/server/data/lib/Lib/email/_compat22.py +70 -0
  116. data/lib/rubyfox/server/data/lib/Lib/email/_parseaddr.py +480 -0
  117. data/lib/rubyfox/server/data/lib/Lib/email/base64MIME.py +184 -0
  118. data/lib/rubyfox/server/data/lib/Lib/email/quopriMIME.py +323 -0
  119. data/lib/rubyfox/server/data/lib/Lib/email/test/__init__.py +2 -0
  120. data/lib/rubyfox/server/data/lib/Lib/email/test/data/PyBanner048.gif +0 -0
  121. data/lib/rubyfox/server/data/lib/Lib/email/test/data/audiotest.au +0 -0
  122. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_01.txt +19 -0
  123. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_02.txt +135 -0
  124. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_03.txt +16 -0
  125. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_04.txt +37 -0
  126. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_05.txt +28 -0
  127. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_06.txt +33 -0
  128. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_07.txt +83 -0
  129. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_08.txt +24 -0
  130. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_09.txt +24 -0
  131. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_10.txt +32 -0
  132. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_11.txt +7 -0
  133. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_12.txt +36 -0
  134. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_13.txt +94 -0
  135. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_14.txt +23 -0
  136. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_15.txt +52 -0
  137. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_16.txt +123 -0
  138. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_17.txt +12 -0
  139. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_18.txt +6 -0
  140. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_19.txt +43 -0
  141. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_20.txt +22 -0
  142. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_21.txt +20 -0
  143. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_22.txt +46 -0
  144. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_23.txt +8 -0
  145. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_24.txt +10 -0
  146. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_25.txt +117 -0
  147. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_26.txt +45 -0
  148. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_27.txt +15 -0
  149. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_28.txt +25 -0
  150. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_29.txt +22 -0
  151. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_30.txt +23 -0
  152. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_31.txt +15 -0
  153. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_32.txt +14 -0
  154. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_33.txt +29 -0
  155. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_34.txt +19 -0
  156. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_35.txt +4 -0
  157. data/lib/rubyfox/server/data/lib/Lib/email/test/test_email.py +2718 -0
  158. data/lib/rubyfox/server/data/lib/Lib/email/test/test_email_codecs.py +68 -0
  159. data/lib/rubyfox/server/data/lib/Lib/email/test/test_email_torture.py +136 -0
  160. data/lib/rubyfox/server/data/lib/Lib/encodings/__init__$py.class +0 -0
  161. data/lib/rubyfox/server/data/lib/Lib/encodings/__init__.py +97 -0
  162. data/lib/rubyfox/server/data/lib/Lib/encodings/aliases$py.class +0 -0
  163. data/lib/rubyfox/server/data/lib/Lib/encodings/aliases.py +115 -0
  164. data/lib/rubyfox/server/data/lib/Lib/encodings/ascii.py +35 -0
  165. data/lib/rubyfox/server/data/lib/Lib/encodings/base64_codec.py +62 -0
  166. data/lib/rubyfox/server/data/lib/Lib/encodings/charmap.py +51 -0
  167. data/lib/rubyfox/server/data/lib/Lib/encodings/cp037.py +280 -0
  168. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1006.py +138 -0
  169. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1026.py +280 -0
  170. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1140.py +45 -0
  171. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1250.py +123 -0
  172. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1251.py +157 -0
  173. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1252.py +76 -0
  174. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1253.py +151 -0
  175. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1254.py +82 -0
  176. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1255.py +143 -0
  177. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1256.py +129 -0
  178. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1257.py +131 -0
  179. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1258.py +90 -0
  180. data/lib/rubyfox/server/data/lib/Lib/encodings/cp424.py +280 -0
  181. data/lib/rubyfox/server/data/lib/Lib/encodings/cp437.py +172 -0
  182. data/lib/rubyfox/server/data/lib/Lib/encodings/cp500.py +280 -0
  183. data/lib/rubyfox/server/data/lib/Lib/encodings/cp737.py +172 -0
  184. data/lib/rubyfox/server/data/lib/Lib/encodings/cp775.py +172 -0
  185. data/lib/rubyfox/server/data/lib/Lib/encodings/cp850.py +172 -0
  186. data/lib/rubyfox/server/data/lib/Lib/encodings/cp852.py +172 -0
  187. data/lib/rubyfox/server/data/lib/Lib/encodings/cp855.py +172 -0
  188. data/lib/rubyfox/server/data/lib/Lib/encodings/cp856.py +172 -0
  189. data/lib/rubyfox/server/data/lib/Lib/encodings/cp857.py +171 -0
  190. data/lib/rubyfox/server/data/lib/Lib/encodings/cp860.py +172 -0
  191. data/lib/rubyfox/server/data/lib/Lib/encodings/cp861.py +172 -0
  192. data/lib/rubyfox/server/data/lib/Lib/encodings/cp862.py +172 -0
  193. data/lib/rubyfox/server/data/lib/Lib/encodings/cp863.py +172 -0
  194. data/lib/rubyfox/server/data/lib/Lib/encodings/cp864.py +170 -0
  195. data/lib/rubyfox/server/data/lib/Lib/encodings/cp865.py +172 -0
  196. data/lib/rubyfox/server/data/lib/Lib/encodings/cp866.py +172 -0
  197. data/lib/rubyfox/server/data/lib/Lib/encodings/cp869.py +172 -0
  198. data/lib/rubyfox/server/data/lib/Lib/encodings/cp874.py +171 -0
  199. data/lib/rubyfox/server/data/lib/Lib/encodings/cp875.py +281 -0
  200. data/lib/rubyfox/server/data/lib/Lib/encodings/hex_codec.py +62 -0
  201. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_1.py +44 -0
  202. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_10.py +90 -0
  203. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_13.py +100 -0
  204. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_14.py +75 -0
  205. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_15.py +52 -0
  206. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_2.py +101 -0
  207. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_3.py +79 -0
  208. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_4.py +94 -0
  209. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_5.py +138 -0
  210. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_6.py +137 -0
  211. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_7.py +124 -0
  212. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_8.py +112 -0
  213. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_9.py +50 -0
  214. data/lib/rubyfox/server/data/lib/Lib/encodings/koi8_r.py +172 -0
  215. data/lib/rubyfox/server/data/lib/Lib/encodings/koi8_u.py +54 -0
  216. data/lib/rubyfox/server/data/lib/Lib/encodings/latin_1.py +35 -0
  217. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_cyrillic.py +167 -0
  218. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_greek.py +170 -0
  219. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_iceland.py +166 -0
  220. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_latin2.py +170 -0
  221. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_roman.py +167 -0
  222. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_turkish.py +167 -0
  223. data/lib/rubyfox/server/data/lib/Lib/encodings/mbcs.py +36 -0
  224. data/lib/rubyfox/server/data/lib/Lib/encodings/quopri_codec.py +58 -0
  225. data/lib/rubyfox/server/data/lib/Lib/encodings/raw_unicode_escape.py +30 -0
  226. data/lib/rubyfox/server/data/lib/Lib/encodings/rot_13.py +105 -0
  227. data/lib/rubyfox/server/data/lib/Lib/encodings/undefined.py +34 -0
  228. data/lib/rubyfox/server/data/lib/Lib/encodings/unicode_escape.py +30 -0
  229. data/lib/rubyfox/server/data/lib/Lib/encodings/unicode_internal.py +30 -0
  230. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_16.py +61 -0
  231. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_16_be.py +31 -0
  232. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_16_le.py +31 -0
  233. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_7.py +27 -0
  234. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_8$py.class +0 -0
  235. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_8.py +31 -0
  236. data/lib/rubyfox/server/data/lib/Lib/encodings/uu_codec.py +112 -0
  237. data/lib/rubyfox/server/data/lib/Lib/encodings/zlib_codec.py +63 -0
  238. data/lib/rubyfox/server/data/lib/Lib/fileinput.py +349 -0
  239. data/lib/rubyfox/server/data/lib/Lib/fnmatch.py +107 -0
  240. data/lib/rubyfox/server/data/lib/Lib/formatter.py +454 -0
  241. data/lib/rubyfox/server/data/lib/Lib/fpformat.py +142 -0
  242. data/lib/rubyfox/server/data/lib/Lib/ftplib.py +804 -0
  243. data/lib/rubyfox/server/data/lib/Lib/getopt.py +143 -0
  244. data/lib/rubyfox/server/data/lib/Lib/glob.py +56 -0
  245. data/lib/rubyfox/server/data/lib/Lib/gopherlib.py +205 -0
  246. data/lib/rubyfox/server/data/lib/Lib/gzip.py +390 -0
  247. data/lib/rubyfox/server/data/lib/Lib/hmac.py +99 -0
  248. data/lib/rubyfox/server/data/lib/Lib/htmlentitydefs.py +257 -0
  249. data/lib/rubyfox/server/data/lib/Lib/htmllib.py +475 -0
  250. data/lib/rubyfox/server/data/lib/Lib/httplib.py +1238 -0
  251. data/lib/rubyfox/server/data/lib/Lib/imaplib.py +1208 -0
  252. data/lib/rubyfox/server/data/lib/Lib/imghdr.py +154 -0
  253. data/lib/rubyfox/server/data/lib/Lib/inspect$py.class +0 -0
  254. data/lib/rubyfox/server/data/lib/Lib/inspect.py +787 -0
  255. data/lib/rubyfox/server/data/lib/Lib/isql.py +238 -0
  256. data/lib/rubyfox/server/data/lib/Lib/javaos$py.class +0 -0
  257. data/lib/rubyfox/server/data/lib/Lib/javaos.py +395 -0
  258. data/lib/rubyfox/server/data/lib/Lib/javapath$py.class +0 -0
  259. data/lib/rubyfox/server/data/lib/Lib/javapath.py +349 -0
  260. data/lib/rubyfox/server/data/lib/Lib/javashell.py +194 -0
  261. data/lib/rubyfox/server/data/lib/Lib/jreload.py +119 -0
  262. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/DiscardHelp.java +59 -0
  263. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/JavaLoaderFactory.java +9 -0
  264. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/PackageManager.java +58 -0
  265. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/PathVFS.java +98 -0
  266. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/PathVFSJavaLoader.java +49 -0
  267. data/lib/rubyfox/server/data/lib/Lib/keyword.py +97 -0
  268. data/lib/rubyfox/server/data/lib/Lib/linecache$py.class +0 -0
  269. data/lib/rubyfox/server/data/lib/Lib/linecache.py +101 -0
  270. data/lib/rubyfox/server/data/lib/Lib/macpath.py +242 -0
  271. data/lib/rubyfox/server/data/lib/Lib/macurl2path.py +95 -0
  272. data/lib/rubyfox/server/data/lib/Lib/mailbox.py +313 -0
  273. data/lib/rubyfox/server/data/lib/Lib/mailcap.py +255 -0
  274. data/lib/rubyfox/server/data/lib/Lib/markupbase.py +317 -0
  275. data/lib/rubyfox/server/data/lib/Lib/marshal.py +315 -0
  276. data/lib/rubyfox/server/data/lib/Lib/mhlib.py +1003 -0
  277. data/lib/rubyfox/server/data/lib/Lib/mimetools.py +226 -0
  278. data/lib/rubyfox/server/data/lib/Lib/mimetypes.py +435 -0
  279. data/lib/rubyfox/server/data/lib/Lib/mimify.py +464 -0
  280. data/lib/rubyfox/server/data/lib/Lib/multifile.py +160 -0
  281. data/lib/rubyfox/server/data/lib/Lib/mutex.py +51 -0
  282. data/lib/rubyfox/server/data/lib/Lib/netrc.py +108 -0
  283. data/lib/rubyfox/server/data/lib/Lib/nntplib.py +575 -0
  284. data/lib/rubyfox/server/data/lib/Lib/ntpath.py +482 -0
  285. data/lib/rubyfox/server/data/lib/Lib/nturl2path.py +66 -0
  286. data/lib/rubyfox/server/data/lib/Lib/pawt/__init__.py +35 -0
  287. data/lib/rubyfox/server/data/lib/Lib/pawt/colors.py +144 -0
  288. data/lib/rubyfox/server/data/lib/Lib/pawt/swing.py +42 -0
  289. data/lib/rubyfox/server/data/lib/Lib/pdb.py +979 -0
  290. data/lib/rubyfox/server/data/lib/Lib/pickle.py +990 -0
  291. data/lib/rubyfox/server/data/lib/Lib/pipes.py +297 -0
  292. data/lib/rubyfox/server/data/lib/Lib/popen2.py +304 -0
  293. data/lib/rubyfox/server/data/lib/Lib/poplib.py +335 -0
  294. data/lib/rubyfox/server/data/lib/Lib/posixfile.py +240 -0
  295. data/lib/rubyfox/server/data/lib/Lib/posixpath.py +414 -0
  296. data/lib/rubyfox/server/data/lib/Lib/pprint.py +310 -0
  297. data/lib/rubyfox/server/data/lib/Lib/profile.py +556 -0
  298. data/lib/rubyfox/server/data/lib/Lib/pstats.py +641 -0
  299. data/lib/rubyfox/server/data/lib/Lib/pyclbr.py +337 -0
  300. data/lib/rubyfox/server/data/lib/Lib/quopri.py +237 -0
  301. data/lib/rubyfox/server/data/lib/Lib/random$py.class +0 -0
  302. data/lib/rubyfox/server/data/lib/Lib/random.py +779 -0
  303. data/lib/rubyfox/server/data/lib/Lib/re$py.class +0 -0
  304. data/lib/rubyfox/server/data/lib/Lib/re.py +11 -0
  305. data/lib/rubyfox/server/data/lib/Lib/reconvert.py +192 -0
  306. data/lib/rubyfox/server/data/lib/Lib/reindex$py.class +0 -0
  307. data/lib/rubyfox/server/data/lib/Lib/repr.py +95 -0
  308. data/lib/rubyfox/server/data/lib/Lib/rfc822.py +1010 -0
  309. data/lib/rubyfox/server/data/lib/Lib/sched.py +106 -0
  310. data/lib/rubyfox/server/data/lib/Lib/select.py +211 -0
  311. data/lib/rubyfox/server/data/lib/Lib/servlet-api-2.5-20081211.jar +0 -0
  312. data/lib/rubyfox/server/data/lib/Lib/setsfactory.py +10 -0
  313. data/lib/rubyfox/server/data/lib/Lib/sfs2x-lms.jar +0 -0
  314. data/lib/rubyfox/server/data/lib/Lib/sgmllib.py +516 -0
  315. data/lib/rubyfox/server/data/lib/Lib/shelve.py +158 -0
  316. data/lib/rubyfox/server/data/lib/Lib/shlex.py +209 -0
  317. data/lib/rubyfox/server/data/lib/Lib/shutil$py.class +0 -0
  318. data/lib/rubyfox/server/data/lib/Lib/shutil.py +138 -0
  319. data/lib/rubyfox/server/data/lib/Lib/site.py +263 -0
  320. data/lib/rubyfox/server/data/lib/Lib/smtplib.py +729 -0
  321. data/lib/rubyfox/server/data/lib/Lib/sndhdr.py +228 -0
  322. data/lib/rubyfox/server/data/lib/Lib/socket.py +902 -0
  323. data/lib/rubyfox/server/data/lib/Lib/sre$py.class +0 -0
  324. data/lib/rubyfox/server/data/lib/Lib/sre.py +311 -0
  325. data/lib/rubyfox/server/data/lib/Lib/sre_compile$py.class +0 -0
  326. data/lib/rubyfox/server/data/lib/Lib/sre_compile.py +455 -0
  327. data/lib/rubyfox/server/data/lib/Lib/sre_constants$py.class +0 -0
  328. data/lib/rubyfox/server/data/lib/Lib/sre_constants.py +259 -0
  329. data/lib/rubyfox/server/data/lib/Lib/sre_parse$py.class +0 -0
  330. data/lib/rubyfox/server/data/lib/Lib/sre_parse.py +738 -0
  331. data/lib/rubyfox/server/data/lib/Lib/stat$py.class +0 -0
  332. data/lib/rubyfox/server/data/lib/Lib/stat.py +86 -0
  333. data/lib/rubyfox/server/data/lib/Lib/string$py.class +0 -0
  334. data/lib/rubyfox/server/data/lib/Lib/string.py +437 -0
  335. data/lib/rubyfox/server/data/lib/Lib/symbol.py +95 -0
  336. data/lib/rubyfox/server/data/lib/Lib/telnetlib.py +662 -0
  337. data/lib/rubyfox/server/data/lib/Lib/tempfile.py +255 -0
  338. data/lib/rubyfox/server/data/lib/Lib/test/Graph.py +62 -0
  339. data/lib/rubyfox/server/data/lib/Lib/test/README +372 -0
  340. data/lib/rubyfox/server/data/lib/Lib/test/__init__.py +1 -0
  341. data/lib/rubyfox/server/data/lib/Lib/test/audiotest.au +0 -0
  342. data/lib/rubyfox/server/data/lib/Lib/test/autotest.py +6 -0
  343. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future3.py +10 -0
  344. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future4.py +10 -0
  345. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future5.py +12 -0
  346. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future6.py +10 -0
  347. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future7.py +11 -0
  348. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_nocaret.py +2 -0
  349. data/lib/rubyfox/server/data/lib/Lib/test/blob.jar +0 -0
  350. data/lib/rubyfox/server/data/lib/Lib/test/bugs/bugs100.py +139 -0
  351. data/lib/rubyfox/server/data/lib/Lib/test/bugs/bugs101.py +57 -0
  352. data/lib/rubyfox/server/data/lib/Lib/test/bugs/jdkbugs.py +10 -0
  353. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr101.py +59 -0
  354. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr104.py +9 -0
  355. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr112.py +14 -0
  356. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr119.py +16 -0
  357. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr127.py +10 -0
  358. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr133/__init__.py +1 -0
  359. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr133/test.py +2 -0
  360. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr133.py +12 -0
  361. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr134.py +9 -0
  362. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr139.py +7 -0
  363. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr142.py +1 -0
  364. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr144.py +2 -0
  365. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr148.py +2 -0
  366. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr149.py +7 -0
  367. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr155.py +13 -0
  368. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr170.py +7 -0
  369. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr171.py +9 -0
  370. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr174.py +9 -0
  371. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr178.py +10 -0
  372. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr183.py +5 -0
  373. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr186.py +10 -0
  374. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr191.py +5 -0
  375. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr192.py +81 -0
  376. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr195.py +11 -0
  377. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr208.py +26 -0
  378. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr233.py +8 -0
  379. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr234.py +16 -0
  380. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr235.py +14 -0
  381. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr239.py +6 -0
  382. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr241.py +16 -0
  383. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr242.py +12 -0
  384. data/lib/rubyfox/server/data/lib/Lib/test/data/PyBanner048.gif +0 -0
  385. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_01.txt +19 -0
  386. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_02.txt +135 -0
  387. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_03.txt +16 -0
  388. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_04.txt +37 -0
  389. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_05.txt +28 -0
  390. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_06.txt +33 -0
  391. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_07.txt +83 -0
  392. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_08.txt +24 -0
  393. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_09.txt +24 -0
  394. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_10.txt +32 -0
  395. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_11.txt +7 -0
  396. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_12.txt +36 -0
  397. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_13.txt +94 -0
  398. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_14.txt +23 -0
  399. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_15.txt +52 -0
  400. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_16.txt +123 -0
  401. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_17.txt +12 -0
  402. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_18.txt +6 -0
  403. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_19.txt +43 -0
  404. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_20.txt +22 -0
  405. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_21.txt +22 -0
  406. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_22.txt +46 -0
  407. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_23.txt +8 -0
  408. data/lib/rubyfox/server/data/lib/Lib/test/double_const.py +30 -0
  409. data/lib/rubyfox/server/data/lib/Lib/test/greyrgb.uue +1547 -0
  410. data/lib/rubyfox/server/data/lib/Lib/test/javatests/AnonInner.java +20 -0
  411. data/lib/rubyfox/server/data/lib/Lib/test/javatests/Foo.java +3 -0
  412. data/lib/rubyfox/server/data/lib/Lib/test/javatests/JOverload.java +132 -0
  413. data/lib/rubyfox/server/data/lib/Lib/test/javatests/ListTest.java +638 -0
  414. data/lib/rubyfox/server/data/lib/Lib/test/javatests/SubFoo.java +3 -0
  415. data/lib/rubyfox/server/data/lib/Lib/test/javatests/TestSupport.java +49 -0
  416. data/lib/rubyfox/server/data/lib/Lib/test/javatests/__init__.py +0 -0
  417. data/lib/rubyfox/server/data/lib/Lib/test/jser2_classes.py +47 -0
  418. data/lib/rubyfox/server/data/lib/Lib/test/output/test_MimeWriter +110 -0
  419. data/lib/rubyfox/server/data/lib/Lib/test/output/test_array +4 -0
  420. data/lib/rubyfox/server/data/lib/Lib/test/output/test_asynchat +3 -0
  421. data/lib/rubyfox/server/data/lib/Lib/test/output/test_augassign +51 -0
  422. data/lib/rubyfox/server/data/lib/Lib/test/output/test_binascii +29 -0
  423. data/lib/rubyfox/server/data/lib/Lib/test/output/test_builtin +53 -0
  424. data/lib/rubyfox/server/data/lib/Lib/test/output/test_cfgparser +9 -0
  425. data/lib/rubyfox/server/data/lib/Lib/test/output/test_cgi +29 -0
  426. data/lib/rubyfox/server/data/lib/Lib/test/output/test_charmapcodec +16 -0
  427. data/lib/rubyfox/server/data/lib/Lib/test/output/test_class +101 -0
  428. data/lib/rubyfox/server/data/lib/Lib/test/output/test_coercion +1054 -0
  429. data/lib/rubyfox/server/data/lib/Lib/test/output/test_compare +101 -0
  430. data/lib/rubyfox/server/data/lib/Lib/test/output/test_compile +7 -0
  431. data/lib/rubyfox/server/data/lib/Lib/test/output/test_cookie +32 -0
  432. data/lib/rubyfox/server/data/lib/Lib/test/output/test_exceptions +52 -0
  433. data/lib/rubyfox/server/data/lib/Lib/test/output/test_extcall +112 -0
  434. data/lib/rubyfox/server/data/lib/Lib/test/output/test_frozen +4 -0
  435. data/lib/rubyfox/server/data/lib/Lib/test/output/test_future +9 -0
  436. data/lib/rubyfox/server/data/lib/Lib/test/output/test_gettext +46 -0
  437. data/lib/rubyfox/server/data/lib/Lib/test/output/test_global +5 -0
  438. data/lib/rubyfox/server/data/lib/Lib/test/output/test_grammar +66 -0
  439. data/lib/rubyfox/server/data/lib/Lib/test/output/test_httplib +10 -0
  440. data/lib/rubyfox/server/data/lib/Lib/test/output/test_janoninner +5 -0
  441. data/lib/rubyfox/server/data/lib/Lib/test/output/test_javalist +6 -0
  442. data/lib/rubyfox/server/data/lib/Lib/test/output/test_jbasic +13 -0
  443. data/lib/rubyfox/server/data/lib/Lib/test/output/test_jser +12 -0
  444. data/lib/rubyfox/server/data/lib/Lib/test/output/test_jsubclass +5 -0
  445. data/lib/rubyfox/server/data/lib/Lib/test/output/test_linuxaudiodev +7 -0
  446. data/lib/rubyfox/server/data/lib/Lib/test/output/test_longexp +2 -0
  447. data/lib/rubyfox/server/data/lib/Lib/test/output/test_math +26 -0
  448. data/lib/rubyfox/server/data/lib/Lib/test/output/test_md5 +9 -0
  449. data/lib/rubyfox/server/data/lib/Lib/test/output/test_methods +6 -0
  450. data/lib/rubyfox/server/data/lib/Lib/test/output/test_mimetools +5 -0
  451. data/lib/rubyfox/server/data/lib/Lib/test/output/test_mmap +34 -0
  452. data/lib/rubyfox/server/data/lib/Lib/test/output/test_new +7 -0
  453. data/lib/rubyfox/server/data/lib/Lib/test/output/test_nis +2 -0
  454. data/lib/rubyfox/server/data/lib/Lib/test/output/test_opcodes +4 -0
  455. data/lib/rubyfox/server/data/lib/Lib/test/output/test_openpty +2 -0
  456. data/lib/rubyfox/server/data/lib/Lib/test/output/test_operations +28 -0
  457. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pkg +45 -0
  458. data/lib/rubyfox/server/data/lib/Lib/test/output/test_poll +17 -0
  459. data/lib/rubyfox/server/data/lib/Lib/test/output/test_popen2 +9 -0
  460. data/lib/rubyfox/server/data/lib/Lib/test/output/test_posixpath +2 -0
  461. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pow +17 -0
  462. data/lib/rubyfox/server/data/lib/Lib/test/output/test_profile +17 -0
  463. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pty +3 -0
  464. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pwd +7 -0
  465. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pyexpat +110 -0
  466. data/lib/rubyfox/server/data/lib/Lib/test/output/test_re +15 -0
  467. data/lib/rubyfox/server/data/lib/Lib/test/output/test_regex +29 -0
  468. data/lib/rubyfox/server/data/lib/Lib/test/output/test_rgbimg +2 -0
  469. data/lib/rubyfox/server/data/lib/Lib/test/output/test_richcmp +187 -0
  470. data/lib/rubyfox/server/data/lib/Lib/test/output/test_rotor +5 -0
  471. data/lib/rubyfox/server/data/lib/Lib/test/output/test_scope +24 -0
  472. data/lib/rubyfox/server/data/lib/Lib/test/output/test_signal +2 -0
  473. data/lib/rubyfox/server/data/lib/Lib/test/output/test_string +18 -0
  474. data/lib/rubyfox/server/data/lib/Lib/test/output/test_thread +4 -0
  475. data/lib/rubyfox/server/data/lib/Lib/test/output/test_threadedtempfile +5 -0
  476. data/lib/rubyfox/server/data/lib/Lib/test/output/test_time +9 -0
  477. data/lib/rubyfox/server/data/lib/Lib/test/output/test_tokenize +648 -0
  478. data/lib/rubyfox/server/data/lib/Lib/test/output/test_types +15 -0
  479. data/lib/rubyfox/server/data/lib/Lib/test/output/test_ucn +7 -0
  480. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unicode +21 -0
  481. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unicode_file +2 -0
  482. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unicodedata +5 -0
  483. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unpack +15 -0
  484. data/lib/rubyfox/server/data/lib/Lib/test/output/test_urlparse +47 -0
  485. data/lib/rubyfox/server/data/lib/Lib/test/output/test_winreg +3 -0
  486. data/lib/rubyfox/server/data/lib/Lib/test/output/test_winsound +2 -0
  487. data/lib/rubyfox/server/data/lib/Lib/test/output/test_xreadline +4 -0
  488. data/lib/rubyfox/server/data/lib/Lib/test/pickletester.py +285 -0
  489. data/lib/rubyfox/server/data/lib/Lib/test/pydocfodder.py +210 -0
  490. data/lib/rubyfox/server/data/lib/Lib/test/pystone.py +252 -0
  491. data/lib/rubyfox/server/data/lib/Lib/test/re_tests.py +590 -0
  492. data/lib/rubyfox/server/data/lib/Lib/test/regex_tests.py +287 -0
  493. data/lib/rubyfox/server/data/lib/Lib/test/regrtest.py +1096 -0
  494. data/lib/rubyfox/server/data/lib/Lib/test/reperf.py +23 -0
  495. data/lib/rubyfox/server/data/lib/Lib/test/sortperf.py +141 -0
  496. data/lib/rubyfox/server/data/lib/Lib/test/string_tests.py +265 -0
  497. data/lib/rubyfox/server/data/lib/Lib/test/test.xml +115 -0
  498. data/lib/rubyfox/server/data/lib/Lib/test/test.xml.out +115 -0
  499. data/lib/rubyfox/server/data/lib/Lib/test/test_MimeWriter.py +170 -0
  500. data/lib/rubyfox/server/data/lib/Lib/test/test_SimpleXMLRPCServer.py +88 -0
  501. data/lib/rubyfox/server/data/lib/Lib/test/test_StringIO.py +113 -0
  502. data/lib/rubyfox/server/data/lib/Lib/test/test___all__.py +158 -0
  503. data/lib/rubyfox/server/data/lib/Lib/test/test___future__.py +59 -0
  504. data/lib/rubyfox/server/data/lib/Lib/test/test_al.py +23 -0
  505. data/lib/rubyfox/server/data/lib/Lib/test/test_array.py +438 -0
  506. data/lib/rubyfox/server/data/lib/Lib/test/test_asynchat.py +58 -0
  507. data/lib/rubyfox/server/data/lib/Lib/test/test_atexit.py +66 -0
  508. data/lib/rubyfox/server/data/lib/Lib/test/test_audioop.py +264 -0
  509. data/lib/rubyfox/server/data/lib/Lib/test/test_augassign.py +261 -0
  510. data/lib/rubyfox/server/data/lib/Lib/test/test_b1.py +632 -0
  511. data/lib/rubyfox/server/data/lib/Lib/test/test_b2.py +365 -0
  512. data/lib/rubyfox/server/data/lib/Lib/test/test_base64.py +53 -0
  513. data/lib/rubyfox/server/data/lib/Lib/test/test_bastion.py +3 -0
  514. data/lib/rubyfox/server/data/lib/Lib/test/test_binascii.py +119 -0
  515. data/lib/rubyfox/server/data/lib/Lib/test/test_binhex.py +50 -0
  516. data/lib/rubyfox/server/data/lib/Lib/test/test_binop.py +328 -0
  517. data/lib/rubyfox/server/data/lib/Lib/test/test_bisect.py +127 -0
  518. data/lib/rubyfox/server/data/lib/Lib/test/test_bsddb.py +76 -0
  519. data/lib/rubyfox/server/data/lib/Lib/test/test_bufio.py +60 -0
  520. data/lib/rubyfox/server/data/lib/Lib/test/test_bugfixes.py +31 -0
  521. data/lib/rubyfox/server/data/lib/Lib/test/test_builtin.py +13 -0
  522. data/lib/rubyfox/server/data/lib/Lib/test/test_calendar.py +61 -0
  523. data/lib/rubyfox/server/data/lib/Lib/test/test_call.py +131 -0
  524. data/lib/rubyfox/server/data/lib/Lib/test/test_capi.py +16 -0
  525. data/lib/rubyfox/server/data/lib/Lib/test/test_cd.py +26 -0
  526. data/lib/rubyfox/server/data/lib/Lib/test/test_cfgparser.py +284 -0
  527. data/lib/rubyfox/server/data/lib/Lib/test/test_cgi.py +188 -0
  528. data/lib/rubyfox/server/data/lib/Lib/test/test_charmapcodec.py +43 -0
  529. data/lib/rubyfox/server/data/lib/Lib/test/test_cl.py +78 -0
  530. data/lib/rubyfox/server/data/lib/Lib/test/test_class.py +317 -0
  531. data/lib/rubyfox/server/data/lib/Lib/test/test_cmath.py +35 -0
  532. data/lib/rubyfox/server/data/lib/Lib/test/test_codecs.py +31 -0
  533. data/lib/rubyfox/server/data/lib/Lib/test/test_codeop.py +190 -0
  534. data/lib/rubyfox/server/data/lib/Lib/test/test_coercion.py +118 -0
  535. data/lib/rubyfox/server/data/lib/Lib/test/test_commands.py +52 -0
  536. data/lib/rubyfox/server/data/lib/Lib/test/test_compare.py +56 -0
  537. data/lib/rubyfox/server/data/lib/Lib/test/test_compile.py +129 -0
  538. data/lib/rubyfox/server/data/lib/Lib/test/test_complex.py +68 -0
  539. data/lib/rubyfox/server/data/lib/Lib/test/test_contains.py +133 -0
  540. data/lib/rubyfox/server/data/lib/Lib/test/test_cookie.py +47 -0
  541. data/lib/rubyfox/server/data/lib/Lib/test/test_copy_reg.py +30 -0
  542. data/lib/rubyfox/server/data/lib/Lib/test/test_cpickle.py +81 -0
  543. data/lib/rubyfox/server/data/lib/Lib/test/test_crypt.py +11 -0
  544. data/lib/rubyfox/server/data/lib/Lib/test/test_curses.py +210 -0
  545. data/lib/rubyfox/server/data/lib/Lib/test/test_datetime.py +2958 -0
  546. data/lib/rubyfox/server/data/lib/Lib/test/test_dbm.py +43 -0
  547. data/lib/rubyfox/server/data/lib/Lib/test/test_descr.py +4094 -0
  548. data/lib/rubyfox/server/data/lib/Lib/test/test_descrtut.py +501 -0
  549. data/lib/rubyfox/server/data/lib/Lib/test/test_difflib.py +2 -0
  550. data/lib/rubyfox/server/data/lib/Lib/test/test_dircache.py +74 -0
  551. data/lib/rubyfox/server/data/lib/Lib/test/test_dl.py +33 -0
  552. data/lib/rubyfox/server/data/lib/Lib/test/test_doctest.py +2 -0
  553. data/lib/rubyfox/server/data/lib/Lib/test/test_doctest2.py +108 -0
  554. data/lib/rubyfox/server/data/lib/Lib/test/test_dospath.py +61 -0
  555. data/lib/rubyfox/server/data/lib/Lib/test/test_dumbdbm.py +79 -0
  556. data/lib/rubyfox/server/data/lib/Lib/test/test_email.py +13 -0
  557. data/lib/rubyfox/server/data/lib/Lib/test/test_email_codecs.py +11 -0
  558. data/lib/rubyfox/server/data/lib/Lib/test/test_enumerate.py +150 -0
  559. data/lib/rubyfox/server/data/lib/Lib/test/test_errno.py +49 -0
  560. data/lib/rubyfox/server/data/lib/Lib/test/test_exceptions.py +206 -0
  561. data/lib/rubyfox/server/data/lib/Lib/test/test_extcall.py +268 -0
  562. data/lib/rubyfox/server/data/lib/Lib/test/test_fcntl.py +53 -0
  563. data/lib/rubyfox/server/data/lib/Lib/test/test_file.py +63 -0
  564. data/lib/rubyfox/server/data/lib/Lib/test/test_fileinput.py +159 -0
  565. data/lib/rubyfox/server/data/lib/Lib/test/test_fnmatch.py +46 -0
  566. data/lib/rubyfox/server/data/lib/Lib/test/test_fork1.py +75 -0
  567. data/lib/rubyfox/server/data/lib/Lib/test/test_format.py +218 -0
  568. data/lib/rubyfox/server/data/lib/Lib/test/test_fpformat.py +75 -0
  569. data/lib/rubyfox/server/data/lib/Lib/test/test_frozen.py +26 -0
  570. data/lib/rubyfox/server/data/lib/Lib/test/test_funcattrs.py +384 -0
  571. data/lib/rubyfox/server/data/lib/Lib/test/test_future.py +47 -0
  572. data/lib/rubyfox/server/data/lib/Lib/test/test_future1.py +11 -0
  573. data/lib/rubyfox/server/data/lib/Lib/test/test_future2.py +10 -0
  574. data/lib/rubyfox/server/data/lib/Lib/test/test_future3.py +11 -0
  575. data/lib/rubyfox/server/data/lib/Lib/test/test_gc.py +346 -0
  576. data/lib/rubyfox/server/data/lib/Lib/test/test_gdbm.py +46 -0
  577. data/lib/rubyfox/server/data/lib/Lib/test/test_generators.py +1385 -0
  578. data/lib/rubyfox/server/data/lib/Lib/test/test_getargs.py +26 -0
  579. data/lib/rubyfox/server/data/lib/Lib/test/test_getopt.py +110 -0
  580. data/lib/rubyfox/server/data/lib/Lib/test/test_gettext.py +200 -0
  581. data/lib/rubyfox/server/data/lib/Lib/test/test_gl.py +150 -0
  582. data/lib/rubyfox/server/data/lib/Lib/test/test_glob.py +115 -0
  583. data/lib/rubyfox/server/data/lib/Lib/test/test_global.py +51 -0
  584. data/lib/rubyfox/server/data/lib/Lib/test/test_grammar.py +732 -0
  585. data/lib/rubyfox/server/data/lib/Lib/test/test_grp.py +27 -0
  586. data/lib/rubyfox/server/data/lib/Lib/test/test_gzip.py +82 -0
  587. data/lib/rubyfox/server/data/lib/Lib/test/test_hash.py +36 -0
  588. data/lib/rubyfox/server/data/lib/Lib/test/test_hmac.py +108 -0
  589. data/lib/rubyfox/server/data/lib/Lib/test/test_hotshot.py +117 -0
  590. data/lib/rubyfox/server/data/lib/Lib/test/test_htmllib.py +42 -0
  591. data/lib/rubyfox/server/data/lib/Lib/test/test_htmlparser.py +294 -0
  592. data/lib/rubyfox/server/data/lib/Lib/test/test_httplib.py +58 -0
  593. data/lib/rubyfox/server/data/lib/Lib/test/test_imageop.py +171 -0
  594. data/lib/rubyfox/server/data/lib/Lib/test/test_imgfile.py +116 -0
  595. data/lib/rubyfox/server/data/lib/Lib/test/test_import.py +71 -0
  596. data/lib/rubyfox/server/data/lib/Lib/test/test_importhooks.py +215 -0
  597. data/lib/rubyfox/server/data/lib/Lib/test/test_inspect.py +365 -0
  598. data/lib/rubyfox/server/data/lib/Lib/test/test_iter.py +784 -0
  599. data/lib/rubyfox/server/data/lib/Lib/test/test_janoninner.py +15 -0
  600. data/lib/rubyfox/server/data/lib/Lib/test/test_javalist.py +53 -0
  601. data/lib/rubyfox/server/data/lib/Lib/test/test_javashell.py +182 -0
  602. data/lib/rubyfox/server/data/lib/Lib/test/test_jbasic.py +119 -0
  603. data/lib/rubyfox/server/data/lib/Lib/test/test_joverload.py +138 -0
  604. data/lib/rubyfox/server/data/lib/Lib/test/test_jreload.py +33 -0
  605. data/lib/rubyfox/server/data/lib/Lib/test/test_jser.py +57 -0
  606. data/lib/rubyfox/server/data/lib/Lib/test/test_jser2.py +93 -0
  607. data/lib/rubyfox/server/data/lib/Lib/test/test_jsubclass.py +49 -0
  608. data/lib/rubyfox/server/data/lib/Lib/test/test_jy_compile.py +168 -0
  609. data/lib/rubyfox/server/data/lib/Lib/test/test_jy_generators.py +165 -0
  610. data/lib/rubyfox/server/data/lib/Lib/test/test_jy_internals.py +130 -0
  611. data/lib/rubyfox/server/data/lib/Lib/test/test_largefile.py +169 -0
  612. data/lib/rubyfox/server/data/lib/Lib/test/test_linuxaudiodev.py +89 -0
  613. data/lib/rubyfox/server/data/lib/Lib/test/test_locale.py +44 -0
  614. data/lib/rubyfox/server/data/lib/Lib/test/test_long.py +445 -0
  615. data/lib/rubyfox/server/data/lib/Lib/test/test_long_future.py +55 -0
  616. data/lib/rubyfox/server/data/lib/Lib/test/test_long_int_args.py +61 -0
  617. data/lib/rubyfox/server/data/lib/Lib/test/test_longexp.py +16 -0
  618. data/lib/rubyfox/server/data/lib/Lib/test/test_mailbox.py +113 -0
  619. data/lib/rubyfox/server/data/lib/Lib/test/test_marshal.py +44 -0
  620. data/lib/rubyfox/server/data/lib/Lib/test/test_math.py +153 -0
  621. data/lib/rubyfox/server/data/lib/Lib/test/test_md5.py +30 -0
  622. data/lib/rubyfox/server/data/lib/Lib/test/test_methods.py +62 -0
  623. data/lib/rubyfox/server/data/lib/Lib/test/test_mhlib.py +353 -0
  624. data/lib/rubyfox/server/data/lib/Lib/test/test_mimetools.py +18 -0
  625. data/lib/rubyfox/server/data/lib/Lib/test/test_mimetypes.py +59 -0
  626. data/lib/rubyfox/server/data/lib/Lib/test/test_minidom.py +648 -0
  627. data/lib/rubyfox/server/data/lib/Lib/test/test_mmap.py +317 -0
  628. data/lib/rubyfox/server/data/lib/Lib/test/test_module.py +77 -0
  629. data/lib/rubyfox/server/data/lib/Lib/test/test_multifile.py +66 -0
  630. data/lib/rubyfox/server/data/lib/Lib/test/test_mutants.py +285 -0
  631. data/lib/rubyfox/server/data/lib/Lib/test/test_netrc.py +42 -0
  632. data/lib/rubyfox/server/data/lib/Lib/test/test_new.py +108 -0
  633. data/lib/rubyfox/server/data/lib/Lib/test/test_nis.py +32 -0
  634. data/lib/rubyfox/server/data/lib/Lib/test/test_ntpath.py +114 -0
  635. data/lib/rubyfox/server/data/lib/Lib/test/test_opcodes.py +65 -0
  636. data/lib/rubyfox/server/data/lib/Lib/test/test_openpty.py +21 -0
  637. data/lib/rubyfox/server/data/lib/Lib/test/test_operations.py +475 -0
  638. data/lib/rubyfox/server/data/lib/Lib/test/test_operator.py +218 -0
  639. data/lib/rubyfox/server/data/lib/Lib/test/test_os.py +187 -0
  640. data/lib/rubyfox/server/data/lib/Lib/test/test_parser.py +383 -0
  641. data/lib/rubyfox/server/data/lib/Lib/test/test_pep247.py +50 -0
  642. data/lib/rubyfox/server/data/lib/Lib/test/test_pickle.py +40 -0
  643. data/lib/rubyfox/server/data/lib/Lib/test/test_pkg.py +259 -0
  644. data/lib/rubyfox/server/data/lib/Lib/test/test_pkgimport.py +84 -0
  645. data/lib/rubyfox/server/data/lib/Lib/test/test_poll.py +3 -0
  646. data/lib/rubyfox/server/data/lib/Lib/test/test_popen2.py +72 -0
  647. data/lib/rubyfox/server/data/lib/Lib/test/test_posixpath.py +40 -0
  648. data/lib/rubyfox/server/data/lib/Lib/test/test_pow.py +107 -0
  649. data/lib/rubyfox/server/data/lib/Lib/test/test_pprint.py +104 -0
  650. data/lib/rubyfox/server/data/lib/Lib/test/test_profile.py +86 -0
  651. data/lib/rubyfox/server/data/lib/Lib/test/test_profilehooks.py +360 -0
  652. data/lib/rubyfox/server/data/lib/Lib/test/test_pty.py +98 -0
  653. data/lib/rubyfox/server/data/lib/Lib/test/test_pwd.py +71 -0
  654. data/lib/rubyfox/server/data/lib/Lib/test/test_pyclbr.py +154 -0
  655. data/lib/rubyfox/server/data/lib/Lib/test/test_pyexpat.py +202 -0
  656. data/lib/rubyfox/server/data/lib/Lib/test/test_queue.py +158 -0
  657. data/lib/rubyfox/server/data/lib/Lib/test/test_quopri.py +157 -0
  658. data/lib/rubyfox/server/data/lib/Lib/test/test_random.py +19 -0
  659. data/lib/rubyfox/server/data/lib/Lib/test/test_re.py +304 -0
  660. data/lib/rubyfox/server/data/lib/Lib/test/test_regex.py +113 -0
  661. data/lib/rubyfox/server/data/lib/Lib/test/test_repr.py +278 -0
  662. data/lib/rubyfox/server/data/lib/Lib/test/test_rfc822.py +211 -0
  663. data/lib/rubyfox/server/data/lib/Lib/test/test_rgbimg.py +63 -0
  664. data/lib/rubyfox/server/data/lib/Lib/test/test_richcmp.py +261 -0
  665. data/lib/rubyfox/server/data/lib/Lib/test/test_rotor.py +28 -0
  666. data/lib/rubyfox/server/data/lib/Lib/test/test_sax.py +727 -0
  667. data/lib/rubyfox/server/data/lib/Lib/test/test_scope.py +530 -0
  668. data/lib/rubyfox/server/data/lib/Lib/test/test_select.py +228 -0
  669. data/lib/rubyfox/server/data/lib/Lib/test/test_select_new.py +229 -0
  670. data/lib/rubyfox/server/data/lib/Lib/test/test_sets.py +793 -0
  671. data/lib/rubyfox/server/data/lib/Lib/test/test_sgmllib.py +314 -0
  672. data/lib/rubyfox/server/data/lib/Lib/test/test_sha.py +52 -0
  673. data/lib/rubyfox/server/data/lib/Lib/test/test_signal.py +66 -0
  674. data/lib/rubyfox/server/data/lib/Lib/test/test_socket.py +1116 -0
  675. data/lib/rubyfox/server/data/lib/Lib/test/test_socket_ssl.py +27 -0
  676. data/lib/rubyfox/server/data/lib/Lib/test/test_socketserver.py +165 -0
  677. data/lib/rubyfox/server/data/lib/Lib/test/test_sre.py +434 -0
  678. data/lib/rubyfox/server/data/lib/Lib/test/test_str2unicode.py +90 -0
  679. data/lib/rubyfox/server/data/lib/Lib/test/test_strftime.py +146 -0
  680. data/lib/rubyfox/server/data/lib/Lib/test/test_string.py +223 -0
  681. data/lib/rubyfox/server/data/lib/Lib/test/test_strop.py +133 -0
  682. data/lib/rubyfox/server/data/lib/Lib/test/test_struct.py +441 -0
  683. data/lib/rubyfox/server/data/lib/Lib/test/test_structseq.py +28 -0
  684. data/lib/rubyfox/server/data/lib/Lib/test/test_subclasses.py +204 -0
  685. data/lib/rubyfox/server/data/lib/Lib/test/test_sunaudiodev.py +28 -0
  686. data/lib/rubyfox/server/data/lib/Lib/test/test_sundry.py +102 -0
  687. data/lib/rubyfox/server/data/lib/Lib/test/test_support.py +265 -0
  688. data/lib/rubyfox/server/data/lib/Lib/test/test_symtable.py +8 -0
  689. data/lib/rubyfox/server/data/lib/Lib/test/test_tempfile.py +10 -0
  690. data/lib/rubyfox/server/data/lib/Lib/test/test_thread.py +116 -0
  691. data/lib/rubyfox/server/data/lib/Lib/test/test_threaded_import.py +56 -0
  692. data/lib/rubyfox/server/data/lib/Lib/test/test_threadedtempfile.py +86 -0
  693. data/lib/rubyfox/server/data/lib/Lib/test/test_threading.py +55 -0
  694. data/lib/rubyfox/server/data/lib/Lib/test/test_time.py +47 -0
  695. data/lib/rubyfox/server/data/lib/Lib/test/test_timing.py +21 -0
  696. data/lib/rubyfox/server/data/lib/Lib/test/test_tokenize.py +9 -0
  697. data/lib/rubyfox/server/data/lib/Lib/test/test_trace.py +219 -0
  698. data/lib/rubyfox/server/data/lib/Lib/test/test_traceback.py +49 -0
  699. data/lib/rubyfox/server/data/lib/Lib/test/test_types.py +762 -0
  700. data/lib/rubyfox/server/data/lib/Lib/test/test_ucn.py +113 -0
  701. data/lib/rubyfox/server/data/lib/Lib/test/test_unary.py +58 -0
  702. data/lib/rubyfox/server/data/lib/Lib/test/test_unicode.py +815 -0
  703. data/lib/rubyfox/server/data/lib/Lib/test/test_unicode_file.py +95 -0
  704. data/lib/rubyfox/server/data/lib/Lib/test/test_unicodedata.py +125 -0
  705. data/lib/rubyfox/server/data/lib/Lib/test/test_unpack.py +105 -0
  706. data/lib/rubyfox/server/data/lib/Lib/test/test_urllib.py +109 -0
  707. data/lib/rubyfox/server/data/lib/Lib/test/test_urllib2.py +31 -0
  708. data/lib/rubyfox/server/data/lib/Lib/test/test_urlparse.py +94 -0
  709. data/lib/rubyfox/server/data/lib/Lib/test/test_userdict.py +120 -0
  710. data/lib/rubyfox/server/data/lib/Lib/test/test_userlist.py +269 -0
  711. data/lib/rubyfox/server/data/lib/Lib/test/test_userstring.py +43 -0
  712. data/lib/rubyfox/server/data/lib/Lib/test/test_uu.py +158 -0
  713. data/lib/rubyfox/server/data/lib/Lib/test/test_wave.py +34 -0
  714. data/lib/rubyfox/server/data/lib/Lib/test/test_weakref.py +573 -0
  715. data/lib/rubyfox/server/data/lib/Lib/test/test_winreg.py +151 -0
  716. data/lib/rubyfox/server/data/lib/Lib/test/test_winsound.py +6 -0
  717. data/lib/rubyfox/server/data/lib/Lib/test/test_xmllib.py +35 -0
  718. data/lib/rubyfox/server/data/lib/Lib/test/test_xmlrpc.py +37 -0
  719. data/lib/rubyfox/server/data/lib/Lib/test/test_xreadline.py +43 -0
  720. data/lib/rubyfox/server/data/lib/Lib/test/test_zipfile.py +78 -0
  721. data/lib/rubyfox/server/data/lib/Lib/test/test_zlib.py +482 -0
  722. data/lib/rubyfox/server/data/lib/Lib/test/testall.py +43 -0
  723. data/lib/rubyfox/server/data/lib/Lib/test/testcodec.py +48 -0
  724. data/lib/rubyfox/server/data/lib/Lib/test/testimg.uue +1170 -0
  725. data/lib/rubyfox/server/data/lib/Lib/test/testimgr.uue +1170 -0
  726. data/lib/rubyfox/server/data/lib/Lib/test/testrgb.uue +971 -0
  727. data/lib/rubyfox/server/data/lib/Lib/test/tokenize_tests.py +175 -0
  728. data/lib/rubyfox/server/data/lib/Lib/test/whrandom.py +96 -0
  729. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/dbextstest.py +266 -0
  730. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/jndi.py +33 -0
  731. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/runner.py +204 -0
  732. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/sptest.py +227 -0
  733. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/test.xml +363 -0
  734. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/test_zxjdbc_dbapi20.py +26 -0
  735. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/zxtest.py +1242 -0
  736. data/lib/rubyfox/server/data/lib/Lib/this.py +28 -0
  737. data/lib/rubyfox/server/data/lib/Lib/threading.py +698 -0
  738. data/lib/rubyfox/server/data/lib/Lib/token$py.class +0 -0
  739. data/lib/rubyfox/server/data/lib/Lib/token.py +140 -0
  740. data/lib/rubyfox/server/data/lib/Lib/tokenize$py.class +0 -0
  741. data/lib/rubyfox/server/data/lib/Lib/tokenize.py +287 -0
  742. data/lib/rubyfox/server/data/lib/Lib/traceback$py.class +0 -0
  743. data/lib/rubyfox/server/data/lib/Lib/traceback.py +301 -0
  744. data/lib/rubyfox/server/data/lib/Lib/tzparse.py +98 -0
  745. data/lib/rubyfox/server/data/lib/Lib/unittest.py +723 -0
  746. data/lib/rubyfox/server/data/lib/Lib/urllib.py +1465 -0
  747. data/lib/rubyfox/server/data/lib/Lib/urllib2.py +1144 -0
  748. data/lib/rubyfox/server/data/lib/Lib/urlparse.py +276 -0
  749. data/lib/rubyfox/server/data/lib/Lib/user.py +45 -0
  750. data/lib/rubyfox/server/data/lib/Lib/uu.py +195 -0
  751. data/lib/rubyfox/server/data/lib/Lib/warnings$py.class +0 -0
  752. data/lib/rubyfox/server/data/lib/Lib/warnings.py +258 -0
  753. data/lib/rubyfox/server/data/lib/Lib/weakref.py +280 -0
  754. data/lib/rubyfox/server/data/lib/Lib/whichdb.py +87 -0
  755. data/lib/rubyfox/server/data/lib/Lib/whrandom.py +140 -0
  756. data/lib/rubyfox/server/data/lib/Lib/xdrlib.py +285 -0
  757. data/lib/rubyfox/server/data/lib/Lib/xml/FtCore.py +58 -0
  758. data/lib/rubyfox/server/data/lib/Lib/xml/Uri.py +380 -0
  759. data/lib/rubyfox/server/data/lib/Lib/xml/__init__.py +41 -0
  760. data/lib/rubyfox/server/data/lib/Lib/xml/dom/MessageSource.py +54 -0
  761. data/lib/rubyfox/server/data/lib/Lib/xml/dom/NodeFilter.py +27 -0
  762. data/lib/rubyfox/server/data/lib/Lib/xml/dom/__init__.py +232 -0
  763. data/lib/rubyfox/server/data/lib/Lib/xml/dom/domreg.py +99 -0
  764. data/lib/rubyfox/server/data/lib/Lib/xml/dom/minicompat.py +184 -0
  765. data/lib/rubyfox/server/data/lib/Lib/xml/dom/minidom.py +1943 -0
  766. data/lib/rubyfox/server/data/lib/Lib/xml/dom/pulldom.py +350 -0
  767. data/lib/rubyfox/server/data/lib/Lib/xml/dom/xmlbuilder.py +388 -0
  768. data/lib/rubyfox/server/data/lib/Lib/xml/sax/__init__.py +102 -0
  769. data/lib/rubyfox/server/data/lib/Lib/xml/sax/_exceptions.py +127 -0
  770. data/lib/rubyfox/server/data/lib/Lib/xml/sax/drivers2/__init__.py +1 -0
  771. data/lib/rubyfox/server/data/lib/Lib/xml/sax/drivers2/drv_javasax.py +333 -0
  772. data/lib/rubyfox/server/data/lib/Lib/xml/sax/handler.py +345 -0
  773. data/lib/rubyfox/server/data/lib/Lib/xml/sax/saxlib.py +430 -0
  774. data/lib/rubyfox/server/data/lib/Lib/xml/sax/saxutils.py +813 -0
  775. data/lib/rubyfox/server/data/lib/Lib/xml/sax/xmlreader.py +378 -0
  776. data/lib/rubyfox/server/data/lib/Lib/xmllib.py +926 -0
  777. data/lib/rubyfox/server/data/lib/Lib/xmlrpclib.py +1019 -0
  778. data/lib/rubyfox/server/data/lib/Lib/zipfile.py +586 -0
  779. data/lib/rubyfox/server/data/lib/Lib/zlib.py +156 -0
  780. data/lib/rubyfox/server/data/lib/boot.jar +0 -0
  781. data/lib/rubyfox/server/data/lib/cachedir/.keep +0 -0
  782. data/lib/rubyfox/server/data/lib/commons-beanutils-1.7.0.jar +0 -0
  783. data/lib/rubyfox/server/data/lib/commons-collections-3.2.1.jar +0 -0
  784. data/lib/rubyfox/server/data/lib/commons-dbcp-1.4.jar +0 -0
  785. data/lib/rubyfox/server/data/lib/commons-io-1.4.jar +0 -0
  786. data/lib/rubyfox/server/data/lib/commons-lang-2.4.jar +0 -0
  787. data/lib/rubyfox/server/data/lib/commons-logging-1.1.1.jar +0 -0
  788. data/lib/rubyfox/server/data/lib/commons-pool-1.5.4.jar +0 -0
  789. data/lib/rubyfox/server/data/lib/commons-vfs-1.0.jar +0 -0
  790. data/lib/rubyfox/server/data/lib/ezmorph-1.0.6.jar +0 -0
  791. data/lib/rubyfox/server/data/lib/httpclient-4.0.3.jar +0 -0
  792. data/lib/rubyfox/server/data/lib/httpcore-4.0.1.jar +0 -0
  793. data/lib/rubyfox/server/data/lib/imap.jar +0 -0
  794. data/lib/rubyfox/server/data/lib/jconsole/COPYING.txt +504 -0
  795. data/lib/rubyfox/server/data/lib/jconsole/bug_test_case.py +49 -0
  796. data/lib/rubyfox/server/data/lib/jconsole/console$py.class +0 -0
  797. data/lib/rubyfox/server/data/lib/jconsole/console.py +439 -0
  798. data/lib/rubyfox/server/data/lib/jconsole/history$py.class +0 -0
  799. data/lib/rubyfox/server/data/lib/jconsole/history.py +82 -0
  800. data/lib/rubyfox/server/data/lib/jconsole/history_test_case.py +133 -0
  801. data/lib/rubyfox/server/data/lib/jconsole/introspect$py.class +0 -0
  802. data/lib/rubyfox/server/data/lib/jconsole/introspect.py +373 -0
  803. data/lib/rubyfox/server/data/lib/jconsole/introspect_test_case.py +19 -0
  804. data/lib/rubyfox/server/data/lib/jconsole/issue_17_test_case.py +36 -0
  805. data/lib/rubyfox/server/data/lib/jconsole/jintrospect$py.class +0 -0
  806. data/lib/rubyfox/server/data/lib/jconsole/jintrospect.py +316 -0
  807. data/lib/rubyfox/server/data/lib/jconsole/jintrospect_test_case.py +107 -0
  808. data/lib/rubyfox/server/data/lib/jconsole/popup$py.class +0 -0
  809. data/lib/rubyfox/server/data/lib/jconsole/popup.py +178 -0
  810. data/lib/rubyfox/server/data/lib/jconsole/run_tests.py +8 -0
  811. data/lib/rubyfox/server/data/lib/jconsole/static_test_case.py +36 -0
  812. data/lib/rubyfox/server/data/lib/jconsole/testcase.py +38 -0
  813. data/lib/rubyfox/server/data/lib/jconsole/tip$py.class +0 -0
  814. data/lib/rubyfox/server/data/lib/jconsole/tip.py +47 -0
  815. data/lib/rubyfox/server/data/lib/jmx-util-1.2.3.jar +0 -0
  816. data/lib/rubyfox/server/data/lib/joda-time-1.6.jar +0 -0
  817. data/lib/rubyfox/server/data/lib/js.jar +0 -0
  818. data/lib/rubyfox/server/data/lib/json-lib-2.2.3-jdk15.jar +0 -0
  819. data/lib/rubyfox/server/data/lib/jython.jar +0 -0
  820. data/lib/rubyfox/server/data/lib/log4j-1.2.15.jar +0 -0
  821. data/lib/rubyfox/server/data/lib/logs-backup-app.jar +0 -0
  822. data/lib/rubyfox/server/data/lib/mailapi.jar +0 -0
  823. data/lib/rubyfox/server/data/lib/pop3.jar +0 -0
  824. data/lib/rubyfox/server/data/lib/scala-library.jar +0 -0
  825. data/lib/rubyfox/server/data/lib/sfs2x-admin.jar +0 -0
  826. data/lib/rubyfox/server/data/lib/sfs2x-core.jar +0 -0
  827. data/lib/rubyfox/server/data/lib/sfs2x-util.jar +0 -0
  828. data/lib/rubyfox/server/data/lib/sfs2x.jar +0 -0
  829. data/lib/rubyfox/server/data/lib/slf4j-api-1.5.10.jar +0 -0
  830. data/lib/rubyfox/server/data/lib/slf4j-log4j12.jar +0 -0
  831. data/lib/rubyfox/server/data/lib/smtp.jar +0 -0
  832. data/lib/rubyfox/server/data/lib/terracotta-api-1.1.1.jar +0 -0
  833. data/lib/rubyfox/server/data/lib/ws-engine.jar +0 -0
  834. data/lib/rubyfox/server/data/lib/xpp3_min-1.1.4c.jar +0 -0
  835. data/lib/rubyfox/server/data/lib/xstream-1.3.1.jar +0 -0
  836. data/lib/rubyfox/server/data/logs/.keep +0 -0
  837. data/lib/rubyfox/server/data/logs/bluebox/.keep +0 -0
  838. data/lib/rubyfox/server/data/logs/boot/.keep +0 -0
  839. data/lib/rubyfox/server/data/logs/http/.keep +0 -0
  840. data/lib/rubyfox/server/data/logs/smartfox.log +295 -0
  841. data/lib/rubyfox/server/data/root/.keep +0 -0
  842. data/lib/rubyfox/server/data/root/_css_/default.css +170 -0
  843. data/lib/rubyfox/server/data/root/_css_/reset.css +49 -0
  844. data/lib/rubyfox/server/data/root/_images_/background_gradient.png +0 -0
  845. data/lib/rubyfox/server/data/root/_images_/background_logo.png +0 -0
  846. data/lib/rubyfox/server/data/root/_images_/favicon.png +0 -0
  847. data/lib/rubyfox/server/data/root/_images_/logo_smartfoxserver.png +0 -0
  848. data/lib/rubyfox/server/data/root/admin/.keep +0 -0
  849. data/lib/rubyfox/server/data/root/admin/AdminTool.html +108 -0
  850. data/lib/rubyfox/server/data/root/admin/AdminTool.swf +0 -0
  851. data/lib/rubyfox/server/data/root/admin/ReleaseNotes.txt +29 -0
  852. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/adobeFlashPlayer.png +0 -0
  853. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/advanced.png +0 -0
  854. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/banManager.png +0 -0
  855. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bannedIPs.png +0 -0
  856. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bannedUsernames.png +0 -0
  857. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bookmarks.png +0 -0
  858. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bootLog.png +0 -0
  859. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/buddyList.png +0 -0
  860. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/buddyProperties.png +0 -0
  861. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/connection.png +0 -0
  862. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/databaseManager.png +0 -0
  863. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/floodFilter.png +0 -0
  864. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/gameSettings.png +0 -0
  865. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/general.png +0 -0
  866. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/globalServerStatus.png +0 -0
  867. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/iPFilter.png +0 -0
  868. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/jVMSettings.png +0 -0
  869. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/logsDownload.png +0 -0
  870. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/mailer.png +0 -0
  871. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/permissionsAndEvents.png +0 -0
  872. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/privilegeManager.png +0 -0
  873. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/remoteAdmin.png +0 -0
  874. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/roomExtension.png +0 -0
  875. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/roomVariables.png +0 -0
  876. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/roomsAndGroups.png +0 -0
  877. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeLog.png +0 -0
  878. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeRoomSettings.png +0 -0
  879. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeUserSettings.png +0 -0
  880. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeZoneSettings.png +0 -0
  881. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/systemQueueStatus.png +0 -0
  882. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/userManagement.png +0 -0
  883. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/userVariables.png +0 -0
  884. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/usersTraffic.png +0 -0
  885. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/webServer.png +0 -0
  886. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/wordsFilter.png +0 -0
  887. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/zoneExtension.png +0 -0
  888. data/lib/rubyfox/server/data/root/admin/index.html +108 -0
  889. data/lib/rubyfox/server/data/root/admin/modules/BanManager/BanManager.swf +0 -0
  890. data/lib/rubyfox/server/data/root/admin/modules/BanManager/icon.png +0 -0
  891. data/lib/rubyfox/server/data/root/admin/modules/BlueBoxMonitor/BlueBoxMonitor.swf +0 -0
  892. data/lib/rubyfox/server/data/root/admin/modules/BlueBoxMonitor/icon.png +0 -0
  893. data/lib/rubyfox/server/data/root/admin/modules/LicenseManager/LicenseManager.swf +0 -0
  894. data/lib/rubyfox/server/data/root/admin/modules/LicenseManager/icon.png +0 -0
  895. data/lib/rubyfox/server/data/root/admin/modules/LogViewer/LogViewer.swf +0 -0
  896. data/lib/rubyfox/server/data/root/admin/modules/LogViewer/icon.png +0 -0
  897. data/lib/rubyfox/server/data/root/admin/modules/RuntimeStatistics/RuntimeStatistics.swf +0 -0
  898. data/lib/rubyfox/server/data/root/admin/modules/RuntimeStatistics/icon.png +0 -0
  899. data/lib/rubyfox/server/data/root/admin/modules/ServerConfigurator/ServerConfigurator.swf +0 -0
  900. data/lib/rubyfox/server/data/root/admin/modules/ServerConfigurator/icon.png +0 -0
  901. data/lib/rubyfox/server/data/root/admin/modules/ZoneConfigurator/ZoneConfigurator.swf +0 -0
  902. data/lib/rubyfox/server/data/root/admin/modules/ZoneConfigurator/icon.png +0 -0
  903. data/lib/rubyfox/server/data/root/admin/modules/ZoneMonitor/ZoneMonitor.swf +0 -0
  904. data/lib/rubyfox/server/data/root/admin/modules/ZoneMonitor/icon.png +0 -0
  905. data/lib/rubyfox/server/data/root/admin/modules/config.xml +12 -0
  906. data/lib/rubyfox/server/data/root/admin/playerProductInstall.swf +0 -0
  907. data/lib/rubyfox/server/data/root/admin/swfobject.js +777 -0
  908. data/lib/rubyfox/server/data/root/crossdomain.xml +6 -0
  909. data/lib/rubyfox/server/data/root/index.html +63 -0
  910. data/lib/rubyfox/server/data/sfs2x-service +435 -0
  911. data/lib/rubyfox/server/data/sfs2x-service.vmoptions +5 -0
  912. data/lib/rubyfox/server/data/sfs2x.sh +12 -0
  913. data/lib/rubyfox/server/data/www/.keep +0 -0
  914. data/lib/rubyfox/server/data/www/BlueBox.war +0 -0
  915. data/lib/rubyfox/server/data/www/root/_css_/default.css +170 -0
  916. data/lib/rubyfox/server/data/www/root/_css_/reset.css +49 -0
  917. data/lib/rubyfox/server/data/www/root/_images_/background_gradient.png +0 -0
  918. data/lib/rubyfox/server/data/www/root/_images_/background_logo.png +0 -0
  919. data/lib/rubyfox/server/data/www/root/_images_/favicon.png +0 -0
  920. data/lib/rubyfox/server/data/www/root/_images_/logo_smartfoxserver.png +0 -0
  921. data/lib/rubyfox/server/data/www/root/admin/.keep +0 -0
  922. data/lib/rubyfox/server/data/www/root/admin/AdminTool.html +108 -0
  923. data/lib/rubyfox/server/data/www/root/admin/AdminTool.swf +0 -0
  924. data/lib/rubyfox/server/data/www/root/admin/ReleaseNotes.txt +63 -0
  925. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/adobeFlashPlayer.png +0 -0
  926. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/advanced.png +0 -0
  927. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/banManager.png +0 -0
  928. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bannedIPs.png +0 -0
  929. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bannedUsernames.png +0 -0
  930. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bookmarks.png +0 -0
  931. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bootLog.png +0 -0
  932. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/buddyList.png +0 -0
  933. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/buddyProperties.png +0 -0
  934. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/connection.png +0 -0
  935. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/databaseManager.png +0 -0
  936. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/floodFilter.png +0 -0
  937. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/gameSettings.png +0 -0
  938. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/general.png +0 -0
  939. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/globalServerStatus.png +0 -0
  940. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/hTML5WebSockets.png +0 -0
  941. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/iPFilter.png +0 -0
  942. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/jVMSettings.png +0 -0
  943. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/logsDownload.png +0 -0
  944. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/mailer.png +0 -0
  945. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/permissionsAndEvents.png +0 -0
  946. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/privilegeManager.png +0 -0
  947. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/remoteAdmin.png +0 -0
  948. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomExtension.png +0 -0
  949. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomVariables.png +0 -0
  950. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomsAndGroups.png +0 -0
  951. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeLog.png +0 -0
  952. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeRoomSettings.png +0 -0
  953. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeUserSettings.png +0 -0
  954. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeZoneSettings.png +0 -0
  955. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/systemQueueStatus.png +0 -0
  956. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/userManagement.png +0 -0
  957. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/userVariables.png +0 -0
  958. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/usersTraffic.png +0 -0
  959. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/webServer.png +0 -0
  960. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/wordsFilter.png +0 -0
  961. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/zoneExtension.png +0 -0
  962. data/lib/rubyfox/server/data/www/root/admin/index.html +108 -0
  963. data/lib/rubyfox/server/data/www/root/admin/modules/BanManager/BanManager.swf +0 -0
  964. data/lib/rubyfox/server/data/www/root/admin/modules/BanManager/icon.png +0 -0
  965. data/lib/rubyfox/server/data/www/root/admin/modules/BlueBoxMonitor/BlueBoxMonitor.swf +0 -0
  966. data/lib/rubyfox/server/data/www/root/admin/modules/BlueBoxMonitor/icon.png +0 -0
  967. data/lib/rubyfox/server/data/www/root/admin/modules/Dashboard/Dashboard.swf +0 -0
  968. data/lib/rubyfox/server/data/www/root/admin/modules/Dashboard/icon.png +0 -0
  969. data/lib/rubyfox/server/data/www/root/admin/modules/LicenseManager/LicenseManager.swf +0 -0
  970. data/lib/rubyfox/server/data/www/root/admin/modules/LicenseManager/icon.png +0 -0
  971. data/lib/rubyfox/server/data/www/root/admin/modules/LogViewer/LogViewer.swf +0 -0
  972. data/lib/rubyfox/server/data/www/root/admin/modules/LogViewer/icon.png +0 -0
  973. data/lib/rubyfox/server/data/www/root/admin/modules/RuntimeStatistics/RuntimeStatistics.swf +0 -0
  974. data/lib/rubyfox/server/data/www/root/admin/modules/RuntimeStatistics/icon.png +0 -0
  975. data/lib/rubyfox/server/data/www/root/admin/modules/ServerConfigurator/ServerConfigurator.swf +0 -0
  976. data/lib/rubyfox/server/data/www/root/admin/modules/ServerConfigurator/icon.png +0 -0
  977. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneConfigurator/ZoneConfigurator.swf +0 -0
  978. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneConfigurator/icon.png +0 -0
  979. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneMonitor/ZoneMonitor.swf +0 -0
  980. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneMonitor/icon.png +0 -0
  981. data/lib/rubyfox/server/data/www/root/admin/modules/config.xml +12 -0
  982. data/lib/rubyfox/server/data/www/root/admin/playerProductInstall.swf +0 -0
  983. data/lib/rubyfox/server/data/www/root/admin/swfobject.js +777 -0
  984. data/lib/rubyfox/server/data/www/root/crossdomain.xml +6 -0
  985. data/lib/rubyfox/server/data/www/root/examples/.keep +0 -0
  986. data/lib/rubyfox/server/data/www/root/examples/index.html +43 -0
  987. data/lib/rubyfox/server/data/www/root/index.html +63 -0
  988. data/lib/rubyfox/server/data/zones/.keep +0 -0
  989. data/lib/rubyfox/server/environment.rb +31 -0
  990. data/lib/rubyfox/server/version.rb +5 -0
  991. data/lib/rubyfox/server.rb +9 -0
  992. data/rubyfox-server.gemspec +22 -0
  993. metadata +1076 -0
@@ -0,0 +1,2007 @@
1
+ """Concrete date/time and related types -- prototype implemented in Python.
2
+
3
+ See http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
4
+
5
+ See also http://dir.yahoo.com/Reference/calendars/
6
+
7
+ For a primer on DST, including many current DST rules, see
8
+ http://webexhibits.org/daylightsaving/
9
+
10
+ For more about DST than you ever wanted to know, see
11
+ ftp://elsie.nci.nih.gov/pub/
12
+
13
+ Sources for time zone and DST data: http://www.twinsun.com/tz/tz-link.htm
14
+
15
+ """
16
+
17
+ import time as _time
18
+ import math as _math
19
+
20
+ MINYEAR = 1
21
+ MAXYEAR = 9999
22
+
23
+ # Utility functions, adapted from Python's Demo/classes/Dates.py, which
24
+ # also assumes the current Gregorian calendar indefinitely extended in
25
+ # both directions. Difference: Dates.py calls January 1 of year 0 day
26
+ # number 1. The code here calls January 1 of year 1 day number 1. This is
27
+ # to match the definition of the "proleptic Gregorian" calendar in Dershowitz
28
+ # and Reingold's "Calendrical Calculations", where it's the base calendar
29
+ # for all computations. See the book for algorithms for converting between
30
+ # proleptic Gregorian ordinals and many other calendar systems.
31
+
32
+ _DAYS_IN_MONTH = [None, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
33
+
34
+ _DAYS_BEFORE_MONTH = [None]
35
+ dbm = 0
36
+ for dim in _DAYS_IN_MONTH[1:]:
37
+ _DAYS_BEFORE_MONTH.append(dbm)
38
+ dbm += dim
39
+ del dbm, dim
40
+
41
+ def _is_leap(year):
42
+ "year -> 1 if leap year, else 0."
43
+ return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
44
+
45
+ def _days_in_year(year):
46
+ "year -> number of days in year (366 if a leap year, else 365)."
47
+ return 365 + _is_leap(year)
48
+
49
+ def _days_before_year(year):
50
+ "year -> number of days before January 1st of year."
51
+ y = year - 1
52
+ return y*365 + y//4 - y//100 + y//400
53
+
54
+ def _days_in_month(year, month):
55
+ "year, month -> number of days in that month in that year."
56
+ assert 1 <= month <= 12, month
57
+ if month == 2 and _is_leap(year):
58
+ return 29
59
+ return _DAYS_IN_MONTH[month]
60
+
61
+ def _days_before_month(year, month):
62
+ "year, month -> number of days in year preceeding first day of month."
63
+ if not 1 <= month <= 12:
64
+ raise ValueError('month must be in 1..12', month)
65
+ return _DAYS_BEFORE_MONTH[month] + (month > 2 and _is_leap(year))
66
+
67
+ def _ymd2ord(year, month, day):
68
+ "year, month, day -> ordinal, considering 01-Jan-0001 as day 1."
69
+ if not 1 <= month <= 12:
70
+ raise ValueError('month must be in 1..12', month)
71
+ dim = _days_in_month(year, month)
72
+ if not 1 <= day <= dim:
73
+ raise ValueError('day must be in 1..%d' % dim, day)
74
+ return (_days_before_year(year) +
75
+ _days_before_month(year, month) +
76
+ day)
77
+
78
+ _DI400Y = _days_before_year(401) # number of days in 400 years
79
+ _DI100Y = _days_before_year(101) # " " " " 100 "
80
+ _DI4Y = _days_before_year(5) # " " " " 4 "
81
+
82
+ # A 4-year cycle has an extra leap day over what we'd get from pasting
83
+ # together 4 single years.
84
+ assert _DI4Y == 4 * 365 + 1
85
+
86
+ # Similarly, a 400-year cycle has an extra leap day over what we'd get from
87
+ # pasting together 4 100-year cycles.
88
+ assert _DI400Y == 4 * _DI100Y + 1
89
+
90
+ # OTOH, a 100-year cycle has one fewer leap day than we'd get from
91
+ # pasting together 25 4-year cycles.
92
+ assert _DI100Y == 25 * _DI4Y - 1
93
+
94
+ def _ord2ymd(n):
95
+ "ordinal -> (year, month, day), considering 01-Jan-0001 as day 1."
96
+
97
+ # n is a 1-based index, starting at 1-Jan-1. The pattern of leap years
98
+ # repeats exactly every 400 years. The basic strategy is to find the
99
+ # closest 400-year boundary at or before n, then work with the offset
100
+ # from that boundary to n. Life is much clearer if we subtract 1 from
101
+ # n first -- then the values of n at 400-year boundaries are exactly
102
+ # those divisible by _DI400Y:
103
+ #
104
+ # D M Y n n-1
105
+ # -- --- ---- ---------- ----------------
106
+ # 31 Dec -400 -_DI400Y -_DI400Y -1
107
+ # 1 Jan -399 -_DI400Y +1 -_DI400Y 400-year boundary
108
+ # ...
109
+ # 30 Dec 000 -1 -2
110
+ # 31 Dec 000 0 -1
111
+ # 1 Jan 001 1 0 400-year boundary
112
+ # 2 Jan 001 2 1
113
+ # 3 Jan 001 3 2
114
+ # ...
115
+ # 31 Dec 400 _DI400Y _DI400Y -1
116
+ # 1 Jan 401 _DI400Y +1 _DI400Y 400-year boundary
117
+ n -= 1
118
+ n400, n = divmod(n, _DI400Y)
119
+ year = n400 * 400 + 1 # ..., -399, 1, 401, ...
120
+
121
+ # Now n is the (non-negative) offset, in days, from January 1 of year, to
122
+ # the desired date. Now compute how many 100-year cycles precede n.
123
+ # Note that it's possible for n100 to equal 4! In that case 4 full
124
+ # 100-year cycles precede the desired day, which implies the desired
125
+ # day is December 31 at the end of a 400-year cycle.
126
+ n100, n = divmod(n, _DI100Y)
127
+
128
+ # Now compute how many 4-year cycles precede it.
129
+ n4, n = divmod(n, _DI4Y)
130
+
131
+ # And now how many single years. Again n1 can be 4, and again meaning
132
+ # that the desired day is December 31 at the end of the 4-year cycle.
133
+ n1, n = divmod(n, 365)
134
+
135
+ year += n100 * 100 + n4 * 4 + n1
136
+ if n1 == 4 or n100 == 4:
137
+ assert n == 0
138
+ return year-1, 12, 31
139
+
140
+ # Now the year is correct, and n is the offset from January 1. We find
141
+ # the month via an estimate that's either exact or one too large.
142
+ leapyear = n1 == 3 and (n4 != 24 or n100 == 3)
143
+ assert leapyear == _is_leap(year)
144
+ month = (n + 50) >> 5
145
+ preceding = _DAYS_BEFORE_MONTH[month] + (month > 2 and leapyear)
146
+ if preceding > n: # estimate is too large
147
+ month -= 1
148
+ preceding -= _DAYS_IN_MONTH[month] + (month == 2 and leapyear)
149
+ n -= preceding
150
+ assert 0 <= n < _days_in_month(year, month)
151
+
152
+ # Now the year and month are correct, and n is the offset from the
153
+ # start of that month: we're done!
154
+ return year, month, n+1
155
+
156
+ # Month and day names. For localized versions, see the calendar module.
157
+ _MONTHNAMES = [None, "Jan", "Feb", "Mar", "Apr", "May", "Jun",
158
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
159
+ _DAYNAMES = [None, "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
160
+
161
+
162
+ def _build_struct_time(y, m, d, hh, mm, ss, dstflag):
163
+ wday = (_ymd2ord(y, m, d) + 6) % 7
164
+ dnum = _days_before_month(y, m) + d
165
+ return _time.struct_time((y, m, d, hh, mm, ss, wday, dnum, dstflag))
166
+
167
+ def _format_time(hh, mm, ss, us):
168
+ # Skip trailing microseconds when us==0.
169
+ result = "%02d:%02d:%02d" % (hh, mm, ss)
170
+ if us:
171
+ result += ".%06d" % us
172
+ return result
173
+
174
+ # Correctly substitute for %z and %Z escapes in strftime formats.
175
+ def _wrap_strftime(object, format, timetuple):
176
+ year = timetuple[0]
177
+ if year < 1900:
178
+ raise ValueError("year=%d is before 1900; the datetime strftime() "
179
+ "methods require year >= 1900" % year)
180
+ # Don't call _utcoffset() or tzname() unless actually needed.
181
+ zreplace = None # the string to use for %z
182
+ Zreplace = None # the string to use for %Z
183
+
184
+ # Scan format for %z and %Z escapes, replacing as needed.
185
+ newformat = []
186
+ push = newformat.append
187
+ i, n = 0, len(format)
188
+ while i < n:
189
+ ch = format[i]
190
+ i += 1
191
+ if ch == '%':
192
+ if i < n:
193
+ ch = format[i]
194
+ i += 1
195
+ if ch == 'z':
196
+ if zreplace is None:
197
+ zreplace = ""
198
+ if hasattr(object, "_utcoffset"):
199
+ offset = object._utcoffset()
200
+ if offset is not None:
201
+ sign = '+'
202
+ if offset < 0:
203
+ offset = -offset
204
+ sign = '-'
205
+ h, m = divmod(offset, 60)
206
+ zreplace = '%c%02d%02d' % (sign, h, m)
207
+ assert '%' not in zreplace
208
+ newformat.append(zreplace)
209
+ elif ch == 'Z':
210
+ if Zreplace is None:
211
+ Zreplace = ""
212
+ if hasattr(object, "tzname"):
213
+ s = object.tzname()
214
+ if s is not None:
215
+ # strftime is going to have at this: escape %
216
+ Zreplace = s.replace('%', '%%')
217
+ newformat.append(Zreplace)
218
+ else:
219
+ push('%')
220
+ push(ch)
221
+ else:
222
+ push('%')
223
+ else:
224
+ push(ch)
225
+ newformat = "".join(newformat)
226
+ return _time.strftime(newformat, timetuple)
227
+
228
+ def _call_tzinfo_method(tzinfo, methname, tzinfoarg):
229
+ if tzinfo is None:
230
+ return None
231
+ return getattr(tzinfo, methname)(tzinfoarg)
232
+
233
+ # Just raise TypeError if the arg isn't None or a string.
234
+ def _check_tzname(name):
235
+ if name is not None and not isinstance(name, str):
236
+ raise TypeError("tzinfo.tzname() must return None or string, "
237
+ "not '%s'" % type(name))
238
+
239
+ # name is the offset-producing method, "utcoffset" or "dst".
240
+ # offset is what it returned.
241
+ # If offset isn't None or timedelta, raises TypeError.
242
+ # If offset is None, returns None.
243
+ # Else offset is checked for being in range, and a whole # of minutes.
244
+ # If it is, its integer value is returned. Else ValueError is raised.
245
+ def _check_utc_offset(name, offset):
246
+ assert name in ("utcoffset", "dst")
247
+ if offset is None:
248
+ return None
249
+ if not isinstance(offset, timedelta):
250
+ raise TypeError("tzinfo.%s() must return None "
251
+ "or timedelta, not '%s'" % (name, type(offset)))
252
+ days = offset.days
253
+ if days < -1 or days > 0:
254
+ offset = 1440 # trigger out-of-range
255
+ else:
256
+ seconds = days * 86400 + offset.seconds
257
+ minutes, seconds = divmod(seconds, 60)
258
+ if seconds or offset.microseconds:
259
+ raise ValueError("tzinfo.%s() must return a whole number "
260
+ "of minutes" % name)
261
+ offset = minutes
262
+ if -1440 < offset < 1440:
263
+ return offset
264
+ raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset))
265
+
266
+ def _check_date_fields(year, month, day):
267
+ if not MINYEAR <= year <= MAXYEAR:
268
+ raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year)
269
+ if not 1 <= month <= 12:
270
+ raise ValueError('month must be in 1..12', month)
271
+ dim = _days_in_month(year, month)
272
+ if not 1 <= day <= dim:
273
+ raise ValueError('day must be in 1..%d' % dim, day)
274
+
275
+ def _check_time_fields(hour, minute, second, microsecond):
276
+ if not 0 <= hour <= 23:
277
+ raise ValueError('hour must be in 0..23', hour)
278
+ if not 0 <= minute <= 59:
279
+ raise ValueError('minute must be in 0..59', minute)
280
+ if not 0 <= second <= 59:
281
+ raise ValueError('second must be in 0..59', second)
282
+ if not 0 <= microsecond <= 999999:
283
+ raise ValueError('microsecond must be in 0..999999', microsecond)
284
+
285
+ def _check_tzinfo_arg(tz):
286
+ if tz is not None and not isinstance(tz, tzinfo):
287
+ raise TypeError("tzinfo argument must be None or of a tzinfo subclass")
288
+
289
+
290
+ # Notes on comparison: In general, datetime module comparison operators raise
291
+ # TypeError when they don't know how to do a comparison themself. If they
292
+ # returned NotImplemented instead, comparison could (silently) fall back to
293
+ # the default compare-objects-by-comparing-their-memory-addresses strategy,
294
+ # and that's not helpful. There are two exceptions:
295
+ #
296
+ # 1. For date and datetime, if the other object has a "timetuple" attr,
297
+ # NotImplemented is returned. This is a hook to allow other kinds of
298
+ # datetime-like objects a chance to intercept the comparison.
299
+ #
300
+ # 2. Else __eq__ and __ne__ return False and True, respectively. This is
301
+ # so opertaions like
302
+ #
303
+ # x == y
304
+ # x != y
305
+ # x in sequence
306
+ # x not in sequence
307
+ # dict[x] = y
308
+ #
309
+ # don't raise annoying TypeErrors just because a datetime object
310
+ # is part of a heterogeneous collection. If there's no known way to
311
+ # compare X to a datetime, saying they're not equal is reasonable.
312
+
313
+ def _cmperror(x, y):
314
+ raise TypeError("can't compare '%s' to '%s'" % (
315
+ type(x).__name__, type(y).__name__))
316
+
317
+ # This is a start at a struct tm workalike. Goals:
318
+ #
319
+ # + Works the same way across platforms.
320
+ # + Handles all the fields datetime needs handled, without 1970-2038 glitches.
321
+ #
322
+ # Note: I suspect it's best if this flavor of tm does *not* try to
323
+ # second-guess timezones or DST. Instead fold whatever adjustments you want
324
+ # into the minutes argument (and the constructor will normalize).
325
+
326
+ _ORD1970 = _ymd2ord(1970, 1, 1) # base ordinal for UNIX epoch
327
+
328
+ class tmxxx:
329
+
330
+ ordinal = None
331
+
332
+ def __init__(self, year, month, day, hour=0, minute=0, second=0,
333
+ microsecond=0):
334
+ # Normalize all the inputs, and store the normalized values.
335
+ if not 0 <= microsecond <= 999999:
336
+ carry, microsecond = divmod(microsecond, 1000000)
337
+ second += carry
338
+ if not 0 <= second <= 59:
339
+ carry, second = divmod(second, 60)
340
+ minute += carry
341
+ if not 0 <= minute <= 59:
342
+ carry, minute = divmod(minute, 60)
343
+ hour += carry
344
+ if not 0 <= hour <= 23:
345
+ carry, hour = divmod(hour, 24)
346
+ day += carry
347
+
348
+ # That was easy. Now it gets muddy: the proper range for day
349
+ # can't be determined without knowing the correct month and year,
350
+ # but if day is, e.g., plus or minus a million, the current month
351
+ # and year values make no sense (and may also be out of bounds
352
+ # themselves).
353
+ # Saying 12 months == 1 year should be non-controversial.
354
+ if not 1 <= month <= 12:
355
+ carry, month = divmod(month-1, 12)
356
+ year += carry
357
+ month += 1
358
+ assert 1 <= month <= 12
359
+
360
+ # Now only day can be out of bounds (year may also be out of bounds
361
+ # for a datetime object, but we don't care about that here).
362
+ # If day is out of bounds, what to do is arguable, but at least the
363
+ # method here is principled and explainable.
364
+ dim = _days_in_month(year, month)
365
+ if not 1 <= day <= dim:
366
+ # Move day-1 days from the first of the month. First try to
367
+ # get off cheap if we're only one day out of range (adjustments
368
+ # for timezone alone can't be worse than that).
369
+ if day == 0: # move back a day
370
+ month -= 1
371
+ if month > 0:
372
+ day = _days_in_month(year, month)
373
+ else:
374
+ year, month, day = year-1, 12, 31
375
+ elif day == dim + 1: # move forward a day
376
+ month += 1
377
+ day = 1
378
+ if month > 12:
379
+ month = 1
380
+ year += 1
381
+ else:
382
+ self.ordinal = _ymd2ord(year, month, 1) + (day - 1)
383
+ year, month, day = _ord2ymd(self.ordinal)
384
+
385
+ self.year, self.month, self.day = year, month, day
386
+ self.hour, self.minute, self.second = hour, minute, second
387
+ self.microsecond = microsecond
388
+
389
+ def toordinal(self):
390
+ """Return proleptic Gregorian ordinal for the year, month and day.
391
+
392
+ January 1 of year 1 is day 1. Only the year, month and day values
393
+ contribute to the result.
394
+ """
395
+ if self.ordinal is None:
396
+ self.ordinal = _ymd2ord(self.year, self.month, self.day)
397
+ return self.ordinal
398
+
399
+ def time(self):
400
+ "Return Unixish timestamp, as a float (assuming UTC)."
401
+ days = self.toordinal() - _ORD1970 # convert to UNIX epoch
402
+ seconds = ((days * 24. + self.hour)*60. + self.minute)*60.
403
+ return seconds + self.second + self.microsecond / 1e6
404
+
405
+ def ctime(self):
406
+ "Return ctime() style string."
407
+ weekday = self.toordinal() % 7 or 7
408
+ return "%s %s %2d %02d:%02d:%02d %04d" % (
409
+ _DAYNAMES[weekday],
410
+ _MONTHNAMES[self.month],
411
+ self.day,
412
+ self.hour, self.minute, self.second,
413
+ self.year)
414
+
415
+ class timedelta(object):
416
+ """Represent the difference between two datetime objects.
417
+
418
+ Supported operators:
419
+
420
+ - add, subtract timedelta
421
+ - unary plus, minus, abs
422
+ - compare to timedelta
423
+ - multiply, divide by int/long
424
+
425
+ In addition, datetime supports subtraction of two datetime objects
426
+ returning a timedelta, and addition or subtraction of a datetime
427
+ and a timedelta giving a datetime.
428
+
429
+ Representation: (days, seconds, microseconds). Why? Because I
430
+ felt like it.
431
+ """
432
+
433
+ def __new__(cls, days=0, seconds=0, microseconds=0,
434
+ # XXX The following should only be used as keyword args:
435
+ milliseconds=0, minutes=0, hours=0, weeks=0):
436
+ # Doing this efficiently and accurately in C is going to be difficult
437
+ # and error-prone, due to ubiquitous overflow possibilities, and that
438
+ # C double doesn't have enough bits of precision to represent
439
+ # microseconds over 10K years faithfully. The code here tries to make
440
+ # explicit where go-fast assumptions can be relied on, in order to
441
+ # guide the C implementation; it's way more convoluted than speed-
442
+ # ignoring auto-overflow-to-long idiomatic Python could be.
443
+
444
+ # XXX Check that all inputs are ints, longs or floats.
445
+
446
+ # Final values, all integer.
447
+ # s and us fit in 32-bit signed ints; d isn't bounded.
448
+ d = s = us = 0
449
+
450
+ # Normalize everything to days, seconds, microseconds.
451
+ days += weeks*7
452
+ seconds += minutes*60 + hours*3600
453
+ microseconds += milliseconds*1000
454
+
455
+ # Get rid of all fractions, and normalize s and us.
456
+ # Take a deep breath <wink>.
457
+ if isinstance(days, float):
458
+ dayfrac, days = _math.modf(days)
459
+ daysecondsfrac, daysecondswhole = _math.modf(dayfrac * (24.*3600.))
460
+ assert daysecondswhole == int(daysecondswhole) # can't overflow
461
+ s = int(daysecondswhole)
462
+ assert days == long(days)
463
+ d = long(days)
464
+ else:
465
+ daysecondsfrac = 0.0
466
+ d = days
467
+ assert isinstance(daysecondsfrac, float)
468
+ assert abs(daysecondsfrac) <= 1.0
469
+ assert isinstance(d, (int, long))
470
+ assert abs(s) <= 24 * 3600
471
+ # days isn't referenced again before redefinition
472
+
473
+ if isinstance(seconds, float):
474
+ secondsfrac, seconds = _math.modf(seconds)
475
+ assert seconds == long(seconds)
476
+ seconds = long(seconds)
477
+ secondsfrac += daysecondsfrac
478
+ assert abs(secondsfrac) <= 2.0
479
+ else:
480
+ secondsfrac = daysecondsfrac
481
+ # daysecondsfrac isn't referenced again
482
+ assert isinstance(secondsfrac, float)
483
+ assert abs(secondsfrac) <= 2.0
484
+
485
+ assert isinstance(seconds, (int, long))
486
+ days, seconds = divmod(seconds, 24*3600)
487
+ d += days
488
+ s += int(seconds) # can't overflow
489
+ assert isinstance(s, int)
490
+ assert abs(s) <= 2 * 24 * 3600
491
+ # seconds isn't referenced again before redefinition
492
+
493
+ usdouble = secondsfrac * 1e6
494
+ assert abs(usdouble) < 2.1e6 # exact value not critical
495
+ # secondsfrac isn't referenced again
496
+
497
+ if isinstance(microseconds, float):
498
+ microseconds += usdouble
499
+ microseconds = round(microseconds)
500
+ seconds, microseconds = divmod(microseconds, 1e6)
501
+ assert microseconds == int(microseconds)
502
+ assert seconds == long(seconds)
503
+ days, seconds = divmod(seconds, 24.*3600.)
504
+ assert days == long(days)
505
+ assert seconds == int(seconds)
506
+ d += long(days)
507
+ s += int(seconds) # can't overflow
508
+ assert isinstance(s, int)
509
+ assert abs(s) <= 3 * 24 * 3600
510
+ else:
511
+ seconds, microseconds = divmod(microseconds, 1000000)
512
+ days, seconds = divmod(seconds, 24*3600)
513
+ d += days
514
+ s += int(seconds) # can't overflow
515
+ assert isinstance(s, int)
516
+ assert abs(s) <= 3 * 24 * 3600
517
+ microseconds = float(microseconds)
518
+ microseconds += usdouble
519
+ microseconds = round(microseconds)
520
+ assert abs(s) <= 3 * 24 * 3600
521
+ assert abs(microseconds) < 3.1e6
522
+
523
+ # Just a little bit of carrying possible for microseconds and seconds.
524
+ assert isinstance(microseconds, float)
525
+ assert int(microseconds) == microseconds
526
+ us = int(microseconds)
527
+ seconds, us = divmod(us, 1000000)
528
+ s += seconds # cant't overflow
529
+ assert isinstance(s, int)
530
+ days, s = divmod(s, 24*3600)
531
+ d += days
532
+
533
+ assert isinstance(d, (int, long))
534
+ assert isinstance(s, int) and 0 <= s < 24*3600
535
+ assert isinstance(us, int) and 0 <= us < 1000000
536
+
537
+ self = object.__new__(cls)
538
+
539
+ self.__days = d
540
+ self.__seconds = s
541
+ self.__microseconds = us
542
+ if abs(d) > 999999999:
543
+ raise OverflowError("timedelta # of days is too large: %d" % d)
544
+
545
+ return self
546
+
547
+ def __repr__(self):
548
+ if self.__microseconds:
549
+ return "%s(%d, %d, %d)" % ('datetime.' + self.__class__.__name__,
550
+ self.__days,
551
+ self.__seconds,
552
+ self.__microseconds)
553
+ if self.__seconds:
554
+ return "%s(%d, %d)" % ('datetime.' + self.__class__.__name__,
555
+ self.__days,
556
+ self.__seconds)
557
+ return "%s(%d)" % ('datetime.' + self.__class__.__name__, self.__days)
558
+
559
+ def __str__(self):
560
+ mm, ss = divmod(self.__seconds, 60)
561
+ hh, mm = divmod(mm, 60)
562
+ s = "%d:%02d:%02d" % (hh, mm, ss)
563
+ if self.__days:
564
+ def plural(n):
565
+ return n, abs(n) != 1 and "s" or ""
566
+ s = ("%d day%s, " % plural(self.__days)) + s
567
+ if self.__microseconds:
568
+ s = s + ".%06d" % self.__microseconds
569
+ return s
570
+
571
+ days = property(lambda self: self.__days, doc="days")
572
+ seconds = property(lambda self: self.__seconds, doc="seconds")
573
+ microseconds = property(lambda self: self.__microseconds,
574
+ doc="microseconds")
575
+
576
+ def __add__(self, other):
577
+ if isinstance(other, timedelta):
578
+ return self.__class__(self.__days + other.__days,
579
+ self.__seconds + other.__seconds,
580
+ self.__microseconds + other.__microseconds)
581
+ return NotImplemented
582
+
583
+ __radd__ = __add__
584
+
585
+ def __sub__(self, other):
586
+ if isinstance(other, timedelta):
587
+ return self + -other
588
+ return NotImplemented
589
+
590
+ def __rsub__(self, other):
591
+ if isinstance(other, timedelta):
592
+ return -self + other
593
+ return NotImplemented
594
+
595
+ def __neg__(self):
596
+ return self.__class__(-self.__days,
597
+ -self.__seconds,
598
+ -self.__microseconds)
599
+
600
+ def __pos__(self):
601
+ return self
602
+
603
+ def __abs__(self):
604
+ if self.__days < 0:
605
+ return -self
606
+ else:
607
+ return self
608
+
609
+ def __mul__(self, other):
610
+ if isinstance(other, (int, long)):
611
+ return self.__class__(self.__days * other,
612
+ self.__seconds * other,
613
+ self.__microseconds * other)
614
+ return NotImplemented
615
+
616
+ __rmul__ = __mul__
617
+
618
+ def __div__(self, other):
619
+ if isinstance(other, (int, long)):
620
+ usec = ((self.__days * (24*3600L) + self.__seconds) * 1000000 +
621
+ self.__microseconds)
622
+ return self.__class__(0, 0, usec // other)
623
+ return NotImplemented
624
+
625
+ __floordiv__ = __div__
626
+
627
+ # Comparisons.
628
+
629
+ def __eq__(self, other):
630
+ if isinstance(other, timedelta):
631
+ return self.__cmp(other) == 0
632
+ else:
633
+ return False
634
+
635
+ def __ne__(self, other):
636
+ if isinstance(other, timedelta):
637
+ return self.__cmp(other) != 0
638
+ else:
639
+ return True
640
+
641
+ def __le__(self, other):
642
+ if isinstance(other, timedelta):
643
+ return self.__cmp(other) <= 0
644
+ else:
645
+ _cmperror(self, other)
646
+
647
+ def __lt__(self, other):
648
+ if isinstance(other, timedelta):
649
+ return self.__cmp(other) < 0
650
+ else:
651
+ _cmperror(self, other)
652
+
653
+ def __ge__(self, other):
654
+ if isinstance(other, timedelta):
655
+ return self.__cmp(other) >= 0
656
+ else:
657
+ _cmperror(self, other)
658
+
659
+ def __gt__(self, other):
660
+ if isinstance(other, timedelta):
661
+ return self.__cmp(other) > 0
662
+ else:
663
+ _cmperror(self, other)
664
+
665
+ def __cmp(self, other):
666
+ assert isinstance(other, timedelta)
667
+ return cmp(self.__getstate(), other.__getstate())
668
+
669
+ def __hash__(self):
670
+ return hash(self.__getstate())
671
+
672
+ def __nonzero__(self):
673
+ return (self.__days != 0 or
674
+ self.__seconds != 0 or
675
+ self.__microseconds != 0)
676
+
677
+ # Pickle support.
678
+
679
+ __safe_for_unpickling__ = True # For Python 2.2
680
+
681
+ def __getstate(self):
682
+ return (self.__days, self.__seconds, self.__microseconds)
683
+
684
+ def __reduce__(self):
685
+ return (self.__class__, self.__getstate())
686
+
687
+ timedelta.min = timedelta(-999999999)
688
+ timedelta.max = timedelta(days=999999999, hours=23, minutes=59, seconds=59,
689
+ microseconds=999999)
690
+ timedelta.resolution = timedelta(microseconds=1)
691
+
692
+ class date(object):
693
+ """Concrete date type.
694
+
695
+ Constructors:
696
+
697
+ __new__()
698
+ fromtimestamp()
699
+ today()
700
+ fromordinal()
701
+
702
+ Operators:
703
+
704
+ __repr__, __str__
705
+ __cmp__, __hash__
706
+ __add__, __radd__, __sub__ (add/radd only with timedelta arg)
707
+
708
+ Methods:
709
+
710
+ timetuple()
711
+ toordinal()
712
+ weekday()
713
+ isoweekday(), isocalendar(), isoformat()
714
+ ctime()
715
+ strftime()
716
+
717
+ Properties (readonly):
718
+ year, month, day
719
+ """
720
+
721
+ def __new__(cls, year, month=None, day=None):
722
+ """Constructor.
723
+
724
+ Arguments:
725
+
726
+ year, month, day (required, base 1)
727
+ """
728
+ if isinstance(year, str):
729
+ # Pickle support
730
+ self = object.__new__(cls)
731
+ self.__setstate((year,))
732
+ return self
733
+ _check_date_fields(year, month, day)
734
+ self = object.__new__(cls)
735
+ self.__year = year
736
+ self.__month = month
737
+ self.__day = day
738
+ return self
739
+
740
+ # Additional constructors
741
+
742
+ def fromtimestamp(cls, t):
743
+ "Construct a date from a POSIX timestamp (like time.time())."
744
+ y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t)
745
+ return cls(y, m, d)
746
+ fromtimestamp = classmethod(fromtimestamp)
747
+
748
+ def today(cls):
749
+ "Construct a date from time.time()."
750
+ t = _time.time()
751
+ return cls.fromtimestamp(t)
752
+ today = classmethod(today)
753
+
754
+ def fromordinal(cls, n):
755
+ """Contruct a date from a proleptic Gregorian ordinal.
756
+
757
+ January 1 of year 1 is day 1. Only the year, month and day are
758
+ non-zero in the result.
759
+ """
760
+ y, m, d = _ord2ymd(n)
761
+ return cls(y, m, d)
762
+ fromordinal = classmethod(fromordinal)
763
+
764
+ # Conversions to string
765
+
766
+ def __repr__(self):
767
+ "Convert to formal string, for repr()."
768
+ return "%s(%d, %d, %d)" % ('datetime.' + self.__class__.__name__,
769
+ self.__year,
770
+ self.__month,
771
+ self.__day)
772
+ # XXX These shouldn't depend on time.localtime(), because that
773
+ # clips the usable dates to [1970 .. 2038). At least ctime() is
774
+ # easily done without using strftime() -- that's better too because
775
+ # strftime("%c", ...) is locale specific.
776
+
777
+ def ctime(self):
778
+ "Format a la ctime()."
779
+ return tmxxx(self.__year, self.__month, self.__day).ctime()
780
+
781
+ def strftime(self, fmt):
782
+ "Format using strftime()."
783
+ return _wrap_strftime(self, fmt, self.timetuple())
784
+
785
+ def isoformat(self):
786
+ """Return the date formatted according to ISO.
787
+
788
+ This is 'YYYY-MM-DD'.
789
+
790
+ References:
791
+ - http://www.w3.org/TR/NOTE-datetime
792
+ - http://www.cl.cam.ac.uk/~mgk25/iso-time.html
793
+ """
794
+ return "%04d-%02d-%02d" % (self.__year, self.__month, self.__day)
795
+
796
+ __str__ = isoformat
797
+
798
+ # Read-only field accessors
799
+ year = property(lambda self: self.__year,
800
+ doc="year (%d-%d)" % (MINYEAR, MAXYEAR))
801
+ month = property(lambda self: self.__month, doc="month (1-12)")
802
+ day = property(lambda self: self.__day, doc="day (1-31)")
803
+
804
+ # Standard conversions, __cmp__, __hash__ (and helpers)
805
+
806
+ def timetuple(self):
807
+ "Return local time tuple compatible with time.localtime()."
808
+ return _build_struct_time(self.__year, self.__month, self.__day,
809
+ 0, 0, 0, -1)
810
+
811
+ def toordinal(self):
812
+ """Return proleptic Gregorian ordinal for the year, month and day.
813
+
814
+ January 1 of year 1 is day 1. Only the year, month and day values
815
+ contribute to the result.
816
+ """
817
+ return _ymd2ord(self.__year, self.__month, self.__day)
818
+
819
+ def replace(self, year=None, month=None, day=None):
820
+ """Return a new date with new values for the specified fields."""
821
+ if year is None:
822
+ year = self.__year
823
+ if month is None:
824
+ month = self.__month
825
+ if day is None:
826
+ day = self.__day
827
+ _check_date_fields(year, month, day)
828
+ return date(year, month, day)
829
+
830
+ # Comparisons.
831
+
832
+ def __eq__(self, other):
833
+ if isinstance(other, date):
834
+ return self.__cmp(other) == 0
835
+ elif hasattr(other, "timetuple"):
836
+ return NotImplemented
837
+ else:
838
+ return False
839
+
840
+ def __ne__(self, other):
841
+ if isinstance(other, date):
842
+ return self.__cmp(other) != 0
843
+ elif hasattr(other, "timetuple"):
844
+ return NotImplemented
845
+ else:
846
+ return True
847
+
848
+ def __le__(self, other):
849
+ if isinstance(other, date):
850
+ return self.__cmp(other) <= 0
851
+ elif hasattr(other, "timetuple"):
852
+ return NotImplemented
853
+ else:
854
+ _cmperror(self, other)
855
+
856
+ def __lt__(self, other):
857
+ if isinstance(other, date):
858
+ return self.__cmp(other) < 0
859
+ elif hasattr(other, "timetuple"):
860
+ return NotImplemented
861
+ else:
862
+ _cmperror(self, other)
863
+
864
+ def __ge__(self, other):
865
+ if isinstance(other, date):
866
+ return self.__cmp(other) >= 0
867
+ elif hasattr(other, "timetuple"):
868
+ return NotImplemented
869
+ else:
870
+ _cmperror(self, other)
871
+
872
+ def __gt__(self, other):
873
+ if isinstance(other, date):
874
+ return self.__cmp(other) > 0
875
+ elif hasattr(other, "timetuple"):
876
+ return NotImplemented
877
+ else:
878
+ _cmperror(self, other)
879
+
880
+ def __cmp(self, other):
881
+ assert isinstance(other, date)
882
+ y, m, d = self.__year, self.__month, self.__day
883
+ y2, m2, d2 = other.__year, other.__month, other.__day
884
+ return cmp((y, m, d), (y2, m2, d2))
885
+
886
+ def __hash__(self):
887
+ "Hash."
888
+ return hash(self.__getstate())
889
+
890
+ # Computations
891
+
892
+ def _checkOverflow(self, year):
893
+ if not MINYEAR <= year <= MAXYEAR:
894
+ raise OverflowError("date +/-: result year %d not in %d..%d" %
895
+ (year, MINYEAR, MAXYEAR))
896
+
897
+ def __add__(self, other):
898
+ "Add a date to a timedelta."
899
+ if isinstance(other, timedelta):
900
+ t = tmxxx(self.__year,
901
+ self.__month,
902
+ self.__day + other.days)
903
+ self._checkOverflow(t.year)
904
+ result = self.__class__(t.year, t.month, t.day)
905
+ return result
906
+ raise TypeError
907
+ # XXX Should be 'return NotImplemented', but there's a bug in 2.2...
908
+
909
+ __radd__ = __add__
910
+
911
+ def __sub__(self, other):
912
+ """Subtract two dates, or a date and a timedelta."""
913
+ if isinstance(other, timedelta):
914
+ return self + timedelta(-other.days)
915
+ if isinstance(other, date):
916
+ days1 = self.toordinal()
917
+ days2 = other.toordinal()
918
+ return timedelta(days1 - days2)
919
+ return NotImplemented
920
+
921
+ def weekday(self):
922
+ "Return day of the week, where Monday == 0 ... Sunday == 6."
923
+ return (self.toordinal() + 6) % 7
924
+
925
+ # Day-of-the-week and week-of-the-year, according to ISO
926
+
927
+ def isoweekday(self):
928
+ "Return day of the week, where Monday == 1 ... Sunday == 7."
929
+ # 1-Jan-0001 is a Monday
930
+ return self.toordinal() % 7 or 7
931
+
932
+ def isocalendar(self):
933
+ """Return a 3-tuple containing ISO year, week number, and weekday.
934
+
935
+ The first ISO week of the year is the (Mon-Sun) week
936
+ containing the year's first Thursday; everything else derives
937
+ from that.
938
+
939
+ The first week is 1; Monday is 1 ... Sunday is 7.
940
+
941
+ ISO calendar algorithm taken from
942
+ http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
943
+ """
944
+ year = self.__year
945
+ week1monday = _isoweek1monday(year)
946
+ today = _ymd2ord(self.__year, self.__month, self.__day)
947
+ # Internally, week and day have origin 0
948
+ week, day = divmod(today - week1monday, 7)
949
+ if week < 0:
950
+ year -= 1
951
+ week1monday = _isoweek1monday(year)
952
+ week, day = divmod(today - week1monday, 7)
953
+ elif week >= 52:
954
+ if today >= _isoweek1monday(year+1):
955
+ year += 1
956
+ week = 0
957
+ return year, week+1, day+1
958
+
959
+ # Pickle support.
960
+
961
+ __safe_for_unpickling__ = True # For Python 2.2
962
+
963
+ def __getstate(self):
964
+ yhi, ylo = divmod(self.__year, 256)
965
+ return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), )
966
+
967
+ def __setstate(self, t):
968
+ assert isinstance(t, tuple) and len(t) == 1, `t`
969
+ string = t[0]
970
+ assert len(string) == 4
971
+ yhi, ylo, self.__month, self.__day = map(ord, string)
972
+ self.__year = yhi * 256 + ylo
973
+
974
+ def __reduce__(self):
975
+ return (self.__class__, self.__getstate())
976
+
977
+ _date_class = date # so functions w/ args named "date" can get at the class
978
+
979
+ date.min = date(1, 1, 1)
980
+ date.max = date(9999, 12, 31)
981
+ date.resolution = timedelta(days=1)
982
+
983
+ class tzinfo(object):
984
+ """Abstract base class for time zone info classes.
985
+
986
+ Subclasses must override the name(), utcoffset() and dst() methods.
987
+ """
988
+
989
+ def tzname(self, dt):
990
+ "datetime -> string name of time zone."
991
+ raise NotImplementedError("tzinfo subclass must override tzname()")
992
+
993
+ def utcoffset(self, dt):
994
+ "datetime -> minutes east of UTC (negative for west of UTC)"
995
+ raise NotImplementedError("tzinfo subclass must override utcoffset()")
996
+
997
+ def dst(self, dt):
998
+ """datetime -> DST offset in minutes east of UTC.
999
+
1000
+ Return 0 if DST not in effect. utcoffset() must include the DST
1001
+ offset.
1002
+ """
1003
+ raise NotImplementedError("tzinfo subclass must override dst()")
1004
+
1005
+ def fromutc(self, dt):
1006
+ "datetime in UTC -> datetime in local time."
1007
+
1008
+ if not isinstance(dt, datetime):
1009
+ raise TypeError("fromutc() requires a datetime argument")
1010
+ if dt.tzinfo is not self:
1011
+ raise ValueError("dt.tzinfo is not self")
1012
+
1013
+ dtoff = dt.utcoffset()
1014
+ if dtoff is None:
1015
+ raise ValueError("fromutc() requires a non-None utcoffset() "
1016
+ "result")
1017
+
1018
+ # See the long comment block at the end of this file for an
1019
+ # explanation of this algorithm.
1020
+ dtdst = dt.dst()
1021
+ if dtdst is None:
1022
+ raise ValueError("fromutc() requires a non-None dst() result")
1023
+ delta = dtoff - dtdst
1024
+ if delta:
1025
+ dt += delta
1026
+ dtdst = dt.dst()
1027
+ if dtdst is None:
1028
+ raise ValueError("fromutc(): dt.dst gave inconsistent "
1029
+ "results; cannot convert")
1030
+ if dtdst:
1031
+ return dt + dtdst
1032
+ else:
1033
+ return dt
1034
+
1035
+ # Pickle support.
1036
+
1037
+ __safe_for_unpickling__ = True # For Python 2.2
1038
+
1039
+ def __reduce__(self):
1040
+ getinitargs = getattr(self, "__getinitargs__", None)
1041
+ if getinitargs:
1042
+ args = getinitargs()
1043
+ else:
1044
+ args = ()
1045
+ getstate = getattr(self, "__getstate__", None)
1046
+ if getstate:
1047
+ state = getstate()
1048
+ else:
1049
+ state = getattr(self, "__dict__", None) or None
1050
+ if state is None:
1051
+ return (self.__class__, args)
1052
+ else:
1053
+ return (self.__class__, args, state)
1054
+
1055
+ _tzinfo_class = tzinfo # so functions w/ args named "tinfo" can get at it
1056
+
1057
+ class time(object):
1058
+ """Time with time zone.
1059
+
1060
+ Constructors:
1061
+
1062
+ __new__()
1063
+
1064
+ Operators:
1065
+
1066
+ __repr__, __str__
1067
+ __cmp__, __hash__
1068
+
1069
+ Methods:
1070
+
1071
+ strftime()
1072
+ isoformat()
1073
+ utcoffset()
1074
+ tzname()
1075
+ dst()
1076
+
1077
+ Properties (readonly):
1078
+ hour, minute, second, microsecond, tzinfo
1079
+ """
1080
+
1081
+ def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None):
1082
+ """Constructor.
1083
+
1084
+ Arguments:
1085
+
1086
+ hour, minute (required)
1087
+ second, microsecond (default to zero)
1088
+ tzinfo (default to None)
1089
+ """
1090
+ self = object.__new__(cls)
1091
+ if isinstance(hour, str):
1092
+ # Pickle support
1093
+ self.__setstate((hour, minute or None))
1094
+ return self
1095
+ _check_tzinfo_arg(tzinfo)
1096
+ _check_time_fields(hour, minute, second, microsecond)
1097
+ self.__hour = hour
1098
+ self.__minute = minute
1099
+ self.__second = second
1100
+ self.__microsecond = microsecond
1101
+ self._tzinfo = tzinfo
1102
+ return self
1103
+
1104
+ # Read-only field accessors
1105
+ hour = property(lambda self: self.__hour, doc="hour (0-23)")
1106
+ minute = property(lambda self: self.__minute, doc="minute (0-59)")
1107
+ second = property(lambda self: self.__second, doc="second (0-59)")
1108
+ microsecond = property(lambda self: self.__microsecond,
1109
+ doc="microsecond (0-999999)")
1110
+ tzinfo = property(lambda self: self._tzinfo, doc="timezone info object")
1111
+
1112
+ # Standard conversions, __hash__ (and helpers)
1113
+
1114
+ # Comparisons.
1115
+
1116
+ def __eq__(self, other):
1117
+ if isinstance(other, time):
1118
+ return self.__cmp(other) == 0
1119
+ else:
1120
+ return False
1121
+
1122
+ def __ne__(self, other):
1123
+ if isinstance(other, time):
1124
+ return self.__cmp(other) != 0
1125
+ else:
1126
+ return True
1127
+
1128
+ def __le__(self, other):
1129
+ if isinstance(other, time):
1130
+ return self.__cmp(other) <= 0
1131
+ else:
1132
+ _cmperror(self, other)
1133
+
1134
+ def __lt__(self, other):
1135
+ if isinstance(other, time):
1136
+ return self.__cmp(other) < 0
1137
+ else:
1138
+ _cmperror(self, other)
1139
+
1140
+ def __ge__(self, other):
1141
+ if isinstance(other, time):
1142
+ return self.__cmp(other) >= 0
1143
+ else:
1144
+ _cmperror(self, other)
1145
+
1146
+ def __gt__(self, other):
1147
+ if isinstance(other, time):
1148
+ return self.__cmp(other) > 0
1149
+ else:
1150
+ _cmperror(self, other)
1151
+
1152
+ def __cmp(self, other):
1153
+ assert isinstance(other, time)
1154
+ mytz = self._tzinfo
1155
+ ottz = other._tzinfo
1156
+ myoff = otoff = None
1157
+
1158
+ if mytz is ottz:
1159
+ base_compare = True
1160
+ else:
1161
+ myoff = self._utcoffset()
1162
+ otoff = other._utcoffset()
1163
+ base_compare = myoff == otoff
1164
+
1165
+ if base_compare:
1166
+ return cmp((self.__hour, self.__minute, self.__second,
1167
+ self.__microsecond),
1168
+ (other.__hour, other.__minute, other.__second,
1169
+ other.__microsecond))
1170
+ if myoff is None or otoff is None:
1171
+ # XXX Buggy in 2.2.2.
1172
+ raise TypeError("cannot compare naive and aware times")
1173
+ myhhmm = self.__hour * 60 + self.__minute - myoff
1174
+ othhmm = other.__hour * 60 + other.__minute - otoff
1175
+ return cmp((myhhmm, self.__second, self.__microsecond),
1176
+ (othhmm, other.__second, other.__microsecond))
1177
+
1178
+ def __hash__(self):
1179
+ """Hash."""
1180
+ tzoff = self._utcoffset()
1181
+ if not tzoff: # zero or None
1182
+ return hash(self.__getstate()[0])
1183
+ h, m = divmod(self.hour * 60 + self.minute - tzoff, 60)
1184
+ if 0 <= h < 24:
1185
+ return hash(time(h, m, self.second, self.microsecond))
1186
+ return hash((h, m, self.second, self.microsecond))
1187
+
1188
+ # Conversion to string
1189
+
1190
+ def _tzstr(self, sep=":"):
1191
+ """Return formatted timezone offset (+xx:xx) or None."""
1192
+ off = self._utcoffset()
1193
+ if off is not None:
1194
+ if off < 0:
1195
+ sign = "-"
1196
+ off = -off
1197
+ else:
1198
+ sign = "+"
1199
+ hh, mm = divmod(off, 60)
1200
+ assert 0 <= hh < 24
1201
+ off = "%s%02d%s%02d" % (sign, hh, sep, mm)
1202
+ return off
1203
+
1204
+ def __repr__(self):
1205
+ """Convert to formal string, for repr()."""
1206
+ if self.__microsecond != 0:
1207
+ s = ", %d, %d" % (self.__second, self.__microsecond)
1208
+ elif self.__second != 0:
1209
+ s = ", %d" % self.__second
1210
+ else:
1211
+ s = ""
1212
+ s= "%s(%d, %d%s)" % ('datetime.' + self.__class__.__name__,
1213
+ self.__hour, self.__minute, s)
1214
+ if self._tzinfo is not None:
1215
+ assert s[-1:] == ")"
1216
+ s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
1217
+ return s
1218
+
1219
+ def isoformat(self):
1220
+ """Return the time formatted according to ISO.
1221
+
1222
+ This is 'HH:MM:SS.mmmmmm+zz:zz', or 'HH:MM:SS+zz:zz' if
1223
+ self.microsecond == 0.
1224
+ """
1225
+ s = _format_time(self.__hour, self.__minute, self.__second,
1226
+ self.__microsecond)
1227
+ tz = self._tzstr()
1228
+ if tz:
1229
+ s += tz
1230
+ return s
1231
+
1232
+ __str__ = isoformat
1233
+
1234
+ def strftime(self, fmt):
1235
+ """Format using strftime(). The date part of the timestamp passed
1236
+ to underlying strftime should not be used.
1237
+ """
1238
+ # The year must be >= 1900 else Python's strftime implementation
1239
+ # can raise a bogus exception.
1240
+ timetuple = (1900, 1, 1,
1241
+ self.__hour, self.__minute, self.__second,
1242
+ 0, 1, -1)
1243
+ return _wrap_strftime(self, fmt, timetuple)
1244
+
1245
+ # Timezone functions
1246
+
1247
+ def utcoffset(self):
1248
+ """Return the timezone offset in minutes east of UTC (negative west of
1249
+ UTC)."""
1250
+ offset = _call_tzinfo_method(self._tzinfo, "utcoffset", None)
1251
+ offset = _check_utc_offset("utcoffset", offset)
1252
+ if offset is not None:
1253
+ offset = timedelta(minutes=offset)
1254
+ return offset
1255
+
1256
+ # Return an integer (or None) instead of a timedelta (or None).
1257
+ def _utcoffset(self):
1258
+ offset = _call_tzinfo_method(self._tzinfo, "utcoffset", None)
1259
+ offset = _check_utc_offset("utcoffset", offset)
1260
+ return offset
1261
+
1262
+ def tzname(self):
1263
+ """Return the timezone name.
1264
+
1265
+ Note that the name is 100% informational -- there's no requirement that
1266
+ it mean anything in particular. For example, "GMT", "UTC", "-500",
1267
+ "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies.
1268
+ """
1269
+ name = _call_tzinfo_method(self._tzinfo, "tzname", None)
1270
+ _check_tzname(name)
1271
+ return name
1272
+
1273
+ def dst(self):
1274
+ """Return 0 if DST is not in effect, or the DST offset (in minutes
1275
+ eastward) if DST is in effect.
1276
+
1277
+ This is purely informational; the DST offset has already been added to
1278
+ the UTC offset returned by utcoffset() if applicable, so there's no
1279
+ need to consult dst() unless you're interested in displaying the DST
1280
+ info.
1281
+ """
1282
+ offset = _call_tzinfo_method(self._tzinfo, "dst", None)
1283
+ offset = _check_utc_offset("dst", offset)
1284
+ if offset is not None:
1285
+ offset = timedelta(minutes=offset)
1286
+ return offset
1287
+
1288
+ def replace(self, hour=None, minute=None, second=None, microsecond=None,
1289
+ tzinfo=True):
1290
+ """Return a new time with new values for the specified fields."""
1291
+ if hour is None:
1292
+ hour = self.hour
1293
+ if minute is None:
1294
+ minute = self.minute
1295
+ if second is None:
1296
+ second = self.second
1297
+ if microsecond is None:
1298
+ microsecond = self.microsecond
1299
+ if tzinfo is True:
1300
+ tzinfo = self.tzinfo
1301
+ _check_time_fields(hour, minute, second, microsecond)
1302
+ _check_tzinfo_arg(tzinfo)
1303
+ return time(hour, minute, second, microsecond, tzinfo)
1304
+
1305
+ # Return an integer (or None) instead of a timedelta (or None).
1306
+ def _dst(self):
1307
+ offset = _call_tzinfo_method(self._tzinfo, "dst", None)
1308
+ offset = _check_utc_offset("dst", offset)
1309
+ return offset
1310
+
1311
+ def __nonzero__(self):
1312
+ if self.second or self.microsecond:
1313
+ return 1
1314
+ offset = self._utcoffset() or 0
1315
+ return self.hour * 60 + self.minute - offset != 0
1316
+
1317
+ # Pickle support.
1318
+
1319
+ __safe_for_unpickling__ = True # For Python 2.2
1320
+
1321
+ def __getstate(self):
1322
+ us2, us3 = divmod(self.__microsecond, 256)
1323
+ us1, us2 = divmod(us2, 256)
1324
+ basestate = ("%c" * 6) % (self.__hour, self.__minute, self.__second,
1325
+ us1, us2, us3)
1326
+ if self._tzinfo is None:
1327
+ return (basestate,)
1328
+ else:
1329
+ return (basestate, self._tzinfo)
1330
+
1331
+ def __setstate(self, state):
1332
+ assert isinstance(state, tuple)
1333
+ assert 1 <= len(state) <= 2
1334
+ string = state[0]
1335
+ assert len(string) == 6
1336
+ self.__hour, self.__minute, self.__second, us1, us2, us3 = \
1337
+ map(ord, string)
1338
+ self.__microsecond = (((us1 << 8) | us2) << 8) | us3
1339
+ if len(state) == 1:
1340
+ self._tzinfo = None
1341
+ else:
1342
+ self._tzinfo = state[1]
1343
+
1344
+ def __reduce__(self):
1345
+ return (self.__class__, self.__getstate())
1346
+
1347
+ _time_class = time # so functions w/ args named "time" can get at the class
1348
+
1349
+ time.min = time(0, 0, 0)
1350
+ time.max = time(23, 59, 59, 999999)
1351
+ time.resolution = timedelta(microseconds=1)
1352
+
1353
+ class datetime(date):
1354
+
1355
+ # XXX needs docstrings
1356
+ # See http://www.zope.org/Members/fdrake/DateTimeWiki/TimeZoneInfo
1357
+
1358
+ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0,
1359
+ microsecond=0, tzinfo=None):
1360
+ if isinstance(year, str):
1361
+ # Pickle support
1362
+ self = date.__new__(cls, year[:4])
1363
+ self.__setstate((year, month))
1364
+ return self
1365
+ _check_tzinfo_arg(tzinfo)
1366
+ _check_time_fields(hour, minute, second, microsecond)
1367
+ self = date.__new__(cls, year, month, day)
1368
+ # XXX This duplicates __year, __month, __day for convenience :-(
1369
+ self.__year = year
1370
+ self.__month = month
1371
+ self.__day = day
1372
+ self.__hour = hour
1373
+ self.__minute = minute
1374
+ self.__second = second
1375
+ self.__microsecond = microsecond
1376
+ self._tzinfo = tzinfo
1377
+ return self
1378
+
1379
+ # Read-only field accessors
1380
+ hour = property(lambda self: self.__hour, doc="hour (0-23)")
1381
+ minute = property(lambda self: self.__minute, doc="minute (0-59)")
1382
+ second = property(lambda self: self.__second, doc="second (0-59)")
1383
+ microsecond = property(lambda self: self.__microsecond,
1384
+ doc="microsecond (0-999999)")
1385
+ tzinfo = property(lambda self: self._tzinfo, doc="timezone info object")
1386
+
1387
+ def fromtimestamp(cls, t, tz=None):
1388
+ """Construct a datetime from a POSIX timestamp (like time.time()).
1389
+
1390
+ A timezone info object may be passed in as well.
1391
+ """
1392
+
1393
+ _check_tzinfo_arg(tz)
1394
+ if tz is None:
1395
+ converter = _time.localtime
1396
+ else:
1397
+ converter = _time.gmtime
1398
+ y, m, d, hh, mm, ss, weekday, jday, dst = converter(t)
1399
+ us = int((t % 1.0) * 1000000)
1400
+ ss = min(ss, 59) # clamp out leap seconds if the platform has them
1401
+ result = cls(y, m, d, hh, mm, ss, us, tz)
1402
+ if tz is not None:
1403
+ result = tz.fromutc(result)
1404
+ return result
1405
+ fromtimestamp = classmethod(fromtimestamp)
1406
+
1407
+ def utcfromtimestamp(cls, t):
1408
+ "Construct a UTC datetime from a POSIX timestamp (like time.time())."
1409
+ y, m, d, hh, mm, ss, weekday, jday, dst = _time.gmtime(t)
1410
+ us = int((t % 1.0) * 1000000)
1411
+ ss = min(ss, 59) # clamp out leap seconds if the platform has them
1412
+ return cls(y, m, d, hh, mm, ss, us)
1413
+ utcfromtimestamp = classmethod(utcfromtimestamp)
1414
+
1415
+ # XXX This is supposed to do better than we *can* do by using time.time(),
1416
+ # XXX if the platform supports a more accurate way. The C implementation
1417
+ # XXX uses gettimeofday on platforms that have it, but that isn't
1418
+ # XXX available from Python. So now() may return different results
1419
+ # XXX across the implementations.
1420
+ def now(cls, tz=None):
1421
+ "Construct a datetime from time.time() and optional time zone info."
1422
+ t = _time.time()
1423
+ return cls.fromtimestamp(t, tz)
1424
+ now = classmethod(now)
1425
+
1426
+ def utcnow(cls):
1427
+ "Construct a UTC datetime from time.time()."
1428
+ t = _time.time()
1429
+ return cls.utcfromtimestamp(t)
1430
+ utcnow = classmethod(utcnow)
1431
+
1432
+ def combine(cls, date, time):
1433
+ "Construct a datetime from a given date and a given time."
1434
+ if not isinstance(date, _date_class):
1435
+ raise TypeError("date argument must be a date instance")
1436
+ if not isinstance(time, _time_class):
1437
+ raise TypeError("time argument must be a time instance")
1438
+ return cls(date.year, date.month, date.day,
1439
+ time.hour, time.minute, time.second, time.microsecond,
1440
+ time.tzinfo)
1441
+ combine = classmethod(combine)
1442
+
1443
+ def timetuple(self):
1444
+ "Return local time tuple compatible with time.localtime()."
1445
+ dst = self._dst()
1446
+ if dst is None:
1447
+ dst = -1
1448
+ elif dst:
1449
+ dst = 1
1450
+ return _build_struct_time(self.year, self.month, self.day,
1451
+ self.hour, self.minute, self.second,
1452
+ dst)
1453
+
1454
+ def utctimetuple(self):
1455
+ "Return UTC time tuple compatible with time.gmtime()."
1456
+ y, m, d = self.year, self.month, self.day
1457
+ hh, mm, ss = self.hour, self.minute, self.second
1458
+ offset = self._utcoffset()
1459
+ if offset: # neither None nor 0
1460
+ tm = tmxxx(y, m, d, hh, mm - offset)
1461
+ y, m, d = tm.year, tm.month, tm.day
1462
+ hh, mm = tm.hour, tm.minute
1463
+ return _build_struct_time(y, m, d, hh, mm, ss, 0)
1464
+
1465
+ def date(self):
1466
+ "Return the date part."
1467
+ return date(self.__year, self.__month, self.__day)
1468
+
1469
+ def time(self):
1470
+ "Return the time part, with tzinfo None."
1471
+ return time(self.hour, self.minute, self.second, self.microsecond)
1472
+
1473
+ def timetz(self):
1474
+ "Return the time part, with same tzinfo."
1475
+ return time(self.hour, self.minute, self.second, self.microsecond,
1476
+ self._tzinfo)
1477
+
1478
+ def replace(self, year=None, month=None, day=None, hour=None,
1479
+ minute=None, second=None, microsecond=None, tzinfo=True):
1480
+ """Return a new datetime with new values for the specified fields."""
1481
+ if year is None:
1482
+ year = self.year
1483
+ if month is None:
1484
+ month = self.month
1485
+ if day is None:
1486
+ day = self.day
1487
+ if hour is None:
1488
+ hour = self.hour
1489
+ if minute is None:
1490
+ minute = self.minute
1491
+ if second is None:
1492
+ second = self.second
1493
+ if microsecond is None:
1494
+ microsecond = self.microsecond
1495
+ if tzinfo is True:
1496
+ tzinfo = self.tzinfo
1497
+ _check_date_fields(year, month, day)
1498
+ _check_time_fields(hour, minute, second, microsecond)
1499
+ _check_tzinfo_arg(tzinfo)
1500
+ return datetime(year, month, day, hour, minute, second,
1501
+ microsecond, tzinfo)
1502
+
1503
+ def astimezone(self, tz):
1504
+ if not isinstance(tz, tzinfo):
1505
+ raise TypeError("tz argument must be an instance of tzinfo")
1506
+
1507
+ mytz = self.tzinfo
1508
+ if mytz is None:
1509
+ raise ValueError("astimezone() requires an aware datetime")
1510
+
1511
+ if tz is mytz:
1512
+ return self
1513
+
1514
+ # Convert self to UTC, and attach the new time zone object.
1515
+ myoffset = self.utcoffset()
1516
+ if myoffset is None:
1517
+ raise ValuError("astimezone() requires an aware datetime")
1518
+ utc = (self - myoffset).replace(tzinfo=tz)
1519
+
1520
+ # Convert from UTC to tz's local time.
1521
+ return tz.fromutc(utc)
1522
+
1523
+ # Ways to produce a string.
1524
+
1525
+ def ctime(self):
1526
+ "Format a la ctime()."
1527
+ t = tmxxx(self.__year, self.__month, self.__day, self.__hour,
1528
+ self.__minute, self.__second)
1529
+ return t.ctime()
1530
+
1531
+ def isoformat(self, sep='T'):
1532
+ """Return the time formatted according to ISO.
1533
+
1534
+ This is 'YYYY-MM-DD HH:MM:SS.mmmmmm', or 'YYYY-MM-DD HH:MM:SS' if
1535
+ self.microsecond == 0.
1536
+
1537
+ If self.tzinfo is not None, the UTC offset is also attached, giving
1538
+ 'YYYY-MM-DD HH:MM:SS.mmmmmm+HH:MM' or 'YYYY-MM-DD HH:MM:SS+HH:MM'.
1539
+
1540
+ Optional argument sep specifies the separator between date and
1541
+ time, default 'T'.
1542
+ """
1543
+ s = ("%04d-%02d-%02d%c" % (self.__year, self.__month, self.__day,
1544
+ sep) +
1545
+ _format_time(self.__hour, self.__minute, self.__second,
1546
+ self.__microsecond))
1547
+ off = self._utcoffset()
1548
+ if off is not None:
1549
+ if off < 0:
1550
+ sign = "-"
1551
+ off = -off
1552
+ else:
1553
+ sign = "+"
1554
+ hh, mm = divmod(off, 60)
1555
+ s += "%s%02d:%02d" % (sign, hh, mm)
1556
+ return s
1557
+
1558
+ def __repr__(self):
1559
+ "Convert to formal string, for repr()."
1560
+ L = [self.__year, self.__month, self.__day, # These are never zero
1561
+ self.__hour, self.__minute, self.__second, self.__microsecond]
1562
+ while L[-1] == 0:
1563
+ del L[-1]
1564
+ s = ", ".join(map(str, L))
1565
+ s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s)
1566
+ if self._tzinfo is not None:
1567
+ assert s[-1:] == ")"
1568
+ s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
1569
+ return s
1570
+
1571
+ def __str__(self):
1572
+ "Convert to string, for str()."
1573
+ return self.isoformat(sep=' ')
1574
+
1575
+ def utcoffset(self):
1576
+ """Return the timezone offset in minutes east of UTC (negative west of
1577
+ UTC)."""
1578
+ offset = _call_tzinfo_method(self._tzinfo, "utcoffset", self)
1579
+ offset = _check_utc_offset("utcoffset", offset)
1580
+ if offset is not None:
1581
+ offset = timedelta(minutes=offset)
1582
+ return offset
1583
+
1584
+ # Return an integer (or None) instead of a timedelta (or None).
1585
+ def _utcoffset(self):
1586
+ offset = _call_tzinfo_method(self._tzinfo, "utcoffset", self)
1587
+ offset = _check_utc_offset("utcoffset", offset)
1588
+ return offset
1589
+
1590
+ def tzname(self):
1591
+ """Return the timezone name.
1592
+
1593
+ Note that the name is 100% informational -- there's no requirement that
1594
+ it mean anything in particular. For example, "GMT", "UTC", "-500",
1595
+ "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies.
1596
+ """
1597
+ name = _call_tzinfo_method(self._tzinfo, "tzname", self)
1598
+ _check_tzname(name)
1599
+ return name
1600
+
1601
+ def dst(self):
1602
+ """Return 0 if DST is not in effect, or the DST offset (in minutes
1603
+ eastward) if DST is in effect.
1604
+
1605
+ This is purely informational; the DST offset has already been added to
1606
+ the UTC offset returned by utcoffset() if applicable, so there's no
1607
+ need to consult dst() unless you're interested in displaying the DST
1608
+ info.
1609
+ """
1610
+ offset = _call_tzinfo_method(self._tzinfo, "dst", self)
1611
+ offset = _check_utc_offset("dst", offset)
1612
+ if offset is not None:
1613
+ offset = timedelta(minutes=offset)
1614
+ return offset
1615
+
1616
+ # Return an integer (or None) instead of a timedelta (or None).1573
1617
+ def _dst(self):
1618
+ offset = _call_tzinfo_method(self._tzinfo, "dst", self)
1619
+ offset = _check_utc_offset("dst", offset)
1620
+ return offset
1621
+
1622
+ # Comparisons.
1623
+
1624
+ def __eq__(self, other):
1625
+ if isinstance(other, datetime):
1626
+ return self.__cmp(other) == 0
1627
+ elif hasattr(other, "timetuple"):
1628
+ return NotImplemented
1629
+ else:
1630
+ return False
1631
+
1632
+ def __ne__(self, other):
1633
+ if isinstance(other, datetime):
1634
+ return self.__cmp(other) != 0
1635
+ elif hasattr(other, "timetuple"):
1636
+ return NotImplemented
1637
+ else:
1638
+ return True
1639
+
1640
+ def __le__(self, other):
1641
+ if isinstance(other, datetime):
1642
+ return self.__cmp(other) <= 0
1643
+ elif hasattr(other, "timetuple"):
1644
+ return NotImplemented
1645
+ else:
1646
+ _cmperror(self, other)
1647
+
1648
+ def __lt__(self, other):
1649
+ if isinstance(other, datetime):
1650
+ return self.__cmp(other) < 0
1651
+ elif hasattr(other, "timetuple"):
1652
+ return NotImplemented
1653
+ else:
1654
+ _cmperror(self, other)
1655
+
1656
+ def __ge__(self, other):
1657
+ if isinstance(other, datetime):
1658
+ return self.__cmp(other) >= 0
1659
+ elif hasattr(other, "timetuple"):
1660
+ return NotImplemented
1661
+ else:
1662
+ _cmperror(self, other)
1663
+
1664
+ def __gt__(self, other):
1665
+ if isinstance(other, datetime):
1666
+ return self.__cmp(other) > 0
1667
+ elif hasattr(other, "timetuple"):
1668
+ return NotImplemented
1669
+ else:
1670
+ _cmperror(self, other)
1671
+
1672
+ def __cmp(self, other):
1673
+ assert isinstance(other, datetime)
1674
+ mytz = self._tzinfo
1675
+ ottz = other._tzinfo
1676
+ myoff = otoff = None
1677
+
1678
+ if mytz is ottz:
1679
+ base_compare = True
1680
+ else:
1681
+ if mytz is not None:
1682
+ myoff = self._utcoffset()
1683
+ if ottz is not None:
1684
+ otoff = other._utcoffset()
1685
+ base_compare = myoff == otoff
1686
+
1687
+ if base_compare:
1688
+ return cmp((self.__year, self.__month, self.__day,
1689
+ self.__hour, self.__minute, self.__second,
1690
+ self.__microsecond),
1691
+ (other.__year, other.__month, other.__day,
1692
+ other.__hour, other.__minute, other.__second,
1693
+ other.__microsecond))
1694
+ if myoff is None or otoff is None:
1695
+ # XXX Buggy in 2.2.2.
1696
+ raise TypeError("cannot compare naive and aware datetimes")
1697
+ # XXX What follows could be done more efficiently...
1698
+ diff = self - other # this will take offsets into account
1699
+ if diff.days < 0:
1700
+ return -1
1701
+ return diff and 1 or 0
1702
+
1703
+ def __add__(self, other):
1704
+ "Add a datetime and a timedelta."
1705
+ if not isinstance(other, timedelta):
1706
+ return NotImplemented
1707
+ t = tmxxx(self.__year,
1708
+ self.__month,
1709
+ self.__day + other.days,
1710
+ self.__hour,
1711
+ self.__minute,
1712
+ self.__second + other.seconds,
1713
+ self.__microsecond + other.microseconds)
1714
+ self._checkOverflow(t.year)
1715
+ result = self.__class__(t.year, t.month, t.day,
1716
+ t.hour, t.minute, t.second,
1717
+ t.microsecond, tzinfo=self._tzinfo)
1718
+ return result
1719
+
1720
+ __radd__ = __add__
1721
+
1722
+ def __sub__(self, other):
1723
+ "Subtract two datetimes, or a datetime and a timedelta."
1724
+ if not isinstance(other, datetime):
1725
+ if isinstance(other, timedelta):
1726
+ return self + -other
1727
+ return NotImplemented
1728
+
1729
+ days1 = self.toordinal()
1730
+ days2 = other.toordinal()
1731
+ secs1 = self.__second + self.__minute * 60 + self.__hour * 3600
1732
+ secs2 = other.__second + other.__minute * 60 + other.__hour * 3600
1733
+ base = timedelta(days1 - days2,
1734
+ secs1 - secs2,
1735
+ self.__microsecond - other.__microsecond)
1736
+ if self._tzinfo is other._tzinfo:
1737
+ return base
1738
+ myoff = self._utcoffset()
1739
+ otoff = other._utcoffset()
1740
+ if myoff == otoff:
1741
+ return base
1742
+ if myoff is None or otoff is None:
1743
+ raise TypeError, "cannot mix naive and timezone-aware time"
1744
+ return base + timedelta(minutes = otoff-myoff)
1745
+
1746
+ def __hash__(self):
1747
+ tzoff = self._utcoffset()
1748
+ if tzoff is None:
1749
+ return hash(self.__getstate()[0])
1750
+ days = _ymd2ord(self.year, self.month, self.day)
1751
+ seconds = self.hour * 3600 + (self.minute - tzoff) * 60 + self.second
1752
+ return hash(timedelta(days, seconds, self.microsecond))
1753
+
1754
+ # Pickle support.
1755
+
1756
+ __safe_for_unpickling__ = True # For Python 2.2
1757
+
1758
+ def __getstate(self):
1759
+ yhi, ylo = divmod(self.__year, 256)
1760
+ us2, us3 = divmod(self.__microsecond, 256)
1761
+ us1, us2 = divmod(us2, 256)
1762
+ basestate = ("%c" * 10) % (yhi, ylo, self.__month, self.__day,
1763
+ self.__hour, self.__minute, self.__second,
1764
+ us1, us2, us3)
1765
+ if self._tzinfo is None:
1766
+ return (basestate,)
1767
+ else:
1768
+ return (basestate, self._tzinfo)
1769
+
1770
+ def __setstate(self, state):
1771
+ assert isinstance(state, tuple)
1772
+ assert 1 <= len(state) <= 2
1773
+ string = state[0]
1774
+ assert len(string) == 10
1775
+ (yhi, ylo, self.__month, self.__day, self.__hour,
1776
+ self.__minute, self.__second, us1, us2, us3) = map(ord, string)
1777
+ self.__year = yhi * 256 + ylo
1778
+ self.__microsecond = (((us1 << 8) | us2) << 8) | us3
1779
+ if len(state) == 1:
1780
+ self._tzinfo = None
1781
+ else:
1782
+ self._tzinfo = state[1]
1783
+
1784
+ def __reduce__(self):
1785
+ return (self.__class__, self.__getstate())
1786
+
1787
+
1788
+ datetime.min = datetime(1, 1, 1)
1789
+ datetime.max = datetime(9999, 12, 31, 23, 59, 59, 999999)
1790
+ datetime.resolution = timedelta(microseconds=1)
1791
+
1792
+
1793
+ def _isoweek1monday(year):
1794
+ # Helper to calculate the day number of the Monday starting week 1
1795
+ # XXX This could be done more efficiently
1796
+ THURSDAY = 3
1797
+ firstday = _ymd2ord(year, 1, 1)
1798
+ firstweekday = (firstday + 6) % 7 # See weekday() above
1799
+ week1monday = firstday - firstweekday
1800
+ if firstweekday > THURSDAY:
1801
+ week1monday += 7
1802
+ return week1monday
1803
+
1804
+ """
1805
+ Some time zone algebra. For a datetime x, let
1806
+ x.n = x stripped of its timezone -- its naive time.
1807
+ x.o = x.utcoffset(), and assuming that doesn't raise an exception or
1808
+ return None
1809
+ x.d = x.dst(), and assuming that doesn't raise an exception or
1810
+ return None
1811
+ x.s = x's standard offset, x.o - x.d
1812
+
1813
+ Now some derived rules, where k is a duration (timedelta).
1814
+
1815
+ 1. x.o = x.s + x.d
1816
+ This follows from the definition of x.s.
1817
+
1818
+ 2. If x and y have the same tzinfo member, x.s = y.s.
1819
+ This is actually a requirement, an assumption we need to make about
1820
+ sane tzinfo classes.
1821
+
1822
+ 3. The naive UTC time corresponding to x is x.n - x.o.
1823
+ This is again a requirement for a sane tzinfo class.
1824
+
1825
+ 4. (x+k).s = x.s
1826
+ This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
1827
+
1828
+ 5. (x+k).n = x.n + k
1829
+ Again follows from how arithmetic is defined.
1830
+
1831
+ Now we can explain tz.fromutc(x). Let's assume it's an interesting case
1832
+ (meaning that the various tzinfo methods exist, and don't blow up or return
1833
+ None when called).
1834
+
1835
+ The function wants to return a datetime y with timezone tz, equivalent to x.
1836
+ x is already in UTC.
1837
+
1838
+ By #3, we want
1839
+
1840
+ y.n - y.o = x.n [1]
1841
+
1842
+ The algorithm starts by attaching tz to x.n, and calling that y. So
1843
+ x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
1844
+ becomes true; in effect, we want to solve [2] for k:
1845
+
1846
+ (y+k).n - (y+k).o = x.n [2]
1847
+
1848
+ By #1, this is the same as
1849
+
1850
+ (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
1851
+
1852
+ By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
1853
+ Substituting that into [3],
1854
+
1855
+ x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
1856
+ k - (y+k).s - (y+k).d = 0; rearranging,
1857
+ k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
1858
+ k = y.s - (y+k).d
1859
+
1860
+ On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
1861
+ approximate k by ignoring the (y+k).d term at first. Note that k can't be
1862
+ very large, since all offset-returning methods return a duration of magnitude
1863
+ less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
1864
+ be 0, so ignoring it has no consequence then.
1865
+
1866
+ In any case, the new value is
1867
+
1868
+ z = y + y.s [4]
1869
+
1870
+ It's helpful to step back at look at [4] from a higher level: it's simply
1871
+ mapping from UTC to tz's standard time.
1872
+
1873
+ At this point, if
1874
+
1875
+ z.n - z.o = x.n [5]
1876
+
1877
+ we have an equivalent time, and are almost done. The insecurity here is
1878
+ at the start of daylight time. Picture US Eastern for concreteness. The wall
1879
+ time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
1880
+ sense then. The docs ask that an Eastern tzinfo class consider such a time to
1881
+ be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
1882
+ on the day DST starts. We want to return the 1:MM EST spelling because that's
1883
+ the only spelling that makes sense on the local wall clock.
1884
+
1885
+ In fact, if [5] holds at this point, we do have the standard-time spelling,
1886
+ but that takes a bit of proof. We first prove a stronger result. What's the
1887
+ difference between the LHS and RHS of [5]? Let
1888
+
1889
+ diff = x.n - (z.n - z.o) [6]
1890
+
1891
+ Now
1892
+ z.n = by [4]
1893
+ (y + y.s).n = by #5
1894
+ y.n + y.s = since y.n = x.n
1895
+ x.n + y.s = since z and y are have the same tzinfo member,
1896
+ y.s = z.s by #2
1897
+ x.n + z.s
1898
+
1899
+ Plugging that back into [6] gives
1900
+
1901
+ diff =
1902
+ x.n - ((x.n + z.s) - z.o) = expanding
1903
+ x.n - x.n - z.s + z.o = cancelling
1904
+ - z.s + z.o = by #2
1905
+ z.d
1906
+
1907
+ So diff = z.d.
1908
+
1909
+ If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
1910
+ spelling we wanted in the endcase described above. We're done. Contrarily,
1911
+ if z.d = 0, then we have a UTC equivalent, and are also done.
1912
+
1913
+ If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
1914
+ add to z (in effect, z is in tz's standard time, and we need to shift the
1915
+ local clock into tz's daylight time).
1916
+
1917
+ Let
1918
+
1919
+ z' = z + z.d = z + diff [7]
1920
+
1921
+ and we can again ask whether
1922
+
1923
+ z'.n - z'.o = x.n [8]
1924
+
1925
+ If so, we're done. If not, the tzinfo class is insane, according to the
1926
+ assumptions we've made. This also requires a bit of proof. As before, let's
1927
+ compute the difference between the LHS and RHS of [8] (and skipping some of
1928
+ the justifications for the kinds of substitutions we've done several times
1929
+ already):
1930
+
1931
+ diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
1932
+ x.n - (z.n + diff - z'.o) = replacing diff via [6]
1933
+ x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
1934
+ x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
1935
+ - z.n + z.n - z.o + z'.o = cancel z.n
1936
+ - z.o + z'.o = #1 twice
1937
+ -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
1938
+ z'.d - z.d
1939
+
1940
+ So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
1941
+ we've found the UTC-equivalent so are done. In fact, we stop with [7] and
1942
+ return z', not bothering to compute z'.d.
1943
+
1944
+ How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
1945
+ a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
1946
+ would have to change the result dst() returns: we start in DST, and moving
1947
+ a little further into it takes us out of DST.
1948
+
1949
+ There isn't a sane case where this can happen. The closest it gets is at
1950
+ the end of DST, where there's an hour in UTC with no spelling in a hybrid
1951
+ tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
1952
+ that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
1953
+ UTC) because the docs insist on that, but 0:MM is taken as being in daylight
1954
+ time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
1955
+ clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
1956
+ standard time. Since that's what the local clock *does*, we want to map both
1957
+ UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
1958
+ in local time, but so it goes -- it's the way the local clock works.
1959
+
1960
+ When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
1961
+ so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
1962
+ z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
1963
+ (correctly) concludes that z' is not UTC-equivalent to x.
1964
+
1965
+ Because we know z.d said z was in daylight time (else [5] would have held and
1966
+ we would have stopped then), and we know z.d != z'.d (else [8] would have held
1967
+ and we we have stopped then), and there are only 2 possible values dst() can
1968
+ return in Eastern, it follows that z'.d must be 0 (which it is in the example,
1969
+ but the reasoning doesn't depend on the example -- it depends on there being
1970
+ two possible dst() outcomes, one zero and the other non-zero). Therefore
1971
+ z' must be in standard time, and is the spelling we want in this case.
1972
+
1973
+ Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
1974
+ concerned (because it takes z' as being in standard time rather than the
1975
+ daylight time we intend here), but returning it gives the real-life "local
1976
+ clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
1977
+ tz.
1978
+
1979
+ When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
1980
+ the 1:MM standard time spelling we want.
1981
+
1982
+ So how can this break? One of the assumptions must be violated. Two
1983
+ possibilities:
1984
+
1985
+ 1) [2] effectively says that y.s is invariant across all y belong to a given
1986
+ time zone. This isn't true if, for political reasons or continental drift,
1987
+ a region decides to change its base offset from UTC.
1988
+
1989
+ 2) There may be versions of "double daylight" time where the tail end of
1990
+ the analysis gives up a step too early. I haven't thought about that
1991
+ enough to say.
1992
+
1993
+ In any case, it's clear that the default fromutc() is strong enough to handle
1994
+ "almost all" time zones: so long as the standard offset is invariant, it
1995
+ doesn't matter if daylight time transition points change from year to year, or
1996
+ if daylight time is skipped in some years; it doesn't matter how large or
1997
+ small dst() may get within its bounds; and it doesn't even matter if some
1998
+ perverse time zone returns a negative dst()). So a breaking case must be
1999
+ pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
2000
+ """
2001
+
2002
+ def _test():
2003
+ import test_datetime
2004
+ test_datetime.test_main()
2005
+
2006
+ if __name__ == "__main__":
2007
+ _test()