rubyfox-server 2.3.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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()