rubyfox-server 2.3.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (993) hide show
  1. data/.gitignore +17 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +23 -0
  6. data/Rakefile +1 -0
  7. data/bin/smartfox +7 -0
  8. data/lib/rubyfox/server/cli.rb +59 -0
  9. data/lib/rubyfox/server/data/config/.keep +0 -0
  10. data/lib/rubyfox/server/data/config/_backups/.keep +0 -0
  11. data/lib/rubyfox/server/data/config/ascii/boot.txt +5 -0
  12. data/lib/rubyfox/server/data/config/ascii/ready.txt +9 -0
  13. data/lib/rubyfox/server/data/config/core.xml +44 -0
  14. data/lib/rubyfox/server/data/config/crossdomain.xml +10 -0
  15. data/lib/rubyfox/server/data/config/descriptors/.keep +0 -0
  16. data/lib/rubyfox/server/data/config/descriptors/config_room.txt +323 -0
  17. data/lib/rubyfox/server/data/config/descriptors/config_server.txt +621 -0
  18. data/lib/rubyfox/server/data/config/descriptors/config_zone.txt +1021 -0
  19. data/lib/rubyfox/server/data/config/descriptors/runtime_game.txt +63 -0
  20. data/lib/rubyfox/server/data/config/descriptors/runtime_room.txt +377 -0
  21. data/lib/rubyfox/server/data/config/descriptors/runtime_user.txt +589 -0
  22. data/lib/rubyfox/server/data/config/descriptors/runtime_zone.txt +354 -0
  23. data/lib/rubyfox/server/data/config/jetty/.keep +0 -0
  24. data/lib/rubyfox/server/data/config/jetty/jetty.xml +214 -0
  25. data/lib/rubyfox/server/data/config/jetty/realm.properties +21 -0
  26. data/lib/rubyfox/server/data/config/jetty/webdefault.xml +410 -0
  27. data/lib/rubyfox/server/data/config/log4j.properties +75 -0
  28. data/lib/rubyfox/server/data/config/myprop.properties +5 -0
  29. data/lib/rubyfox/server/data/config/server.xml +65 -0
  30. data/lib/rubyfox/server/data/config/templates/sfs2x.unix.txt +12 -0
  31. data/lib/rubyfox/server/data/config/templates/sfs2x.windows.txt +1 -0
  32. data/lib/rubyfox/server/data/config/templates/vmoptions.txt +3 -0
  33. data/lib/rubyfox/server/data/config/wordsFile.txt +13 -0
  34. data/lib/rubyfox/server/data/data/bannedusers/.keep +0 -0
  35. data/lib/rubyfox/server/data/data/bannedusers/users.bin +0 -0
  36. data/lib/rubyfox/server/data/data/buddylists/.keep +0 -0
  37. data/lib/rubyfox/server/data/data/buddylists/BasicExamples/7364666773646667 +0 -0
  38. data/lib/rubyfox/server/data/extensions/.keep +0 -0
  39. data/lib/rubyfox/server/data/extensions/__lib__/.keep +0 -0
  40. data/lib/rubyfox/server/data/lib/Jetty/.keep +0 -0
  41. data/lib/rubyfox/server/data/lib/Jetty/ant-1.6.5.jar +0 -0
  42. data/lib/rubyfox/server/data/lib/Jetty/core-3.1.1.jar +0 -0
  43. data/lib/rubyfox/server/data/lib/Jetty/jetty-6.1.26.jar +0 -0
  44. data/lib/rubyfox/server/data/lib/Jetty/jetty-util-6.1.26.jar +0 -0
  45. data/lib/rubyfox/server/data/lib/Jetty/jsp-2.1-glassfish-2.1.v20091210.jar +0 -0
  46. data/lib/rubyfox/server/data/lib/Jetty/jsp-2.1-jetty-6.1.26.jar +0 -0
  47. data/lib/rubyfox/server/data/lib/Jetty/jsp-api-2.1-glassfish-2.1.v20091210.jar +0 -0
  48. data/lib/rubyfox/server/data/lib/Jetty/servlet-api-2.5-20081211.jar +0 -0
  49. data/lib/rubyfox/server/data/lib/Lib/BaseHTTPServer.py +484 -0
  50. data/lib/rubyfox/server/data/lib/Lib/CGIHTTPServer.py +325 -0
  51. data/lib/rubyfox/server/data/lib/Lib/ConfigParser.py +472 -0
  52. data/lib/rubyfox/server/data/lib/Lib/Cookie.py +742 -0
  53. data/lib/rubyfox/server/data/lib/Lib/HTMLParser.py +383 -0
  54. data/lib/rubyfox/server/data/lib/Lib/MimeWriter.py +181 -0
  55. data/lib/rubyfox/server/data/lib/Lib/Queue.py +151 -0
  56. data/lib/rubyfox/server/data/lib/Lib/SimpleHTTPServer.py +198 -0
  57. data/lib/rubyfox/server/data/lib/Lib/SimpleXMLRPCServer.py +274 -0
  58. data/lib/rubyfox/server/data/lib/Lib/SocketServer.py +576 -0
  59. data/lib/rubyfox/server/data/lib/Lib/StringIO.py +239 -0
  60. data/lib/rubyfox/server/data/lib/Lib/UserDict$py.class +0 -0
  61. data/lib/rubyfox/server/data/lib/Lib/UserDict.py +60 -0
  62. data/lib/rubyfox/server/data/lib/Lib/UserList.py +94 -0
  63. data/lib/rubyfox/server/data/lib/Lib/UserString.py +182 -0
  64. data/lib/rubyfox/server/data/lib/Lib/__future__$py.class +0 -0
  65. data/lib/rubyfox/server/data/lib/Lib/__future__.py +104 -0
  66. data/lib/rubyfox/server/data/lib/Lib/aifc.py +961 -0
  67. data/lib/rubyfox/server/data/lib/Lib/anydbm.py +86 -0
  68. data/lib/rubyfox/server/data/lib/Lib/atexit.py +50 -0
  69. data/lib/rubyfox/server/data/lib/Lib/base64.py +77 -0
  70. data/lib/rubyfox/server/data/lib/Lib/bdb.py +563 -0
  71. data/lib/rubyfox/server/data/lib/Lib/binhex.py +531 -0
  72. data/lib/rubyfox/server/data/lib/Lib/bisect.py +78 -0
  73. data/lib/rubyfox/server/data/lib/Lib/calendar.py +246 -0
  74. data/lib/rubyfox/server/data/lib/Lib/cgi.py +1040 -0
  75. data/lib/rubyfox/server/data/lib/Lib/chunk.py +167 -0
  76. data/lib/rubyfox/server/data/lib/Lib/cmd.py +336 -0
  77. data/lib/rubyfox/server/data/lib/Lib/code$py.class +0 -0
  78. data/lib/rubyfox/server/data/lib/Lib/code.py +311 -0
  79. data/lib/rubyfox/server/data/lib/Lib/codecs$py.class +0 -0
  80. data/lib/rubyfox/server/data/lib/Lib/codecs.py +636 -0
  81. data/lib/rubyfox/server/data/lib/Lib/codeop$py.class +0 -0
  82. data/lib/rubyfox/server/data/lib/Lib/codeop.py +131 -0
  83. data/lib/rubyfox/server/data/lib/Lib/colorsys.py +123 -0
  84. data/lib/rubyfox/server/data/lib/Lib/commands.py +84 -0
  85. data/lib/rubyfox/server/data/lib/Lib/compileall.py +148 -0
  86. data/lib/rubyfox/server/data/lib/Lib/copy.py +330 -0
  87. data/lib/rubyfox/server/data/lib/Lib/copy_reg$py.class +0 -0
  88. data/lib/rubyfox/server/data/lib/Lib/copy_reg.py +78 -0
  89. data/lib/rubyfox/server/data/lib/Lib/datetime$py.class +0 -0
  90. data/lib/rubyfox/server/data/lib/Lib/datetime.py +2007 -0
  91. data/lib/rubyfox/server/data/lib/Lib/dbexts.py +726 -0
  92. data/lib/rubyfox/server/data/lib/Lib/difflib.py +1088 -0
  93. data/lib/rubyfox/server/data/lib/Lib/dircache.py +44 -0
  94. data/lib/rubyfox/server/data/lib/Lib/doctest.py +1173 -0
  95. data/lib/rubyfox/server/data/lib/Lib/dospath.py +341 -0
  96. data/lib/rubyfox/server/data/lib/Lib/dumbdbm.py +170 -0
  97. data/lib/rubyfox/server/data/lib/Lib/email/Charset.py +393 -0
  98. data/lib/rubyfox/server/data/lib/Lib/email/Encoders.py +94 -0
  99. data/lib/rubyfox/server/data/lib/Lib/email/Errors.py +26 -0
  100. data/lib/rubyfox/server/data/lib/Lib/email/Generator.py +378 -0
  101. data/lib/rubyfox/server/data/lib/Lib/email/Header.py +515 -0
  102. data/lib/rubyfox/server/data/lib/Lib/email/Iterators.py +25 -0
  103. data/lib/rubyfox/server/data/lib/Lib/email/MIMEAudio.py +71 -0
  104. data/lib/rubyfox/server/data/lib/Lib/email/MIMEBase.py +24 -0
  105. data/lib/rubyfox/server/data/lib/Lib/email/MIMEImage.py +45 -0
  106. data/lib/rubyfox/server/data/lib/Lib/email/MIMEMessage.py +32 -0
  107. data/lib/rubyfox/server/data/lib/Lib/email/MIMEMultipart.py +37 -0
  108. data/lib/rubyfox/server/data/lib/Lib/email/MIMENonMultipart.py +24 -0
  109. data/lib/rubyfox/server/data/lib/Lib/email/MIMEText.py +45 -0
  110. data/lib/rubyfox/server/data/lib/Lib/email/Message.py +837 -0
  111. data/lib/rubyfox/server/data/lib/Lib/email/Parser.py +292 -0
  112. data/lib/rubyfox/server/data/lib/Lib/email/Utils.py +340 -0
  113. data/lib/rubyfox/server/data/lib/Lib/email/__init__.py +72 -0
  114. data/lib/rubyfox/server/data/lib/Lib/email/_compat21.py +69 -0
  115. data/lib/rubyfox/server/data/lib/Lib/email/_compat22.py +70 -0
  116. data/lib/rubyfox/server/data/lib/Lib/email/_parseaddr.py +480 -0
  117. data/lib/rubyfox/server/data/lib/Lib/email/base64MIME.py +184 -0
  118. data/lib/rubyfox/server/data/lib/Lib/email/quopriMIME.py +323 -0
  119. data/lib/rubyfox/server/data/lib/Lib/email/test/__init__.py +2 -0
  120. data/lib/rubyfox/server/data/lib/Lib/email/test/data/PyBanner048.gif +0 -0
  121. data/lib/rubyfox/server/data/lib/Lib/email/test/data/audiotest.au +0 -0
  122. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_01.txt +19 -0
  123. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_02.txt +135 -0
  124. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_03.txt +16 -0
  125. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_04.txt +37 -0
  126. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_05.txt +28 -0
  127. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_06.txt +33 -0
  128. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_07.txt +83 -0
  129. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_08.txt +24 -0
  130. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_09.txt +24 -0
  131. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_10.txt +32 -0
  132. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_11.txt +7 -0
  133. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_12.txt +36 -0
  134. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_13.txt +94 -0
  135. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_14.txt +23 -0
  136. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_15.txt +52 -0
  137. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_16.txt +123 -0
  138. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_17.txt +12 -0
  139. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_18.txt +6 -0
  140. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_19.txt +43 -0
  141. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_20.txt +22 -0
  142. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_21.txt +20 -0
  143. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_22.txt +46 -0
  144. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_23.txt +8 -0
  145. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_24.txt +10 -0
  146. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_25.txt +117 -0
  147. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_26.txt +45 -0
  148. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_27.txt +15 -0
  149. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_28.txt +25 -0
  150. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_29.txt +22 -0
  151. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_30.txt +23 -0
  152. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_31.txt +15 -0
  153. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_32.txt +14 -0
  154. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_33.txt +29 -0
  155. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_34.txt +19 -0
  156. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_35.txt +4 -0
  157. data/lib/rubyfox/server/data/lib/Lib/email/test/test_email.py +2718 -0
  158. data/lib/rubyfox/server/data/lib/Lib/email/test/test_email_codecs.py +68 -0
  159. data/lib/rubyfox/server/data/lib/Lib/email/test/test_email_torture.py +136 -0
  160. data/lib/rubyfox/server/data/lib/Lib/encodings/__init__$py.class +0 -0
  161. data/lib/rubyfox/server/data/lib/Lib/encodings/__init__.py +97 -0
  162. data/lib/rubyfox/server/data/lib/Lib/encodings/aliases$py.class +0 -0
  163. data/lib/rubyfox/server/data/lib/Lib/encodings/aliases.py +115 -0
  164. data/lib/rubyfox/server/data/lib/Lib/encodings/ascii.py +35 -0
  165. data/lib/rubyfox/server/data/lib/Lib/encodings/base64_codec.py +62 -0
  166. data/lib/rubyfox/server/data/lib/Lib/encodings/charmap.py +51 -0
  167. data/lib/rubyfox/server/data/lib/Lib/encodings/cp037.py +280 -0
  168. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1006.py +138 -0
  169. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1026.py +280 -0
  170. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1140.py +45 -0
  171. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1250.py +123 -0
  172. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1251.py +157 -0
  173. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1252.py +76 -0
  174. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1253.py +151 -0
  175. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1254.py +82 -0
  176. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1255.py +143 -0
  177. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1256.py +129 -0
  178. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1257.py +131 -0
  179. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1258.py +90 -0
  180. data/lib/rubyfox/server/data/lib/Lib/encodings/cp424.py +280 -0
  181. data/lib/rubyfox/server/data/lib/Lib/encodings/cp437.py +172 -0
  182. data/lib/rubyfox/server/data/lib/Lib/encodings/cp500.py +280 -0
  183. data/lib/rubyfox/server/data/lib/Lib/encodings/cp737.py +172 -0
  184. data/lib/rubyfox/server/data/lib/Lib/encodings/cp775.py +172 -0
  185. data/lib/rubyfox/server/data/lib/Lib/encodings/cp850.py +172 -0
  186. data/lib/rubyfox/server/data/lib/Lib/encodings/cp852.py +172 -0
  187. data/lib/rubyfox/server/data/lib/Lib/encodings/cp855.py +172 -0
  188. data/lib/rubyfox/server/data/lib/Lib/encodings/cp856.py +172 -0
  189. data/lib/rubyfox/server/data/lib/Lib/encodings/cp857.py +171 -0
  190. data/lib/rubyfox/server/data/lib/Lib/encodings/cp860.py +172 -0
  191. data/lib/rubyfox/server/data/lib/Lib/encodings/cp861.py +172 -0
  192. data/lib/rubyfox/server/data/lib/Lib/encodings/cp862.py +172 -0
  193. data/lib/rubyfox/server/data/lib/Lib/encodings/cp863.py +172 -0
  194. data/lib/rubyfox/server/data/lib/Lib/encodings/cp864.py +170 -0
  195. data/lib/rubyfox/server/data/lib/Lib/encodings/cp865.py +172 -0
  196. data/lib/rubyfox/server/data/lib/Lib/encodings/cp866.py +172 -0
  197. data/lib/rubyfox/server/data/lib/Lib/encodings/cp869.py +172 -0
  198. data/lib/rubyfox/server/data/lib/Lib/encodings/cp874.py +171 -0
  199. data/lib/rubyfox/server/data/lib/Lib/encodings/cp875.py +281 -0
  200. data/lib/rubyfox/server/data/lib/Lib/encodings/hex_codec.py +62 -0
  201. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_1.py +44 -0
  202. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_10.py +90 -0
  203. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_13.py +100 -0
  204. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_14.py +75 -0
  205. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_15.py +52 -0
  206. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_2.py +101 -0
  207. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_3.py +79 -0
  208. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_4.py +94 -0
  209. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_5.py +138 -0
  210. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_6.py +137 -0
  211. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_7.py +124 -0
  212. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_8.py +112 -0
  213. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_9.py +50 -0
  214. data/lib/rubyfox/server/data/lib/Lib/encodings/koi8_r.py +172 -0
  215. data/lib/rubyfox/server/data/lib/Lib/encodings/koi8_u.py +54 -0
  216. data/lib/rubyfox/server/data/lib/Lib/encodings/latin_1.py +35 -0
  217. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_cyrillic.py +167 -0
  218. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_greek.py +170 -0
  219. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_iceland.py +166 -0
  220. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_latin2.py +170 -0
  221. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_roman.py +167 -0
  222. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_turkish.py +167 -0
  223. data/lib/rubyfox/server/data/lib/Lib/encodings/mbcs.py +36 -0
  224. data/lib/rubyfox/server/data/lib/Lib/encodings/quopri_codec.py +58 -0
  225. data/lib/rubyfox/server/data/lib/Lib/encodings/raw_unicode_escape.py +30 -0
  226. data/lib/rubyfox/server/data/lib/Lib/encodings/rot_13.py +105 -0
  227. data/lib/rubyfox/server/data/lib/Lib/encodings/undefined.py +34 -0
  228. data/lib/rubyfox/server/data/lib/Lib/encodings/unicode_escape.py +30 -0
  229. data/lib/rubyfox/server/data/lib/Lib/encodings/unicode_internal.py +30 -0
  230. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_16.py +61 -0
  231. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_16_be.py +31 -0
  232. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_16_le.py +31 -0
  233. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_7.py +27 -0
  234. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_8$py.class +0 -0
  235. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_8.py +31 -0
  236. data/lib/rubyfox/server/data/lib/Lib/encodings/uu_codec.py +112 -0
  237. data/lib/rubyfox/server/data/lib/Lib/encodings/zlib_codec.py +63 -0
  238. data/lib/rubyfox/server/data/lib/Lib/fileinput.py +349 -0
  239. data/lib/rubyfox/server/data/lib/Lib/fnmatch.py +107 -0
  240. data/lib/rubyfox/server/data/lib/Lib/formatter.py +454 -0
  241. data/lib/rubyfox/server/data/lib/Lib/fpformat.py +142 -0
  242. data/lib/rubyfox/server/data/lib/Lib/ftplib.py +804 -0
  243. data/lib/rubyfox/server/data/lib/Lib/getopt.py +143 -0
  244. data/lib/rubyfox/server/data/lib/Lib/glob.py +56 -0
  245. data/lib/rubyfox/server/data/lib/Lib/gopherlib.py +205 -0
  246. data/lib/rubyfox/server/data/lib/Lib/gzip.py +390 -0
  247. data/lib/rubyfox/server/data/lib/Lib/hmac.py +99 -0
  248. data/lib/rubyfox/server/data/lib/Lib/htmlentitydefs.py +257 -0
  249. data/lib/rubyfox/server/data/lib/Lib/htmllib.py +475 -0
  250. data/lib/rubyfox/server/data/lib/Lib/httplib.py +1238 -0
  251. data/lib/rubyfox/server/data/lib/Lib/imaplib.py +1208 -0
  252. data/lib/rubyfox/server/data/lib/Lib/imghdr.py +154 -0
  253. data/lib/rubyfox/server/data/lib/Lib/inspect$py.class +0 -0
  254. data/lib/rubyfox/server/data/lib/Lib/inspect.py +787 -0
  255. data/lib/rubyfox/server/data/lib/Lib/isql.py +238 -0
  256. data/lib/rubyfox/server/data/lib/Lib/javaos$py.class +0 -0
  257. data/lib/rubyfox/server/data/lib/Lib/javaos.py +395 -0
  258. data/lib/rubyfox/server/data/lib/Lib/javapath$py.class +0 -0
  259. data/lib/rubyfox/server/data/lib/Lib/javapath.py +349 -0
  260. data/lib/rubyfox/server/data/lib/Lib/javashell.py +194 -0
  261. data/lib/rubyfox/server/data/lib/Lib/jreload.py +119 -0
  262. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/DiscardHelp.java +59 -0
  263. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/JavaLoaderFactory.java +9 -0
  264. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/PackageManager.java +58 -0
  265. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/PathVFS.java +98 -0
  266. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/PathVFSJavaLoader.java +49 -0
  267. data/lib/rubyfox/server/data/lib/Lib/keyword.py +97 -0
  268. data/lib/rubyfox/server/data/lib/Lib/linecache$py.class +0 -0
  269. data/lib/rubyfox/server/data/lib/Lib/linecache.py +101 -0
  270. data/lib/rubyfox/server/data/lib/Lib/macpath.py +242 -0
  271. data/lib/rubyfox/server/data/lib/Lib/macurl2path.py +95 -0
  272. data/lib/rubyfox/server/data/lib/Lib/mailbox.py +313 -0
  273. data/lib/rubyfox/server/data/lib/Lib/mailcap.py +255 -0
  274. data/lib/rubyfox/server/data/lib/Lib/markupbase.py +317 -0
  275. data/lib/rubyfox/server/data/lib/Lib/marshal.py +315 -0
  276. data/lib/rubyfox/server/data/lib/Lib/mhlib.py +1003 -0
  277. data/lib/rubyfox/server/data/lib/Lib/mimetools.py +226 -0
  278. data/lib/rubyfox/server/data/lib/Lib/mimetypes.py +435 -0
  279. data/lib/rubyfox/server/data/lib/Lib/mimify.py +464 -0
  280. data/lib/rubyfox/server/data/lib/Lib/multifile.py +160 -0
  281. data/lib/rubyfox/server/data/lib/Lib/mutex.py +51 -0
  282. data/lib/rubyfox/server/data/lib/Lib/netrc.py +108 -0
  283. data/lib/rubyfox/server/data/lib/Lib/nntplib.py +575 -0
  284. data/lib/rubyfox/server/data/lib/Lib/ntpath.py +482 -0
  285. data/lib/rubyfox/server/data/lib/Lib/nturl2path.py +66 -0
  286. data/lib/rubyfox/server/data/lib/Lib/pawt/__init__.py +35 -0
  287. data/lib/rubyfox/server/data/lib/Lib/pawt/colors.py +144 -0
  288. data/lib/rubyfox/server/data/lib/Lib/pawt/swing.py +42 -0
  289. data/lib/rubyfox/server/data/lib/Lib/pdb.py +979 -0
  290. data/lib/rubyfox/server/data/lib/Lib/pickle.py +990 -0
  291. data/lib/rubyfox/server/data/lib/Lib/pipes.py +297 -0
  292. data/lib/rubyfox/server/data/lib/Lib/popen2.py +304 -0
  293. data/lib/rubyfox/server/data/lib/Lib/poplib.py +335 -0
  294. data/lib/rubyfox/server/data/lib/Lib/posixfile.py +240 -0
  295. data/lib/rubyfox/server/data/lib/Lib/posixpath.py +414 -0
  296. data/lib/rubyfox/server/data/lib/Lib/pprint.py +310 -0
  297. data/lib/rubyfox/server/data/lib/Lib/profile.py +556 -0
  298. data/lib/rubyfox/server/data/lib/Lib/pstats.py +641 -0
  299. data/lib/rubyfox/server/data/lib/Lib/pyclbr.py +337 -0
  300. data/lib/rubyfox/server/data/lib/Lib/quopri.py +237 -0
  301. data/lib/rubyfox/server/data/lib/Lib/random$py.class +0 -0
  302. data/lib/rubyfox/server/data/lib/Lib/random.py +779 -0
  303. data/lib/rubyfox/server/data/lib/Lib/re$py.class +0 -0
  304. data/lib/rubyfox/server/data/lib/Lib/re.py +11 -0
  305. data/lib/rubyfox/server/data/lib/Lib/reconvert.py +192 -0
  306. data/lib/rubyfox/server/data/lib/Lib/reindex$py.class +0 -0
  307. data/lib/rubyfox/server/data/lib/Lib/repr.py +95 -0
  308. data/lib/rubyfox/server/data/lib/Lib/rfc822.py +1010 -0
  309. data/lib/rubyfox/server/data/lib/Lib/sched.py +106 -0
  310. data/lib/rubyfox/server/data/lib/Lib/select.py +211 -0
  311. data/lib/rubyfox/server/data/lib/Lib/servlet-api-2.5-20081211.jar +0 -0
  312. data/lib/rubyfox/server/data/lib/Lib/setsfactory.py +10 -0
  313. data/lib/rubyfox/server/data/lib/Lib/sfs2x-lms.jar +0 -0
  314. data/lib/rubyfox/server/data/lib/Lib/sgmllib.py +516 -0
  315. data/lib/rubyfox/server/data/lib/Lib/shelve.py +158 -0
  316. data/lib/rubyfox/server/data/lib/Lib/shlex.py +209 -0
  317. data/lib/rubyfox/server/data/lib/Lib/shutil$py.class +0 -0
  318. data/lib/rubyfox/server/data/lib/Lib/shutil.py +138 -0
  319. data/lib/rubyfox/server/data/lib/Lib/site.py +263 -0
  320. data/lib/rubyfox/server/data/lib/Lib/smtplib.py +729 -0
  321. data/lib/rubyfox/server/data/lib/Lib/sndhdr.py +228 -0
  322. data/lib/rubyfox/server/data/lib/Lib/socket.py +902 -0
  323. data/lib/rubyfox/server/data/lib/Lib/sre$py.class +0 -0
  324. data/lib/rubyfox/server/data/lib/Lib/sre.py +311 -0
  325. data/lib/rubyfox/server/data/lib/Lib/sre_compile$py.class +0 -0
  326. data/lib/rubyfox/server/data/lib/Lib/sre_compile.py +455 -0
  327. data/lib/rubyfox/server/data/lib/Lib/sre_constants$py.class +0 -0
  328. data/lib/rubyfox/server/data/lib/Lib/sre_constants.py +259 -0
  329. data/lib/rubyfox/server/data/lib/Lib/sre_parse$py.class +0 -0
  330. data/lib/rubyfox/server/data/lib/Lib/sre_parse.py +738 -0
  331. data/lib/rubyfox/server/data/lib/Lib/stat$py.class +0 -0
  332. data/lib/rubyfox/server/data/lib/Lib/stat.py +86 -0
  333. data/lib/rubyfox/server/data/lib/Lib/string$py.class +0 -0
  334. data/lib/rubyfox/server/data/lib/Lib/string.py +437 -0
  335. data/lib/rubyfox/server/data/lib/Lib/symbol.py +95 -0
  336. data/lib/rubyfox/server/data/lib/Lib/telnetlib.py +662 -0
  337. data/lib/rubyfox/server/data/lib/Lib/tempfile.py +255 -0
  338. data/lib/rubyfox/server/data/lib/Lib/test/Graph.py +62 -0
  339. data/lib/rubyfox/server/data/lib/Lib/test/README +372 -0
  340. data/lib/rubyfox/server/data/lib/Lib/test/__init__.py +1 -0
  341. data/lib/rubyfox/server/data/lib/Lib/test/audiotest.au +0 -0
  342. data/lib/rubyfox/server/data/lib/Lib/test/autotest.py +6 -0
  343. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future3.py +10 -0
  344. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future4.py +10 -0
  345. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future5.py +12 -0
  346. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future6.py +10 -0
  347. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future7.py +11 -0
  348. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_nocaret.py +2 -0
  349. data/lib/rubyfox/server/data/lib/Lib/test/blob.jar +0 -0
  350. data/lib/rubyfox/server/data/lib/Lib/test/bugs/bugs100.py +139 -0
  351. data/lib/rubyfox/server/data/lib/Lib/test/bugs/bugs101.py +57 -0
  352. data/lib/rubyfox/server/data/lib/Lib/test/bugs/jdkbugs.py +10 -0
  353. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr101.py +59 -0
  354. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr104.py +9 -0
  355. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr112.py +14 -0
  356. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr119.py +16 -0
  357. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr127.py +10 -0
  358. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr133/__init__.py +1 -0
  359. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr133/test.py +2 -0
  360. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr133.py +12 -0
  361. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr134.py +9 -0
  362. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr139.py +7 -0
  363. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr142.py +1 -0
  364. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr144.py +2 -0
  365. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr148.py +2 -0
  366. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr149.py +7 -0
  367. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr155.py +13 -0
  368. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr170.py +7 -0
  369. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr171.py +9 -0
  370. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr174.py +9 -0
  371. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr178.py +10 -0
  372. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr183.py +5 -0
  373. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr186.py +10 -0
  374. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr191.py +5 -0
  375. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr192.py +81 -0
  376. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr195.py +11 -0
  377. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr208.py +26 -0
  378. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr233.py +8 -0
  379. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr234.py +16 -0
  380. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr235.py +14 -0
  381. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr239.py +6 -0
  382. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr241.py +16 -0
  383. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr242.py +12 -0
  384. data/lib/rubyfox/server/data/lib/Lib/test/data/PyBanner048.gif +0 -0
  385. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_01.txt +19 -0
  386. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_02.txt +135 -0
  387. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_03.txt +16 -0
  388. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_04.txt +37 -0
  389. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_05.txt +28 -0
  390. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_06.txt +33 -0
  391. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_07.txt +83 -0
  392. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_08.txt +24 -0
  393. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_09.txt +24 -0
  394. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_10.txt +32 -0
  395. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_11.txt +7 -0
  396. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_12.txt +36 -0
  397. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_13.txt +94 -0
  398. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_14.txt +23 -0
  399. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_15.txt +52 -0
  400. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_16.txt +123 -0
  401. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_17.txt +12 -0
  402. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_18.txt +6 -0
  403. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_19.txt +43 -0
  404. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_20.txt +22 -0
  405. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_21.txt +22 -0
  406. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_22.txt +46 -0
  407. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_23.txt +8 -0
  408. data/lib/rubyfox/server/data/lib/Lib/test/double_const.py +30 -0
  409. data/lib/rubyfox/server/data/lib/Lib/test/greyrgb.uue +1547 -0
  410. data/lib/rubyfox/server/data/lib/Lib/test/javatests/AnonInner.java +20 -0
  411. data/lib/rubyfox/server/data/lib/Lib/test/javatests/Foo.java +3 -0
  412. data/lib/rubyfox/server/data/lib/Lib/test/javatests/JOverload.java +132 -0
  413. data/lib/rubyfox/server/data/lib/Lib/test/javatests/ListTest.java +638 -0
  414. data/lib/rubyfox/server/data/lib/Lib/test/javatests/SubFoo.java +3 -0
  415. data/lib/rubyfox/server/data/lib/Lib/test/javatests/TestSupport.java +49 -0
  416. data/lib/rubyfox/server/data/lib/Lib/test/javatests/__init__.py +0 -0
  417. data/lib/rubyfox/server/data/lib/Lib/test/jser2_classes.py +47 -0
  418. data/lib/rubyfox/server/data/lib/Lib/test/output/test_MimeWriter +110 -0
  419. data/lib/rubyfox/server/data/lib/Lib/test/output/test_array +4 -0
  420. data/lib/rubyfox/server/data/lib/Lib/test/output/test_asynchat +3 -0
  421. data/lib/rubyfox/server/data/lib/Lib/test/output/test_augassign +51 -0
  422. data/lib/rubyfox/server/data/lib/Lib/test/output/test_binascii +29 -0
  423. data/lib/rubyfox/server/data/lib/Lib/test/output/test_builtin +53 -0
  424. data/lib/rubyfox/server/data/lib/Lib/test/output/test_cfgparser +9 -0
  425. data/lib/rubyfox/server/data/lib/Lib/test/output/test_cgi +29 -0
  426. data/lib/rubyfox/server/data/lib/Lib/test/output/test_charmapcodec +16 -0
  427. data/lib/rubyfox/server/data/lib/Lib/test/output/test_class +101 -0
  428. data/lib/rubyfox/server/data/lib/Lib/test/output/test_coercion +1054 -0
  429. data/lib/rubyfox/server/data/lib/Lib/test/output/test_compare +101 -0
  430. data/lib/rubyfox/server/data/lib/Lib/test/output/test_compile +7 -0
  431. data/lib/rubyfox/server/data/lib/Lib/test/output/test_cookie +32 -0
  432. data/lib/rubyfox/server/data/lib/Lib/test/output/test_exceptions +52 -0
  433. data/lib/rubyfox/server/data/lib/Lib/test/output/test_extcall +112 -0
  434. data/lib/rubyfox/server/data/lib/Lib/test/output/test_frozen +4 -0
  435. data/lib/rubyfox/server/data/lib/Lib/test/output/test_future +9 -0
  436. data/lib/rubyfox/server/data/lib/Lib/test/output/test_gettext +46 -0
  437. data/lib/rubyfox/server/data/lib/Lib/test/output/test_global +5 -0
  438. data/lib/rubyfox/server/data/lib/Lib/test/output/test_grammar +66 -0
  439. data/lib/rubyfox/server/data/lib/Lib/test/output/test_httplib +10 -0
  440. data/lib/rubyfox/server/data/lib/Lib/test/output/test_janoninner +5 -0
  441. data/lib/rubyfox/server/data/lib/Lib/test/output/test_javalist +6 -0
  442. data/lib/rubyfox/server/data/lib/Lib/test/output/test_jbasic +13 -0
  443. data/lib/rubyfox/server/data/lib/Lib/test/output/test_jser +12 -0
  444. data/lib/rubyfox/server/data/lib/Lib/test/output/test_jsubclass +5 -0
  445. data/lib/rubyfox/server/data/lib/Lib/test/output/test_linuxaudiodev +7 -0
  446. data/lib/rubyfox/server/data/lib/Lib/test/output/test_longexp +2 -0
  447. data/lib/rubyfox/server/data/lib/Lib/test/output/test_math +26 -0
  448. data/lib/rubyfox/server/data/lib/Lib/test/output/test_md5 +9 -0
  449. data/lib/rubyfox/server/data/lib/Lib/test/output/test_methods +6 -0
  450. data/lib/rubyfox/server/data/lib/Lib/test/output/test_mimetools +5 -0
  451. data/lib/rubyfox/server/data/lib/Lib/test/output/test_mmap +34 -0
  452. data/lib/rubyfox/server/data/lib/Lib/test/output/test_new +7 -0
  453. data/lib/rubyfox/server/data/lib/Lib/test/output/test_nis +2 -0
  454. data/lib/rubyfox/server/data/lib/Lib/test/output/test_opcodes +4 -0
  455. data/lib/rubyfox/server/data/lib/Lib/test/output/test_openpty +2 -0
  456. data/lib/rubyfox/server/data/lib/Lib/test/output/test_operations +28 -0
  457. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pkg +45 -0
  458. data/lib/rubyfox/server/data/lib/Lib/test/output/test_poll +17 -0
  459. data/lib/rubyfox/server/data/lib/Lib/test/output/test_popen2 +9 -0
  460. data/lib/rubyfox/server/data/lib/Lib/test/output/test_posixpath +2 -0
  461. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pow +17 -0
  462. data/lib/rubyfox/server/data/lib/Lib/test/output/test_profile +17 -0
  463. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pty +3 -0
  464. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pwd +7 -0
  465. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pyexpat +110 -0
  466. data/lib/rubyfox/server/data/lib/Lib/test/output/test_re +15 -0
  467. data/lib/rubyfox/server/data/lib/Lib/test/output/test_regex +29 -0
  468. data/lib/rubyfox/server/data/lib/Lib/test/output/test_rgbimg +2 -0
  469. data/lib/rubyfox/server/data/lib/Lib/test/output/test_richcmp +187 -0
  470. data/lib/rubyfox/server/data/lib/Lib/test/output/test_rotor +5 -0
  471. data/lib/rubyfox/server/data/lib/Lib/test/output/test_scope +24 -0
  472. data/lib/rubyfox/server/data/lib/Lib/test/output/test_signal +2 -0
  473. data/lib/rubyfox/server/data/lib/Lib/test/output/test_string +18 -0
  474. data/lib/rubyfox/server/data/lib/Lib/test/output/test_thread +4 -0
  475. data/lib/rubyfox/server/data/lib/Lib/test/output/test_threadedtempfile +5 -0
  476. data/lib/rubyfox/server/data/lib/Lib/test/output/test_time +9 -0
  477. data/lib/rubyfox/server/data/lib/Lib/test/output/test_tokenize +648 -0
  478. data/lib/rubyfox/server/data/lib/Lib/test/output/test_types +15 -0
  479. data/lib/rubyfox/server/data/lib/Lib/test/output/test_ucn +7 -0
  480. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unicode +21 -0
  481. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unicode_file +2 -0
  482. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unicodedata +5 -0
  483. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unpack +15 -0
  484. data/lib/rubyfox/server/data/lib/Lib/test/output/test_urlparse +47 -0
  485. data/lib/rubyfox/server/data/lib/Lib/test/output/test_winreg +3 -0
  486. data/lib/rubyfox/server/data/lib/Lib/test/output/test_winsound +2 -0
  487. data/lib/rubyfox/server/data/lib/Lib/test/output/test_xreadline +4 -0
  488. data/lib/rubyfox/server/data/lib/Lib/test/pickletester.py +285 -0
  489. data/lib/rubyfox/server/data/lib/Lib/test/pydocfodder.py +210 -0
  490. data/lib/rubyfox/server/data/lib/Lib/test/pystone.py +252 -0
  491. data/lib/rubyfox/server/data/lib/Lib/test/re_tests.py +590 -0
  492. data/lib/rubyfox/server/data/lib/Lib/test/regex_tests.py +287 -0
  493. data/lib/rubyfox/server/data/lib/Lib/test/regrtest.py +1096 -0
  494. data/lib/rubyfox/server/data/lib/Lib/test/reperf.py +23 -0
  495. data/lib/rubyfox/server/data/lib/Lib/test/sortperf.py +141 -0
  496. data/lib/rubyfox/server/data/lib/Lib/test/string_tests.py +265 -0
  497. data/lib/rubyfox/server/data/lib/Lib/test/test.xml +115 -0
  498. data/lib/rubyfox/server/data/lib/Lib/test/test.xml.out +115 -0
  499. data/lib/rubyfox/server/data/lib/Lib/test/test_MimeWriter.py +170 -0
  500. data/lib/rubyfox/server/data/lib/Lib/test/test_SimpleXMLRPCServer.py +88 -0
  501. data/lib/rubyfox/server/data/lib/Lib/test/test_StringIO.py +113 -0
  502. data/lib/rubyfox/server/data/lib/Lib/test/test___all__.py +158 -0
  503. data/lib/rubyfox/server/data/lib/Lib/test/test___future__.py +59 -0
  504. data/lib/rubyfox/server/data/lib/Lib/test/test_al.py +23 -0
  505. data/lib/rubyfox/server/data/lib/Lib/test/test_array.py +438 -0
  506. data/lib/rubyfox/server/data/lib/Lib/test/test_asynchat.py +58 -0
  507. data/lib/rubyfox/server/data/lib/Lib/test/test_atexit.py +66 -0
  508. data/lib/rubyfox/server/data/lib/Lib/test/test_audioop.py +264 -0
  509. data/lib/rubyfox/server/data/lib/Lib/test/test_augassign.py +261 -0
  510. data/lib/rubyfox/server/data/lib/Lib/test/test_b1.py +632 -0
  511. data/lib/rubyfox/server/data/lib/Lib/test/test_b2.py +365 -0
  512. data/lib/rubyfox/server/data/lib/Lib/test/test_base64.py +53 -0
  513. data/lib/rubyfox/server/data/lib/Lib/test/test_bastion.py +3 -0
  514. data/lib/rubyfox/server/data/lib/Lib/test/test_binascii.py +119 -0
  515. data/lib/rubyfox/server/data/lib/Lib/test/test_binhex.py +50 -0
  516. data/lib/rubyfox/server/data/lib/Lib/test/test_binop.py +328 -0
  517. data/lib/rubyfox/server/data/lib/Lib/test/test_bisect.py +127 -0
  518. data/lib/rubyfox/server/data/lib/Lib/test/test_bsddb.py +76 -0
  519. data/lib/rubyfox/server/data/lib/Lib/test/test_bufio.py +60 -0
  520. data/lib/rubyfox/server/data/lib/Lib/test/test_bugfixes.py +31 -0
  521. data/lib/rubyfox/server/data/lib/Lib/test/test_builtin.py +13 -0
  522. data/lib/rubyfox/server/data/lib/Lib/test/test_calendar.py +61 -0
  523. data/lib/rubyfox/server/data/lib/Lib/test/test_call.py +131 -0
  524. data/lib/rubyfox/server/data/lib/Lib/test/test_capi.py +16 -0
  525. data/lib/rubyfox/server/data/lib/Lib/test/test_cd.py +26 -0
  526. data/lib/rubyfox/server/data/lib/Lib/test/test_cfgparser.py +284 -0
  527. data/lib/rubyfox/server/data/lib/Lib/test/test_cgi.py +188 -0
  528. data/lib/rubyfox/server/data/lib/Lib/test/test_charmapcodec.py +43 -0
  529. data/lib/rubyfox/server/data/lib/Lib/test/test_cl.py +78 -0
  530. data/lib/rubyfox/server/data/lib/Lib/test/test_class.py +317 -0
  531. data/lib/rubyfox/server/data/lib/Lib/test/test_cmath.py +35 -0
  532. data/lib/rubyfox/server/data/lib/Lib/test/test_codecs.py +31 -0
  533. data/lib/rubyfox/server/data/lib/Lib/test/test_codeop.py +190 -0
  534. data/lib/rubyfox/server/data/lib/Lib/test/test_coercion.py +118 -0
  535. data/lib/rubyfox/server/data/lib/Lib/test/test_commands.py +52 -0
  536. data/lib/rubyfox/server/data/lib/Lib/test/test_compare.py +56 -0
  537. data/lib/rubyfox/server/data/lib/Lib/test/test_compile.py +129 -0
  538. data/lib/rubyfox/server/data/lib/Lib/test/test_complex.py +68 -0
  539. data/lib/rubyfox/server/data/lib/Lib/test/test_contains.py +133 -0
  540. data/lib/rubyfox/server/data/lib/Lib/test/test_cookie.py +47 -0
  541. data/lib/rubyfox/server/data/lib/Lib/test/test_copy_reg.py +30 -0
  542. data/lib/rubyfox/server/data/lib/Lib/test/test_cpickle.py +81 -0
  543. data/lib/rubyfox/server/data/lib/Lib/test/test_crypt.py +11 -0
  544. data/lib/rubyfox/server/data/lib/Lib/test/test_curses.py +210 -0
  545. data/lib/rubyfox/server/data/lib/Lib/test/test_datetime.py +2958 -0
  546. data/lib/rubyfox/server/data/lib/Lib/test/test_dbm.py +43 -0
  547. data/lib/rubyfox/server/data/lib/Lib/test/test_descr.py +4094 -0
  548. data/lib/rubyfox/server/data/lib/Lib/test/test_descrtut.py +501 -0
  549. data/lib/rubyfox/server/data/lib/Lib/test/test_difflib.py +2 -0
  550. data/lib/rubyfox/server/data/lib/Lib/test/test_dircache.py +74 -0
  551. data/lib/rubyfox/server/data/lib/Lib/test/test_dl.py +33 -0
  552. data/lib/rubyfox/server/data/lib/Lib/test/test_doctest.py +2 -0
  553. data/lib/rubyfox/server/data/lib/Lib/test/test_doctest2.py +108 -0
  554. data/lib/rubyfox/server/data/lib/Lib/test/test_dospath.py +61 -0
  555. data/lib/rubyfox/server/data/lib/Lib/test/test_dumbdbm.py +79 -0
  556. data/lib/rubyfox/server/data/lib/Lib/test/test_email.py +13 -0
  557. data/lib/rubyfox/server/data/lib/Lib/test/test_email_codecs.py +11 -0
  558. data/lib/rubyfox/server/data/lib/Lib/test/test_enumerate.py +150 -0
  559. data/lib/rubyfox/server/data/lib/Lib/test/test_errno.py +49 -0
  560. data/lib/rubyfox/server/data/lib/Lib/test/test_exceptions.py +206 -0
  561. data/lib/rubyfox/server/data/lib/Lib/test/test_extcall.py +268 -0
  562. data/lib/rubyfox/server/data/lib/Lib/test/test_fcntl.py +53 -0
  563. data/lib/rubyfox/server/data/lib/Lib/test/test_file.py +63 -0
  564. data/lib/rubyfox/server/data/lib/Lib/test/test_fileinput.py +159 -0
  565. data/lib/rubyfox/server/data/lib/Lib/test/test_fnmatch.py +46 -0
  566. data/lib/rubyfox/server/data/lib/Lib/test/test_fork1.py +75 -0
  567. data/lib/rubyfox/server/data/lib/Lib/test/test_format.py +218 -0
  568. data/lib/rubyfox/server/data/lib/Lib/test/test_fpformat.py +75 -0
  569. data/lib/rubyfox/server/data/lib/Lib/test/test_frozen.py +26 -0
  570. data/lib/rubyfox/server/data/lib/Lib/test/test_funcattrs.py +384 -0
  571. data/lib/rubyfox/server/data/lib/Lib/test/test_future.py +47 -0
  572. data/lib/rubyfox/server/data/lib/Lib/test/test_future1.py +11 -0
  573. data/lib/rubyfox/server/data/lib/Lib/test/test_future2.py +10 -0
  574. data/lib/rubyfox/server/data/lib/Lib/test/test_future3.py +11 -0
  575. data/lib/rubyfox/server/data/lib/Lib/test/test_gc.py +346 -0
  576. data/lib/rubyfox/server/data/lib/Lib/test/test_gdbm.py +46 -0
  577. data/lib/rubyfox/server/data/lib/Lib/test/test_generators.py +1385 -0
  578. data/lib/rubyfox/server/data/lib/Lib/test/test_getargs.py +26 -0
  579. data/lib/rubyfox/server/data/lib/Lib/test/test_getopt.py +110 -0
  580. data/lib/rubyfox/server/data/lib/Lib/test/test_gettext.py +200 -0
  581. data/lib/rubyfox/server/data/lib/Lib/test/test_gl.py +150 -0
  582. data/lib/rubyfox/server/data/lib/Lib/test/test_glob.py +115 -0
  583. data/lib/rubyfox/server/data/lib/Lib/test/test_global.py +51 -0
  584. data/lib/rubyfox/server/data/lib/Lib/test/test_grammar.py +732 -0
  585. data/lib/rubyfox/server/data/lib/Lib/test/test_grp.py +27 -0
  586. data/lib/rubyfox/server/data/lib/Lib/test/test_gzip.py +82 -0
  587. data/lib/rubyfox/server/data/lib/Lib/test/test_hash.py +36 -0
  588. data/lib/rubyfox/server/data/lib/Lib/test/test_hmac.py +108 -0
  589. data/lib/rubyfox/server/data/lib/Lib/test/test_hotshot.py +117 -0
  590. data/lib/rubyfox/server/data/lib/Lib/test/test_htmllib.py +42 -0
  591. data/lib/rubyfox/server/data/lib/Lib/test/test_htmlparser.py +294 -0
  592. data/lib/rubyfox/server/data/lib/Lib/test/test_httplib.py +58 -0
  593. data/lib/rubyfox/server/data/lib/Lib/test/test_imageop.py +171 -0
  594. data/lib/rubyfox/server/data/lib/Lib/test/test_imgfile.py +116 -0
  595. data/lib/rubyfox/server/data/lib/Lib/test/test_import.py +71 -0
  596. data/lib/rubyfox/server/data/lib/Lib/test/test_importhooks.py +215 -0
  597. data/lib/rubyfox/server/data/lib/Lib/test/test_inspect.py +365 -0
  598. data/lib/rubyfox/server/data/lib/Lib/test/test_iter.py +784 -0
  599. data/lib/rubyfox/server/data/lib/Lib/test/test_janoninner.py +15 -0
  600. data/lib/rubyfox/server/data/lib/Lib/test/test_javalist.py +53 -0
  601. data/lib/rubyfox/server/data/lib/Lib/test/test_javashell.py +182 -0
  602. data/lib/rubyfox/server/data/lib/Lib/test/test_jbasic.py +119 -0
  603. data/lib/rubyfox/server/data/lib/Lib/test/test_joverload.py +138 -0
  604. data/lib/rubyfox/server/data/lib/Lib/test/test_jreload.py +33 -0
  605. data/lib/rubyfox/server/data/lib/Lib/test/test_jser.py +57 -0
  606. data/lib/rubyfox/server/data/lib/Lib/test/test_jser2.py +93 -0
  607. data/lib/rubyfox/server/data/lib/Lib/test/test_jsubclass.py +49 -0
  608. data/lib/rubyfox/server/data/lib/Lib/test/test_jy_compile.py +168 -0
  609. data/lib/rubyfox/server/data/lib/Lib/test/test_jy_generators.py +165 -0
  610. data/lib/rubyfox/server/data/lib/Lib/test/test_jy_internals.py +130 -0
  611. data/lib/rubyfox/server/data/lib/Lib/test/test_largefile.py +169 -0
  612. data/lib/rubyfox/server/data/lib/Lib/test/test_linuxaudiodev.py +89 -0
  613. data/lib/rubyfox/server/data/lib/Lib/test/test_locale.py +44 -0
  614. data/lib/rubyfox/server/data/lib/Lib/test/test_long.py +445 -0
  615. data/lib/rubyfox/server/data/lib/Lib/test/test_long_future.py +55 -0
  616. data/lib/rubyfox/server/data/lib/Lib/test/test_long_int_args.py +61 -0
  617. data/lib/rubyfox/server/data/lib/Lib/test/test_longexp.py +16 -0
  618. data/lib/rubyfox/server/data/lib/Lib/test/test_mailbox.py +113 -0
  619. data/lib/rubyfox/server/data/lib/Lib/test/test_marshal.py +44 -0
  620. data/lib/rubyfox/server/data/lib/Lib/test/test_math.py +153 -0
  621. data/lib/rubyfox/server/data/lib/Lib/test/test_md5.py +30 -0
  622. data/lib/rubyfox/server/data/lib/Lib/test/test_methods.py +62 -0
  623. data/lib/rubyfox/server/data/lib/Lib/test/test_mhlib.py +353 -0
  624. data/lib/rubyfox/server/data/lib/Lib/test/test_mimetools.py +18 -0
  625. data/lib/rubyfox/server/data/lib/Lib/test/test_mimetypes.py +59 -0
  626. data/lib/rubyfox/server/data/lib/Lib/test/test_minidom.py +648 -0
  627. data/lib/rubyfox/server/data/lib/Lib/test/test_mmap.py +317 -0
  628. data/lib/rubyfox/server/data/lib/Lib/test/test_module.py +77 -0
  629. data/lib/rubyfox/server/data/lib/Lib/test/test_multifile.py +66 -0
  630. data/lib/rubyfox/server/data/lib/Lib/test/test_mutants.py +285 -0
  631. data/lib/rubyfox/server/data/lib/Lib/test/test_netrc.py +42 -0
  632. data/lib/rubyfox/server/data/lib/Lib/test/test_new.py +108 -0
  633. data/lib/rubyfox/server/data/lib/Lib/test/test_nis.py +32 -0
  634. data/lib/rubyfox/server/data/lib/Lib/test/test_ntpath.py +114 -0
  635. data/lib/rubyfox/server/data/lib/Lib/test/test_opcodes.py +65 -0
  636. data/lib/rubyfox/server/data/lib/Lib/test/test_openpty.py +21 -0
  637. data/lib/rubyfox/server/data/lib/Lib/test/test_operations.py +475 -0
  638. data/lib/rubyfox/server/data/lib/Lib/test/test_operator.py +218 -0
  639. data/lib/rubyfox/server/data/lib/Lib/test/test_os.py +187 -0
  640. data/lib/rubyfox/server/data/lib/Lib/test/test_parser.py +383 -0
  641. data/lib/rubyfox/server/data/lib/Lib/test/test_pep247.py +50 -0
  642. data/lib/rubyfox/server/data/lib/Lib/test/test_pickle.py +40 -0
  643. data/lib/rubyfox/server/data/lib/Lib/test/test_pkg.py +259 -0
  644. data/lib/rubyfox/server/data/lib/Lib/test/test_pkgimport.py +84 -0
  645. data/lib/rubyfox/server/data/lib/Lib/test/test_poll.py +3 -0
  646. data/lib/rubyfox/server/data/lib/Lib/test/test_popen2.py +72 -0
  647. data/lib/rubyfox/server/data/lib/Lib/test/test_posixpath.py +40 -0
  648. data/lib/rubyfox/server/data/lib/Lib/test/test_pow.py +107 -0
  649. data/lib/rubyfox/server/data/lib/Lib/test/test_pprint.py +104 -0
  650. data/lib/rubyfox/server/data/lib/Lib/test/test_profile.py +86 -0
  651. data/lib/rubyfox/server/data/lib/Lib/test/test_profilehooks.py +360 -0
  652. data/lib/rubyfox/server/data/lib/Lib/test/test_pty.py +98 -0
  653. data/lib/rubyfox/server/data/lib/Lib/test/test_pwd.py +71 -0
  654. data/lib/rubyfox/server/data/lib/Lib/test/test_pyclbr.py +154 -0
  655. data/lib/rubyfox/server/data/lib/Lib/test/test_pyexpat.py +202 -0
  656. data/lib/rubyfox/server/data/lib/Lib/test/test_queue.py +158 -0
  657. data/lib/rubyfox/server/data/lib/Lib/test/test_quopri.py +157 -0
  658. data/lib/rubyfox/server/data/lib/Lib/test/test_random.py +19 -0
  659. data/lib/rubyfox/server/data/lib/Lib/test/test_re.py +304 -0
  660. data/lib/rubyfox/server/data/lib/Lib/test/test_regex.py +113 -0
  661. data/lib/rubyfox/server/data/lib/Lib/test/test_repr.py +278 -0
  662. data/lib/rubyfox/server/data/lib/Lib/test/test_rfc822.py +211 -0
  663. data/lib/rubyfox/server/data/lib/Lib/test/test_rgbimg.py +63 -0
  664. data/lib/rubyfox/server/data/lib/Lib/test/test_richcmp.py +261 -0
  665. data/lib/rubyfox/server/data/lib/Lib/test/test_rotor.py +28 -0
  666. data/lib/rubyfox/server/data/lib/Lib/test/test_sax.py +727 -0
  667. data/lib/rubyfox/server/data/lib/Lib/test/test_scope.py +530 -0
  668. data/lib/rubyfox/server/data/lib/Lib/test/test_select.py +228 -0
  669. data/lib/rubyfox/server/data/lib/Lib/test/test_select_new.py +229 -0
  670. data/lib/rubyfox/server/data/lib/Lib/test/test_sets.py +793 -0
  671. data/lib/rubyfox/server/data/lib/Lib/test/test_sgmllib.py +314 -0
  672. data/lib/rubyfox/server/data/lib/Lib/test/test_sha.py +52 -0
  673. data/lib/rubyfox/server/data/lib/Lib/test/test_signal.py +66 -0
  674. data/lib/rubyfox/server/data/lib/Lib/test/test_socket.py +1116 -0
  675. data/lib/rubyfox/server/data/lib/Lib/test/test_socket_ssl.py +27 -0
  676. data/lib/rubyfox/server/data/lib/Lib/test/test_socketserver.py +165 -0
  677. data/lib/rubyfox/server/data/lib/Lib/test/test_sre.py +434 -0
  678. data/lib/rubyfox/server/data/lib/Lib/test/test_str2unicode.py +90 -0
  679. data/lib/rubyfox/server/data/lib/Lib/test/test_strftime.py +146 -0
  680. data/lib/rubyfox/server/data/lib/Lib/test/test_string.py +223 -0
  681. data/lib/rubyfox/server/data/lib/Lib/test/test_strop.py +133 -0
  682. data/lib/rubyfox/server/data/lib/Lib/test/test_struct.py +441 -0
  683. data/lib/rubyfox/server/data/lib/Lib/test/test_structseq.py +28 -0
  684. data/lib/rubyfox/server/data/lib/Lib/test/test_subclasses.py +204 -0
  685. data/lib/rubyfox/server/data/lib/Lib/test/test_sunaudiodev.py +28 -0
  686. data/lib/rubyfox/server/data/lib/Lib/test/test_sundry.py +102 -0
  687. data/lib/rubyfox/server/data/lib/Lib/test/test_support.py +265 -0
  688. data/lib/rubyfox/server/data/lib/Lib/test/test_symtable.py +8 -0
  689. data/lib/rubyfox/server/data/lib/Lib/test/test_tempfile.py +10 -0
  690. data/lib/rubyfox/server/data/lib/Lib/test/test_thread.py +116 -0
  691. data/lib/rubyfox/server/data/lib/Lib/test/test_threaded_import.py +56 -0
  692. data/lib/rubyfox/server/data/lib/Lib/test/test_threadedtempfile.py +86 -0
  693. data/lib/rubyfox/server/data/lib/Lib/test/test_threading.py +55 -0
  694. data/lib/rubyfox/server/data/lib/Lib/test/test_time.py +47 -0
  695. data/lib/rubyfox/server/data/lib/Lib/test/test_timing.py +21 -0
  696. data/lib/rubyfox/server/data/lib/Lib/test/test_tokenize.py +9 -0
  697. data/lib/rubyfox/server/data/lib/Lib/test/test_trace.py +219 -0
  698. data/lib/rubyfox/server/data/lib/Lib/test/test_traceback.py +49 -0
  699. data/lib/rubyfox/server/data/lib/Lib/test/test_types.py +762 -0
  700. data/lib/rubyfox/server/data/lib/Lib/test/test_ucn.py +113 -0
  701. data/lib/rubyfox/server/data/lib/Lib/test/test_unary.py +58 -0
  702. data/lib/rubyfox/server/data/lib/Lib/test/test_unicode.py +815 -0
  703. data/lib/rubyfox/server/data/lib/Lib/test/test_unicode_file.py +95 -0
  704. data/lib/rubyfox/server/data/lib/Lib/test/test_unicodedata.py +125 -0
  705. data/lib/rubyfox/server/data/lib/Lib/test/test_unpack.py +105 -0
  706. data/lib/rubyfox/server/data/lib/Lib/test/test_urllib.py +109 -0
  707. data/lib/rubyfox/server/data/lib/Lib/test/test_urllib2.py +31 -0
  708. data/lib/rubyfox/server/data/lib/Lib/test/test_urlparse.py +94 -0
  709. data/lib/rubyfox/server/data/lib/Lib/test/test_userdict.py +120 -0
  710. data/lib/rubyfox/server/data/lib/Lib/test/test_userlist.py +269 -0
  711. data/lib/rubyfox/server/data/lib/Lib/test/test_userstring.py +43 -0
  712. data/lib/rubyfox/server/data/lib/Lib/test/test_uu.py +158 -0
  713. data/lib/rubyfox/server/data/lib/Lib/test/test_wave.py +34 -0
  714. data/lib/rubyfox/server/data/lib/Lib/test/test_weakref.py +573 -0
  715. data/lib/rubyfox/server/data/lib/Lib/test/test_winreg.py +151 -0
  716. data/lib/rubyfox/server/data/lib/Lib/test/test_winsound.py +6 -0
  717. data/lib/rubyfox/server/data/lib/Lib/test/test_xmllib.py +35 -0
  718. data/lib/rubyfox/server/data/lib/Lib/test/test_xmlrpc.py +37 -0
  719. data/lib/rubyfox/server/data/lib/Lib/test/test_xreadline.py +43 -0
  720. data/lib/rubyfox/server/data/lib/Lib/test/test_zipfile.py +78 -0
  721. data/lib/rubyfox/server/data/lib/Lib/test/test_zlib.py +482 -0
  722. data/lib/rubyfox/server/data/lib/Lib/test/testall.py +43 -0
  723. data/lib/rubyfox/server/data/lib/Lib/test/testcodec.py +48 -0
  724. data/lib/rubyfox/server/data/lib/Lib/test/testimg.uue +1170 -0
  725. data/lib/rubyfox/server/data/lib/Lib/test/testimgr.uue +1170 -0
  726. data/lib/rubyfox/server/data/lib/Lib/test/testrgb.uue +971 -0
  727. data/lib/rubyfox/server/data/lib/Lib/test/tokenize_tests.py +175 -0
  728. data/lib/rubyfox/server/data/lib/Lib/test/whrandom.py +96 -0
  729. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/dbextstest.py +266 -0
  730. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/jndi.py +33 -0
  731. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/runner.py +204 -0
  732. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/sptest.py +227 -0
  733. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/test.xml +363 -0
  734. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/test_zxjdbc_dbapi20.py +26 -0
  735. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/zxtest.py +1242 -0
  736. data/lib/rubyfox/server/data/lib/Lib/this.py +28 -0
  737. data/lib/rubyfox/server/data/lib/Lib/threading.py +698 -0
  738. data/lib/rubyfox/server/data/lib/Lib/token$py.class +0 -0
  739. data/lib/rubyfox/server/data/lib/Lib/token.py +140 -0
  740. data/lib/rubyfox/server/data/lib/Lib/tokenize$py.class +0 -0
  741. data/lib/rubyfox/server/data/lib/Lib/tokenize.py +287 -0
  742. data/lib/rubyfox/server/data/lib/Lib/traceback$py.class +0 -0
  743. data/lib/rubyfox/server/data/lib/Lib/traceback.py +301 -0
  744. data/lib/rubyfox/server/data/lib/Lib/tzparse.py +98 -0
  745. data/lib/rubyfox/server/data/lib/Lib/unittest.py +723 -0
  746. data/lib/rubyfox/server/data/lib/Lib/urllib.py +1465 -0
  747. data/lib/rubyfox/server/data/lib/Lib/urllib2.py +1144 -0
  748. data/lib/rubyfox/server/data/lib/Lib/urlparse.py +276 -0
  749. data/lib/rubyfox/server/data/lib/Lib/user.py +45 -0
  750. data/lib/rubyfox/server/data/lib/Lib/uu.py +195 -0
  751. data/lib/rubyfox/server/data/lib/Lib/warnings$py.class +0 -0
  752. data/lib/rubyfox/server/data/lib/Lib/warnings.py +258 -0
  753. data/lib/rubyfox/server/data/lib/Lib/weakref.py +280 -0
  754. data/lib/rubyfox/server/data/lib/Lib/whichdb.py +87 -0
  755. data/lib/rubyfox/server/data/lib/Lib/whrandom.py +140 -0
  756. data/lib/rubyfox/server/data/lib/Lib/xdrlib.py +285 -0
  757. data/lib/rubyfox/server/data/lib/Lib/xml/FtCore.py +58 -0
  758. data/lib/rubyfox/server/data/lib/Lib/xml/Uri.py +380 -0
  759. data/lib/rubyfox/server/data/lib/Lib/xml/__init__.py +41 -0
  760. data/lib/rubyfox/server/data/lib/Lib/xml/dom/MessageSource.py +54 -0
  761. data/lib/rubyfox/server/data/lib/Lib/xml/dom/NodeFilter.py +27 -0
  762. data/lib/rubyfox/server/data/lib/Lib/xml/dom/__init__.py +232 -0
  763. data/lib/rubyfox/server/data/lib/Lib/xml/dom/domreg.py +99 -0
  764. data/lib/rubyfox/server/data/lib/Lib/xml/dom/minicompat.py +184 -0
  765. data/lib/rubyfox/server/data/lib/Lib/xml/dom/minidom.py +1943 -0
  766. data/lib/rubyfox/server/data/lib/Lib/xml/dom/pulldom.py +350 -0
  767. data/lib/rubyfox/server/data/lib/Lib/xml/dom/xmlbuilder.py +388 -0
  768. data/lib/rubyfox/server/data/lib/Lib/xml/sax/__init__.py +102 -0
  769. data/lib/rubyfox/server/data/lib/Lib/xml/sax/_exceptions.py +127 -0
  770. data/lib/rubyfox/server/data/lib/Lib/xml/sax/drivers2/__init__.py +1 -0
  771. data/lib/rubyfox/server/data/lib/Lib/xml/sax/drivers2/drv_javasax.py +333 -0
  772. data/lib/rubyfox/server/data/lib/Lib/xml/sax/handler.py +345 -0
  773. data/lib/rubyfox/server/data/lib/Lib/xml/sax/saxlib.py +430 -0
  774. data/lib/rubyfox/server/data/lib/Lib/xml/sax/saxutils.py +813 -0
  775. data/lib/rubyfox/server/data/lib/Lib/xml/sax/xmlreader.py +378 -0
  776. data/lib/rubyfox/server/data/lib/Lib/xmllib.py +926 -0
  777. data/lib/rubyfox/server/data/lib/Lib/xmlrpclib.py +1019 -0
  778. data/lib/rubyfox/server/data/lib/Lib/zipfile.py +586 -0
  779. data/lib/rubyfox/server/data/lib/Lib/zlib.py +156 -0
  780. data/lib/rubyfox/server/data/lib/boot.jar +0 -0
  781. data/lib/rubyfox/server/data/lib/cachedir/.keep +0 -0
  782. data/lib/rubyfox/server/data/lib/commons-beanutils-1.7.0.jar +0 -0
  783. data/lib/rubyfox/server/data/lib/commons-collections-3.2.1.jar +0 -0
  784. data/lib/rubyfox/server/data/lib/commons-dbcp-1.4.jar +0 -0
  785. data/lib/rubyfox/server/data/lib/commons-io-1.4.jar +0 -0
  786. data/lib/rubyfox/server/data/lib/commons-lang-2.4.jar +0 -0
  787. data/lib/rubyfox/server/data/lib/commons-logging-1.1.1.jar +0 -0
  788. data/lib/rubyfox/server/data/lib/commons-pool-1.5.4.jar +0 -0
  789. data/lib/rubyfox/server/data/lib/commons-vfs-1.0.jar +0 -0
  790. data/lib/rubyfox/server/data/lib/ezmorph-1.0.6.jar +0 -0
  791. data/lib/rubyfox/server/data/lib/httpclient-4.0.3.jar +0 -0
  792. data/lib/rubyfox/server/data/lib/httpcore-4.0.1.jar +0 -0
  793. data/lib/rubyfox/server/data/lib/imap.jar +0 -0
  794. data/lib/rubyfox/server/data/lib/jconsole/COPYING.txt +504 -0
  795. data/lib/rubyfox/server/data/lib/jconsole/bug_test_case.py +49 -0
  796. data/lib/rubyfox/server/data/lib/jconsole/console$py.class +0 -0
  797. data/lib/rubyfox/server/data/lib/jconsole/console.py +439 -0
  798. data/lib/rubyfox/server/data/lib/jconsole/history$py.class +0 -0
  799. data/lib/rubyfox/server/data/lib/jconsole/history.py +82 -0
  800. data/lib/rubyfox/server/data/lib/jconsole/history_test_case.py +133 -0
  801. data/lib/rubyfox/server/data/lib/jconsole/introspect$py.class +0 -0
  802. data/lib/rubyfox/server/data/lib/jconsole/introspect.py +373 -0
  803. data/lib/rubyfox/server/data/lib/jconsole/introspect_test_case.py +19 -0
  804. data/lib/rubyfox/server/data/lib/jconsole/issue_17_test_case.py +36 -0
  805. data/lib/rubyfox/server/data/lib/jconsole/jintrospect$py.class +0 -0
  806. data/lib/rubyfox/server/data/lib/jconsole/jintrospect.py +316 -0
  807. data/lib/rubyfox/server/data/lib/jconsole/jintrospect_test_case.py +107 -0
  808. data/lib/rubyfox/server/data/lib/jconsole/popup$py.class +0 -0
  809. data/lib/rubyfox/server/data/lib/jconsole/popup.py +178 -0
  810. data/lib/rubyfox/server/data/lib/jconsole/run_tests.py +8 -0
  811. data/lib/rubyfox/server/data/lib/jconsole/static_test_case.py +36 -0
  812. data/lib/rubyfox/server/data/lib/jconsole/testcase.py +38 -0
  813. data/lib/rubyfox/server/data/lib/jconsole/tip$py.class +0 -0
  814. data/lib/rubyfox/server/data/lib/jconsole/tip.py +47 -0
  815. data/lib/rubyfox/server/data/lib/jmx-util-1.2.3.jar +0 -0
  816. data/lib/rubyfox/server/data/lib/joda-time-1.6.jar +0 -0
  817. data/lib/rubyfox/server/data/lib/js.jar +0 -0
  818. data/lib/rubyfox/server/data/lib/json-lib-2.2.3-jdk15.jar +0 -0
  819. data/lib/rubyfox/server/data/lib/jython.jar +0 -0
  820. data/lib/rubyfox/server/data/lib/log4j-1.2.15.jar +0 -0
  821. data/lib/rubyfox/server/data/lib/logs-backup-app.jar +0 -0
  822. data/lib/rubyfox/server/data/lib/mailapi.jar +0 -0
  823. data/lib/rubyfox/server/data/lib/pop3.jar +0 -0
  824. data/lib/rubyfox/server/data/lib/scala-library.jar +0 -0
  825. data/lib/rubyfox/server/data/lib/sfs2x-admin.jar +0 -0
  826. data/lib/rubyfox/server/data/lib/sfs2x-core.jar +0 -0
  827. data/lib/rubyfox/server/data/lib/sfs2x-util.jar +0 -0
  828. data/lib/rubyfox/server/data/lib/sfs2x.jar +0 -0
  829. data/lib/rubyfox/server/data/lib/slf4j-api-1.5.10.jar +0 -0
  830. data/lib/rubyfox/server/data/lib/slf4j-log4j12.jar +0 -0
  831. data/lib/rubyfox/server/data/lib/smtp.jar +0 -0
  832. data/lib/rubyfox/server/data/lib/terracotta-api-1.1.1.jar +0 -0
  833. data/lib/rubyfox/server/data/lib/ws-engine.jar +0 -0
  834. data/lib/rubyfox/server/data/lib/xpp3_min-1.1.4c.jar +0 -0
  835. data/lib/rubyfox/server/data/lib/xstream-1.3.1.jar +0 -0
  836. data/lib/rubyfox/server/data/logs/.keep +0 -0
  837. data/lib/rubyfox/server/data/logs/bluebox/.keep +0 -0
  838. data/lib/rubyfox/server/data/logs/boot/.keep +0 -0
  839. data/lib/rubyfox/server/data/logs/http/.keep +0 -0
  840. data/lib/rubyfox/server/data/logs/smartfox.log +295 -0
  841. data/lib/rubyfox/server/data/root/.keep +0 -0
  842. data/lib/rubyfox/server/data/root/_css_/default.css +170 -0
  843. data/lib/rubyfox/server/data/root/_css_/reset.css +49 -0
  844. data/lib/rubyfox/server/data/root/_images_/background_gradient.png +0 -0
  845. data/lib/rubyfox/server/data/root/_images_/background_logo.png +0 -0
  846. data/lib/rubyfox/server/data/root/_images_/favicon.png +0 -0
  847. data/lib/rubyfox/server/data/root/_images_/logo_smartfoxserver.png +0 -0
  848. data/lib/rubyfox/server/data/root/admin/.keep +0 -0
  849. data/lib/rubyfox/server/data/root/admin/AdminTool.html +108 -0
  850. data/lib/rubyfox/server/data/root/admin/AdminTool.swf +0 -0
  851. data/lib/rubyfox/server/data/root/admin/ReleaseNotes.txt +29 -0
  852. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/adobeFlashPlayer.png +0 -0
  853. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/advanced.png +0 -0
  854. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/banManager.png +0 -0
  855. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bannedIPs.png +0 -0
  856. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bannedUsernames.png +0 -0
  857. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bookmarks.png +0 -0
  858. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bootLog.png +0 -0
  859. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/buddyList.png +0 -0
  860. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/buddyProperties.png +0 -0
  861. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/connection.png +0 -0
  862. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/databaseManager.png +0 -0
  863. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/floodFilter.png +0 -0
  864. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/gameSettings.png +0 -0
  865. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/general.png +0 -0
  866. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/globalServerStatus.png +0 -0
  867. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/iPFilter.png +0 -0
  868. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/jVMSettings.png +0 -0
  869. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/logsDownload.png +0 -0
  870. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/mailer.png +0 -0
  871. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/permissionsAndEvents.png +0 -0
  872. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/privilegeManager.png +0 -0
  873. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/remoteAdmin.png +0 -0
  874. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/roomExtension.png +0 -0
  875. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/roomVariables.png +0 -0
  876. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/roomsAndGroups.png +0 -0
  877. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeLog.png +0 -0
  878. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeRoomSettings.png +0 -0
  879. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeUserSettings.png +0 -0
  880. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeZoneSettings.png +0 -0
  881. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/systemQueueStatus.png +0 -0
  882. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/userManagement.png +0 -0
  883. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/userVariables.png +0 -0
  884. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/usersTraffic.png +0 -0
  885. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/webServer.png +0 -0
  886. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/wordsFilter.png +0 -0
  887. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/zoneExtension.png +0 -0
  888. data/lib/rubyfox/server/data/root/admin/index.html +108 -0
  889. data/lib/rubyfox/server/data/root/admin/modules/BanManager/BanManager.swf +0 -0
  890. data/lib/rubyfox/server/data/root/admin/modules/BanManager/icon.png +0 -0
  891. data/lib/rubyfox/server/data/root/admin/modules/BlueBoxMonitor/BlueBoxMonitor.swf +0 -0
  892. data/lib/rubyfox/server/data/root/admin/modules/BlueBoxMonitor/icon.png +0 -0
  893. data/lib/rubyfox/server/data/root/admin/modules/LicenseManager/LicenseManager.swf +0 -0
  894. data/lib/rubyfox/server/data/root/admin/modules/LicenseManager/icon.png +0 -0
  895. data/lib/rubyfox/server/data/root/admin/modules/LogViewer/LogViewer.swf +0 -0
  896. data/lib/rubyfox/server/data/root/admin/modules/LogViewer/icon.png +0 -0
  897. data/lib/rubyfox/server/data/root/admin/modules/RuntimeStatistics/RuntimeStatistics.swf +0 -0
  898. data/lib/rubyfox/server/data/root/admin/modules/RuntimeStatistics/icon.png +0 -0
  899. data/lib/rubyfox/server/data/root/admin/modules/ServerConfigurator/ServerConfigurator.swf +0 -0
  900. data/lib/rubyfox/server/data/root/admin/modules/ServerConfigurator/icon.png +0 -0
  901. data/lib/rubyfox/server/data/root/admin/modules/ZoneConfigurator/ZoneConfigurator.swf +0 -0
  902. data/lib/rubyfox/server/data/root/admin/modules/ZoneConfigurator/icon.png +0 -0
  903. data/lib/rubyfox/server/data/root/admin/modules/ZoneMonitor/ZoneMonitor.swf +0 -0
  904. data/lib/rubyfox/server/data/root/admin/modules/ZoneMonitor/icon.png +0 -0
  905. data/lib/rubyfox/server/data/root/admin/modules/config.xml +12 -0
  906. data/lib/rubyfox/server/data/root/admin/playerProductInstall.swf +0 -0
  907. data/lib/rubyfox/server/data/root/admin/swfobject.js +777 -0
  908. data/lib/rubyfox/server/data/root/crossdomain.xml +6 -0
  909. data/lib/rubyfox/server/data/root/index.html +63 -0
  910. data/lib/rubyfox/server/data/sfs2x-service +435 -0
  911. data/lib/rubyfox/server/data/sfs2x-service.vmoptions +5 -0
  912. data/lib/rubyfox/server/data/sfs2x.sh +12 -0
  913. data/lib/rubyfox/server/data/www/.keep +0 -0
  914. data/lib/rubyfox/server/data/www/BlueBox.war +0 -0
  915. data/lib/rubyfox/server/data/www/root/_css_/default.css +170 -0
  916. data/lib/rubyfox/server/data/www/root/_css_/reset.css +49 -0
  917. data/lib/rubyfox/server/data/www/root/_images_/background_gradient.png +0 -0
  918. data/lib/rubyfox/server/data/www/root/_images_/background_logo.png +0 -0
  919. data/lib/rubyfox/server/data/www/root/_images_/favicon.png +0 -0
  920. data/lib/rubyfox/server/data/www/root/_images_/logo_smartfoxserver.png +0 -0
  921. data/lib/rubyfox/server/data/www/root/admin/.keep +0 -0
  922. data/lib/rubyfox/server/data/www/root/admin/AdminTool.html +108 -0
  923. data/lib/rubyfox/server/data/www/root/admin/AdminTool.swf +0 -0
  924. data/lib/rubyfox/server/data/www/root/admin/ReleaseNotes.txt +63 -0
  925. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/adobeFlashPlayer.png +0 -0
  926. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/advanced.png +0 -0
  927. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/banManager.png +0 -0
  928. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bannedIPs.png +0 -0
  929. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bannedUsernames.png +0 -0
  930. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bookmarks.png +0 -0
  931. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bootLog.png +0 -0
  932. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/buddyList.png +0 -0
  933. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/buddyProperties.png +0 -0
  934. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/connection.png +0 -0
  935. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/databaseManager.png +0 -0
  936. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/floodFilter.png +0 -0
  937. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/gameSettings.png +0 -0
  938. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/general.png +0 -0
  939. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/globalServerStatus.png +0 -0
  940. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/hTML5WebSockets.png +0 -0
  941. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/iPFilter.png +0 -0
  942. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/jVMSettings.png +0 -0
  943. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/logsDownload.png +0 -0
  944. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/mailer.png +0 -0
  945. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/permissionsAndEvents.png +0 -0
  946. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/privilegeManager.png +0 -0
  947. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/remoteAdmin.png +0 -0
  948. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomExtension.png +0 -0
  949. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomVariables.png +0 -0
  950. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomsAndGroups.png +0 -0
  951. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeLog.png +0 -0
  952. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeRoomSettings.png +0 -0
  953. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeUserSettings.png +0 -0
  954. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeZoneSettings.png +0 -0
  955. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/systemQueueStatus.png +0 -0
  956. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/userManagement.png +0 -0
  957. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/userVariables.png +0 -0
  958. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/usersTraffic.png +0 -0
  959. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/webServer.png +0 -0
  960. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/wordsFilter.png +0 -0
  961. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/zoneExtension.png +0 -0
  962. data/lib/rubyfox/server/data/www/root/admin/index.html +108 -0
  963. data/lib/rubyfox/server/data/www/root/admin/modules/BanManager/BanManager.swf +0 -0
  964. data/lib/rubyfox/server/data/www/root/admin/modules/BanManager/icon.png +0 -0
  965. data/lib/rubyfox/server/data/www/root/admin/modules/BlueBoxMonitor/BlueBoxMonitor.swf +0 -0
  966. data/lib/rubyfox/server/data/www/root/admin/modules/BlueBoxMonitor/icon.png +0 -0
  967. data/lib/rubyfox/server/data/www/root/admin/modules/Dashboard/Dashboard.swf +0 -0
  968. data/lib/rubyfox/server/data/www/root/admin/modules/Dashboard/icon.png +0 -0
  969. data/lib/rubyfox/server/data/www/root/admin/modules/LicenseManager/LicenseManager.swf +0 -0
  970. data/lib/rubyfox/server/data/www/root/admin/modules/LicenseManager/icon.png +0 -0
  971. data/lib/rubyfox/server/data/www/root/admin/modules/LogViewer/LogViewer.swf +0 -0
  972. data/lib/rubyfox/server/data/www/root/admin/modules/LogViewer/icon.png +0 -0
  973. data/lib/rubyfox/server/data/www/root/admin/modules/RuntimeStatistics/RuntimeStatistics.swf +0 -0
  974. data/lib/rubyfox/server/data/www/root/admin/modules/RuntimeStatistics/icon.png +0 -0
  975. data/lib/rubyfox/server/data/www/root/admin/modules/ServerConfigurator/ServerConfigurator.swf +0 -0
  976. data/lib/rubyfox/server/data/www/root/admin/modules/ServerConfigurator/icon.png +0 -0
  977. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneConfigurator/ZoneConfigurator.swf +0 -0
  978. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneConfigurator/icon.png +0 -0
  979. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneMonitor/ZoneMonitor.swf +0 -0
  980. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneMonitor/icon.png +0 -0
  981. data/lib/rubyfox/server/data/www/root/admin/modules/config.xml +12 -0
  982. data/lib/rubyfox/server/data/www/root/admin/playerProductInstall.swf +0 -0
  983. data/lib/rubyfox/server/data/www/root/admin/swfobject.js +777 -0
  984. data/lib/rubyfox/server/data/www/root/crossdomain.xml +6 -0
  985. data/lib/rubyfox/server/data/www/root/examples/.keep +0 -0
  986. data/lib/rubyfox/server/data/www/root/examples/index.html +43 -0
  987. data/lib/rubyfox/server/data/www/root/index.html +63 -0
  988. data/lib/rubyfox/server/data/zones/.keep +0 -0
  989. data/lib/rubyfox/server/environment.rb +31 -0
  990. data/lib/rubyfox/server/version.rb +5 -0
  991. data/lib/rubyfox/server.rb +9 -0
  992. data/rubyfox-server.gemspec +22 -0
  993. metadata +1076 -0
@@ -0,0 +1,2958 @@
1
+ """Test date/time type.
2
+
3
+ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases
4
+ """
5
+
6
+ import sys
7
+ import pickle
8
+ import cPickle
9
+ import unittest
10
+
11
+ from datetime import MINYEAR, MAXYEAR
12
+ from datetime import timedelta
13
+ from datetime import tzinfo
14
+ from datetime import time
15
+ from datetime import date, datetime
16
+ from test import test_support
17
+
18
+ # Before Python 2.3, proto=2 was taken as a synonym for proto=1.
19
+ # cPickle not updated in Jython so commenting out.
20
+ pickle_choices = [(pickler, unpickler, proto)
21
+ for pickler in pickle, #cPickle
22
+ for unpickler in pickle, #cPickle
23
+ for proto in range(3)]
24
+ #assert len(pickle_choices) == 2*2*3
25
+
26
+ # An arbitrary collection of objects of non-datetime types, for testing
27
+ # mixed-type comparisons.
28
+ OTHERSTUFF = (10, 10L, 34.5, "abc", {}, [], ())
29
+
30
+
31
+ #############################################################################
32
+ # module tests
33
+
34
+ class TestModule(unittest.TestCase):
35
+
36
+ def test_constants(self):
37
+ import datetime
38
+ self.assertEqual(datetime.MINYEAR, 1)
39
+ self.assertEqual(datetime.MAXYEAR, 9999)
40
+
41
+ #############################################################################
42
+ # tzinfo tests
43
+
44
+ class FixedOffset(tzinfo):
45
+ def __init__(self, offset, name, dstoffset=42):
46
+ if isinstance(offset, int):
47
+ offset = timedelta(minutes=offset)
48
+ if isinstance(dstoffset, int):
49
+ dstoffset = timedelta(minutes=dstoffset)
50
+ self.__offset = offset
51
+ self.__name = name
52
+ self.__dstoffset = dstoffset
53
+ def __repr__(self):
54
+ return self.__name.lower()
55
+ def utcoffset(self, dt):
56
+ return self.__offset
57
+ def tzname(self, dt):
58
+ return self.__name
59
+ def dst(self, dt):
60
+ return self.__dstoffset
61
+
62
+ class PicklableFixedOffset(FixedOffset):
63
+ def __init__(self, offset=None, name=None, dstoffset=None):
64
+ FixedOffset.__init__(self, offset, name, dstoffset)
65
+
66
+ class TestTZInfo(unittest.TestCase):
67
+
68
+ def test_non_abstractness(self):
69
+ # In order to allow subclasses to get pickled, the C implementation
70
+ # wasn't able to get away with having __init__ raise
71
+ # NotImplementedError.
72
+ useless = tzinfo()
73
+ dt = datetime.max
74
+ self.assertRaises(NotImplementedError, useless.tzname, dt)
75
+ self.assertRaises(NotImplementedError, useless.utcoffset, dt)
76
+ self.assertRaises(NotImplementedError, useless.dst, dt)
77
+
78
+ def test_subclass_must_override(self):
79
+ class NotEnough(tzinfo):
80
+ def __init__(self, offset, name):
81
+ self.__offset = offset
82
+ self.__name = name
83
+ self.failUnless(issubclass(NotEnough, tzinfo))
84
+ ne = NotEnough(3, "NotByALongShot")
85
+ self.failUnless(isinstance(ne, tzinfo))
86
+
87
+ dt = datetime.now()
88
+ self.assertRaises(NotImplementedError, ne.tzname, dt)
89
+ self.assertRaises(NotImplementedError, ne.utcoffset, dt)
90
+ self.assertRaises(NotImplementedError, ne.dst, dt)
91
+
92
+ def test_normal(self):
93
+ fo = FixedOffset(3, "Three")
94
+ self.failUnless(isinstance(fo, tzinfo))
95
+ for dt in datetime.now(), None:
96
+ self.assertEqual(fo.utcoffset(dt), timedelta(minutes=3))
97
+ self.assertEqual(fo.tzname(dt), "Three")
98
+ self.assertEqual(fo.dst(dt), timedelta(minutes=42))
99
+
100
+ #XXX: pickling not working for jython yet.
101
+ def test_pickling_base(self):
102
+ # There's no point to pickling tzinfo objects on their own (they
103
+ # carry no data), but they need to be picklable anyway else
104
+ # concrete subclasses can't be pickled.
105
+ orig = tzinfo.__new__(tzinfo)
106
+ self.failUnless(type(orig) is tzinfo)
107
+ for pickler, unpickler, proto in pickle_choices:
108
+ green = pickler.dumps(orig, proto)
109
+ derived = unpickler.loads(green)
110
+ self.failUnless(type(derived) is tzinfo)
111
+
112
+ #XXX: pickling not working for jython yet.
113
+ def test_pickling_subclass(self):
114
+ # Make sure we can pickle/unpickle an instance of a subclass.
115
+ offset = timedelta(minutes=-300)
116
+ orig = PicklableFixedOffset(offset, 'cookie')
117
+ self.failUnless(isinstance(orig, tzinfo))
118
+ self.failUnless(type(orig) is PicklableFixedOffset)
119
+ self.assertEqual(orig.utcoffset(None), offset)
120
+ self.assertEqual(orig.tzname(None), 'cookie')
121
+ for pickler, unpickler, proto in pickle_choices:
122
+ green = pickler.dumps(orig, proto)
123
+ derived = unpickler.loads(green)
124
+ self.failUnless(isinstance(derived, tzinfo))
125
+ self.failUnless(type(derived) is PicklableFixedOffset)
126
+ self.assertEqual(derived.utcoffset(None), offset)
127
+ self.assertEqual(derived.tzname(None), 'cookie')
128
+
129
+ #############################################################################
130
+ # Base clase for testing a particular aspect of timedelta, time, date and
131
+ # datetime comparisons.
132
+
133
+ class HarmlessMixedComparison(unittest.TestCase):
134
+ # Test that __eq__ and __ne__ don't complain for mixed-type comparisons.
135
+
136
+ # Subclasses must define 'theclass', and theclass(1, 1, 1) must be a
137
+ # legit constructor.
138
+
139
+ def test_harmless_mixed_comparison(self):
140
+ me = self.theclass(1, 1, 1)
141
+
142
+ self.failIf(me == ())
143
+ self.failUnless(me != ())
144
+ self.failIf(() == me)
145
+ self.failUnless(() != me)
146
+
147
+ self.failUnless(me in [1, 20L, [], me])
148
+ self.failIf(me not in [1, 20L, [], me])
149
+
150
+ self.failUnless([] in [me, 1, 20L, []])
151
+ self.failIf([] not in [me, 1, 20L, []])
152
+
153
+ def test_harmful_mixed_comparison(self):
154
+ me = self.theclass(1, 1, 1)
155
+
156
+ self.assertRaises(TypeError, lambda: me < ())
157
+ self.assertRaises(TypeError, lambda: me <= ())
158
+ self.assertRaises(TypeError, lambda: me > ())
159
+ self.assertRaises(TypeError, lambda: me >= ())
160
+
161
+ self.assertRaises(TypeError, lambda: () < me)
162
+ self.assertRaises(TypeError, lambda: () <= me)
163
+ self.assertRaises(TypeError, lambda: () > me)
164
+ self.assertRaises(TypeError, lambda: () >= me)
165
+
166
+ self.assertRaises(TypeError, cmp, (), me)
167
+ self.assertRaises(TypeError, cmp, me, ())
168
+
169
+ #############################################################################
170
+ # timedelta tests
171
+
172
+ class TestTimeDelta(HarmlessMixedComparison):
173
+
174
+ theclass = timedelta
175
+
176
+ def test_constructor(self):
177
+ eq = self.assertEqual
178
+ td = timedelta
179
+
180
+ # Check keyword args to constructor
181
+ eq(td(), td(weeks=0, days=0, hours=0, minutes=0, seconds=0,
182
+ milliseconds=0, microseconds=0))
183
+ eq(td(1), td(days=1))
184
+ eq(td(0, 1), td(seconds=1))
185
+ eq(td(0, 0, 1), td(microseconds=1))
186
+ eq(td(weeks=1), td(days=7))
187
+ eq(td(days=1), td(hours=24))
188
+ eq(td(hours=1), td(minutes=60))
189
+ eq(td(minutes=1), td(seconds=60))
190
+ eq(td(seconds=1), td(milliseconds=1000))
191
+ eq(td(milliseconds=1), td(microseconds=1000))
192
+
193
+ # Check float args to constructor
194
+ eq(td(weeks=1.0/7), td(days=1))
195
+ eq(td(days=1.0/24), td(hours=1))
196
+ eq(td(hours=1.0/60), td(minutes=1))
197
+ eq(td(minutes=1.0/60), td(seconds=1))
198
+ eq(td(seconds=0.001), td(milliseconds=1))
199
+ eq(td(milliseconds=0.001), td(microseconds=1))
200
+
201
+ def test_computations(self):
202
+ eq = self.assertEqual
203
+ td = timedelta
204
+
205
+ a = td(7) # One week
206
+ b = td(0, 60) # One minute
207
+ c = td(0, 0, 1000) # One millisecond
208
+ eq(a+b+c, td(7, 60, 1000))
209
+ eq(a-b, td(6, 24*3600 - 60))
210
+ eq(-a, td(-7))
211
+ eq(+a, td(7))
212
+ eq(-b, td(-1, 24*3600 - 60))
213
+ eq(-c, td(-1, 24*3600 - 1, 999000))
214
+ eq(abs(a), a)
215
+ eq(abs(-a), a)
216
+ eq(td(6, 24*3600), a)
217
+ eq(td(0, 0, 60*1000000), b)
218
+ eq(a*10, td(70))
219
+ eq(a*10, 10*a)
220
+ eq(a*10L, 10*a)
221
+ eq(b*10, td(0, 600))
222
+ eq(10*b, td(0, 600))
223
+ eq(b*10L, td(0, 600))
224
+ eq(c*10, td(0, 0, 10000))
225
+ eq(10*c, td(0, 0, 10000))
226
+ eq(c*10L, td(0, 0, 10000))
227
+ eq(a*-1, -a)
228
+ eq(b*-2, -b-b)
229
+ eq(c*-2, -c+-c)
230
+ eq(b*(60*24), (b*60)*24)
231
+ eq(b*(60*24), (60*b)*24)
232
+ eq(c*1000, td(0, 1))
233
+ eq(1000*c, td(0, 1))
234
+ eq(a//7, td(1))
235
+ eq(b//10, td(0, 6))
236
+ eq(c//1000, td(0, 0, 1))
237
+ eq(a//10, td(0, 7*24*360))
238
+ eq(a//3600000, td(0, 0, 7*24*1000))
239
+
240
+ def test_disallowed_computations(self):
241
+ a = timedelta(42)
242
+
243
+ # Add/sub ints, longs, floats should be illegal
244
+ for i in 1, 1L, 1.0:
245
+ self.assertRaises(TypeError, lambda: a+i)
246
+ self.assertRaises(TypeError, lambda: a-i)
247
+ self.assertRaises(TypeError, lambda: i+a)
248
+ self.assertRaises(TypeError, lambda: i-a)
249
+
250
+ # Mul/div by float isn't supported.
251
+ x = 2.3
252
+ self.assertRaises(TypeError, lambda: a*x)
253
+ self.assertRaises(TypeError, lambda: x*a)
254
+ self.assertRaises(TypeError, lambda: a/x)
255
+ self.assertRaises(TypeError, lambda: x/a)
256
+ self.assertRaises(TypeError, lambda: a // x)
257
+ self.assertRaises(TypeError, lambda: x // a)
258
+
259
+ # Divison of int by timedelta doesn't make sense.
260
+ # Division by zero doesn't make sense.
261
+ for zero in 0, 0L:
262
+ self.assertRaises(TypeError, lambda: zero // a)
263
+ self.assertRaises(ZeroDivisionError, lambda: a // zero)
264
+
265
+ def test_basic_attributes(self):
266
+ days, seconds, us = 1, 7, 31
267
+ td = timedelta(days, seconds, us)
268
+ self.assertEqual(td.days, days)
269
+ self.assertEqual(td.seconds, seconds)
270
+ self.assertEqual(td.microseconds, us)
271
+
272
+ def test_carries(self):
273
+ t1 = timedelta(days=100,
274
+ weeks=-7,
275
+ hours=-24*(100-49),
276
+ minutes=-3,
277
+ seconds=12,
278
+ microseconds=(3*60 - 12) * 1e6 + 1)
279
+ t2 = timedelta(microseconds=1)
280
+ self.assertEqual(t1, t2)
281
+
282
+ def test_hash_equality(self):
283
+ t1 = timedelta(days=100,
284
+ weeks=-7,
285
+ hours=-24*(100-49),
286
+ minutes=-3,
287
+ seconds=12,
288
+ microseconds=(3*60 - 12) * 1000000)
289
+ t2 = timedelta()
290
+ self.assertEqual(hash(t1), hash(t2))
291
+
292
+ t1 += timedelta(weeks=7)
293
+ t2 += timedelta(days=7*7)
294
+ self.assertEqual(t1, t2)
295
+ self.assertEqual(hash(t1), hash(t2))
296
+
297
+ d = {t1: 1}
298
+ d[t2] = 2
299
+ self.assertEqual(len(d), 1)
300
+ self.assertEqual(d[t1], 2)
301
+
302
+ #XXX: pickling not working for jython yet.
303
+ def test_pickling(self):
304
+ args = 12, 34, 56
305
+ orig = timedelta(*args)
306
+ for pickler, unpickler, proto in pickle_choices:
307
+ green = pickler.dumps(orig, proto)
308
+ derived = unpickler.loads(green)
309
+ self.assertEqual(orig, derived)
310
+
311
+ def test_compare(self):
312
+ t1 = timedelta(2, 3, 4)
313
+ t2 = timedelta(2, 3, 4)
314
+ self.failUnless(t1 == t2)
315
+ self.failUnless(t1 <= t2)
316
+ self.failUnless(t1 >= t2)
317
+ self.failUnless(not t1 != t2)
318
+ self.failUnless(not t1 < t2)
319
+ self.failUnless(not t1 > t2)
320
+ self.assertEqual(cmp(t1, t2), 0)
321
+ self.assertEqual(cmp(t2, t1), 0)
322
+
323
+ for args in (3, 3, 3), (2, 4, 4), (2, 3, 5):
324
+ t2 = timedelta(*args) # this is larger than t1
325
+ self.failUnless(t1 < t2)
326
+ self.failUnless(t2 > t1)
327
+ self.failUnless(t1 <= t2)
328
+ self.failUnless(t2 >= t1)
329
+ self.failUnless(t1 != t2)
330
+ self.failUnless(t2 != t1)
331
+ self.failUnless(not t1 == t2)
332
+ self.failUnless(not t2 == t1)
333
+ self.failUnless(not t1 > t2)
334
+ self.failUnless(not t2 < t1)
335
+ self.failUnless(not t1 >= t2)
336
+ self.failUnless(not t2 <= t1)
337
+ self.assertEqual(cmp(t1, t2), -1)
338
+ self.assertEqual(cmp(t2, t1), 1)
339
+
340
+ for badarg in OTHERSTUFF:
341
+ self.assertEqual(t1 == badarg, False)
342
+ self.assertEqual(t1 != badarg, True)
343
+ self.assertEqual(badarg == t1, False)
344
+ self.assertEqual(badarg != t1, True)
345
+
346
+ self.assertRaises(TypeError, lambda: t1 <= badarg)
347
+ self.assertRaises(TypeError, lambda: t1 < badarg)
348
+ self.assertRaises(TypeError, lambda: t1 > badarg)
349
+ self.assertRaises(TypeError, lambda: t1 >= badarg)
350
+ self.assertRaises(TypeError, lambda: badarg <= t1)
351
+ self.assertRaises(TypeError, lambda: badarg < t1)
352
+ self.assertRaises(TypeError, lambda: badarg > t1)
353
+ self.assertRaises(TypeError, lambda: badarg >= t1)
354
+
355
+ def test_str(self):
356
+ td = timedelta
357
+ eq = self.assertEqual
358
+
359
+ eq(str(td(1)), "1 day, 0:00:00")
360
+ eq(str(td(-1)), "-1 day, 0:00:00")
361
+ eq(str(td(2)), "2 days, 0:00:00")
362
+ eq(str(td(-2)), "-2 days, 0:00:00")
363
+
364
+ eq(str(td(hours=12, minutes=58, seconds=59)), "12:58:59")
365
+ eq(str(td(hours=2, minutes=3, seconds=4)), "2:03:04")
366
+ eq(str(td(weeks=-30, hours=23, minutes=12, seconds=34)),
367
+ "-210 days, 23:12:34")
368
+
369
+ eq(str(td(milliseconds=1)), "0:00:00.001000")
370
+ eq(str(td(microseconds=3)), "0:00:00.000003")
371
+
372
+ eq(str(td(days=999999999, hours=23, minutes=59, seconds=59,
373
+ microseconds=999999)),
374
+ "999999999 days, 23:59:59.999999")
375
+
376
+ def test_roundtrip(self):
377
+ for td in (timedelta(days=999999999, hours=23, minutes=59,
378
+ seconds=59, microseconds=999999),
379
+ timedelta(days=-999999999),
380
+ timedelta(days=1, seconds=2, microseconds=3)):
381
+
382
+ # Verify td -> string -> td identity.
383
+ s = repr(td)
384
+ self.failUnless(s.startswith('datetime.'))
385
+ s = s[9:]
386
+ td2 = eval(s)
387
+ self.assertEqual(td, td2)
388
+
389
+ # Verify identity via reconstructing from pieces.
390
+ td2 = timedelta(td.days, td.seconds, td.microseconds)
391
+ self.assertEqual(td, td2)
392
+
393
+ def test_resolution_info(self):
394
+ self.assert_(isinstance(timedelta.min, timedelta))
395
+ self.assert_(isinstance(timedelta.max, timedelta))
396
+ self.assert_(isinstance(timedelta.resolution, timedelta))
397
+ self.assert_(timedelta.max > timedelta.min)
398
+ self.assertEqual(timedelta.min, timedelta(-999999999))
399
+ self.assertEqual(timedelta.max, timedelta(999999999, 24*3600-1, 1e6-1))
400
+ self.assertEqual(timedelta.resolution, timedelta(0, 0, 1))
401
+
402
+ def test_overflow(self):
403
+ tiny = timedelta.resolution
404
+
405
+ td = timedelta.min + tiny
406
+ td -= tiny # no problem
407
+ self.assertRaises(OverflowError, td.__sub__, tiny)
408
+ self.assertRaises(OverflowError, td.__add__, -tiny)
409
+
410
+ td = timedelta.max - tiny
411
+ td += tiny # no problem
412
+ self.assertRaises(OverflowError, td.__add__, tiny)
413
+ self.assertRaises(OverflowError, td.__sub__, -tiny)
414
+
415
+ self.assertRaises(OverflowError, lambda: -timedelta.max)
416
+
417
+ def test_microsecond_rounding(self):
418
+ td = timedelta
419
+ eq = self.assertEqual
420
+
421
+ # Single-field rounding.
422
+ eq(td(milliseconds=0.4/1000), td(0)) # rounds to 0
423
+ eq(td(milliseconds=-0.4/1000), td(0)) # rounds to 0
424
+ eq(td(milliseconds=0.6/1000), td(microseconds=1))
425
+ eq(td(milliseconds=-0.6/1000), td(microseconds=-1))
426
+
427
+ # Rounding due to contributions from more than one field.
428
+ us_per_hour = 3600e6
429
+ us_per_day = us_per_hour * 24
430
+ eq(td(days=.4/us_per_day), td(0))
431
+ eq(td(hours=.2/us_per_hour), td(0))
432
+ eq(td(days=.4/us_per_day, hours=.2/us_per_hour), td(microseconds=1))
433
+
434
+ eq(td(days=-.4/us_per_day), td(0))
435
+ eq(td(hours=-.2/us_per_hour), td(0))
436
+ eq(td(days=-.4/us_per_day, hours=-.2/us_per_hour), td(microseconds=-1))
437
+
438
+ def test_massive_normalization(self):
439
+ td = timedelta(microseconds=-1)
440
+ self.assertEqual((td.days, td.seconds, td.microseconds),
441
+ (-1, 24*3600-1, 999999))
442
+
443
+ def test_bool(self):
444
+ self.failUnless(timedelta(1))
445
+ self.failUnless(timedelta(0, 1))
446
+ self.failUnless(timedelta(0, 0, 1))
447
+ self.failUnless(timedelta(microseconds=1))
448
+ self.failUnless(not timedelta(0))
449
+
450
+ #############################################################################
451
+ # date tests
452
+
453
+ class TestDateOnly(unittest.TestCase):
454
+ # Tests here won't pass if also run on datetime objects, so don't
455
+ # subclass this to test datetimes too.
456
+
457
+ def test_delta_non_days_ignored(self):
458
+ dt = date(2000, 1, 2)
459
+ delta = timedelta(days=1, hours=2, minutes=3, seconds=4,
460
+ microseconds=5)
461
+ days = timedelta(delta.days)
462
+ self.assertEqual(days, timedelta(1))
463
+
464
+ dt2 = dt + delta
465
+ self.assertEqual(dt2, dt + days)
466
+
467
+ dt2 = delta + dt
468
+ self.assertEqual(dt2, dt + days)
469
+
470
+ dt2 = dt - delta
471
+ self.assertEqual(dt2, dt - days)
472
+
473
+ delta = -delta
474
+ days = timedelta(delta.days)
475
+ self.assertEqual(days, timedelta(-2))
476
+
477
+ dt2 = dt + delta
478
+ self.assertEqual(dt2, dt + days)
479
+
480
+ dt2 = delta + dt
481
+ self.assertEqual(dt2, dt + days)
482
+
483
+ dt2 = dt - delta
484
+ self.assertEqual(dt2, dt - days)
485
+
486
+ class TestDate(HarmlessMixedComparison):
487
+ # Tests here should pass for both dates and datetimes, except for a
488
+ # few tests that TestDateTime overrides.
489
+
490
+ theclass = date
491
+
492
+ def test_basic_attributes(self):
493
+ dt = self.theclass(2002, 3, 1)
494
+ self.assertEqual(dt.year, 2002)
495
+ self.assertEqual(dt.month, 3)
496
+ self.assertEqual(dt.day, 1)
497
+
498
+ def test_roundtrip(self):
499
+ for dt in (self.theclass(1, 2, 3),
500
+ self.theclass.today()):
501
+ # Verify dt -> string -> date identity.
502
+ s = repr(dt)
503
+ self.failUnless(s.startswith('datetime.'))
504
+ s = s[9:]
505
+ dt2 = eval(s)
506
+ self.assertEqual(dt, dt2)
507
+
508
+ # Verify identity via reconstructing from pieces.
509
+ dt2 = self.theclass(dt.year, dt.month, dt.day)
510
+ self.assertEqual(dt, dt2)
511
+
512
+ def test_ordinal_conversions(self):
513
+ # Check some fixed values.
514
+ for y, m, d, n in [(1, 1, 1, 1), # calendar origin
515
+ (1, 12, 31, 365),
516
+ (2, 1, 1, 366),
517
+ # first example from "Calendrical Calculations"
518
+ (1945, 11, 12, 710347)]:
519
+ d = self.theclass(y, m, d)
520
+ self.assertEqual(n, d.toordinal())
521
+ fromord = self.theclass.fromordinal(n)
522
+ self.assertEqual(d, fromord)
523
+ if hasattr(fromord, "hour"):
524
+ # if we're checking something fancier than a date, verify
525
+ # the extra fields have been zeroed out
526
+ self.assertEqual(fromord.hour, 0)
527
+ self.assertEqual(fromord.minute, 0)
528
+ self.assertEqual(fromord.second, 0)
529
+ self.assertEqual(fromord.microsecond, 0)
530
+
531
+ # Check first and last days of year spottily across the whole
532
+ # range of years supported.
533
+ for year in xrange(MINYEAR, MAXYEAR+1, 7):
534
+ # Verify (year, 1, 1) -> ordinal -> y, m, d is identity.
535
+ d = self.theclass(year, 1, 1)
536
+ n = d.toordinal()
537
+ d2 = self.theclass.fromordinal(n)
538
+ self.assertEqual(d, d2)
539
+ # Verify that moving back a day gets to the end of year-1.
540
+ if year > 1:
541
+ d = self.theclass.fromordinal(n-1)
542
+ d2 = self.theclass(year-1, 12, 31)
543
+ self.assertEqual(d, d2)
544
+ self.assertEqual(d2.toordinal(), n-1)
545
+
546
+ # Test every day in a leap-year and a non-leap year.
547
+ dim = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
548
+ for year, isleap in (2000, True), (2002, False):
549
+ n = self.theclass(year, 1, 1).toordinal()
550
+ for month, maxday in zip(range(1, 13), dim):
551
+ if month == 2 and isleap:
552
+ maxday += 1
553
+ for day in range(1, maxday+1):
554
+ d = self.theclass(year, month, day)
555
+ self.assertEqual(d.toordinal(), n)
556
+ self.assertEqual(d, self.theclass.fromordinal(n))
557
+ n += 1
558
+
559
+ def test_extreme_ordinals(self):
560
+ a = self.theclass.min
561
+ a = self.theclass(a.year, a.month, a.day) # get rid of time parts
562
+ aord = a.toordinal()
563
+ b = a.fromordinal(aord)
564
+ self.assertEqual(a, b)
565
+
566
+ self.assertRaises(ValueError, lambda: a.fromordinal(aord - 1))
567
+
568
+ b = a + timedelta(days=1)
569
+ self.assertEqual(b.toordinal(), aord + 1)
570
+ self.assertEqual(b, self.theclass.fromordinal(aord + 1))
571
+
572
+ a = self.theclass.max
573
+ a = self.theclass(a.year, a.month, a.day) # get rid of time parts
574
+ aord = a.toordinal()
575
+ b = a.fromordinal(aord)
576
+ self.assertEqual(a, b)
577
+
578
+ self.assertRaises(ValueError, lambda: a.fromordinal(aord + 1))
579
+
580
+ b = a - timedelta(days=1)
581
+ self.assertEqual(b.toordinal(), aord - 1)
582
+ self.assertEqual(b, self.theclass.fromordinal(aord - 1))
583
+
584
+ def test_bad_constructor_arguments(self):
585
+ # bad years
586
+ self.theclass(MINYEAR, 1, 1) # no exception
587
+ self.theclass(MAXYEAR, 1, 1) # no exception
588
+ self.assertRaises(ValueError, self.theclass, MINYEAR-1, 1, 1)
589
+ self.assertRaises(ValueError, self.theclass, MAXYEAR+1, 1, 1)
590
+ # bad months
591
+ self.theclass(2000, 1, 1) # no exception
592
+ self.theclass(2000, 12, 1) # no exception
593
+ self.assertRaises(ValueError, self.theclass, 2000, 0, 1)
594
+ self.assertRaises(ValueError, self.theclass, 2000, 13, 1)
595
+ # bad days
596
+ self.theclass(2000, 2, 29) # no exception
597
+ self.theclass(2004, 2, 29) # no exception
598
+ self.theclass(2400, 2, 29) # no exception
599
+ self.assertRaises(ValueError, self.theclass, 2000, 2, 30)
600
+ self.assertRaises(ValueError, self.theclass, 2001, 2, 29)
601
+ self.assertRaises(ValueError, self.theclass, 2100, 2, 29)
602
+ self.assertRaises(ValueError, self.theclass, 1900, 2, 29)
603
+ self.assertRaises(ValueError, self.theclass, 2000, 1, 0)
604
+ self.assertRaises(ValueError, self.theclass, 2000, 1, 32)
605
+
606
+ def test_hash_equality(self):
607
+ d = self.theclass(2000, 12, 31)
608
+ # same thing
609
+ e = self.theclass(2000, 12, 31)
610
+ self.assertEqual(d, e)
611
+ self.assertEqual(hash(d), hash(e))
612
+
613
+ dic = {d: 1}
614
+ dic[e] = 2
615
+ self.assertEqual(len(dic), 1)
616
+ self.assertEqual(dic[d], 2)
617
+ self.assertEqual(dic[e], 2)
618
+
619
+ d = self.theclass(2001, 1, 1)
620
+ # same thing
621
+ e = self.theclass(2001, 1, 1)
622
+ self.assertEqual(d, e)
623
+ self.assertEqual(hash(d), hash(e))
624
+
625
+ dic = {d: 1}
626
+ dic[e] = 2
627
+ self.assertEqual(len(dic), 1)
628
+ self.assertEqual(dic[d], 2)
629
+ self.assertEqual(dic[e], 2)
630
+
631
+ def test_computations(self):
632
+ a = self.theclass(2002, 1, 31)
633
+ b = self.theclass(1956, 1, 31)
634
+
635
+ diff = a-b
636
+ self.assertEqual(diff.days, 46*365 + len(range(1956, 2002, 4)))
637
+ self.assertEqual(diff.seconds, 0)
638
+ self.assertEqual(diff.microseconds, 0)
639
+
640
+ day = timedelta(1)
641
+ week = timedelta(7)
642
+ a = self.theclass(2002, 3, 2)
643
+ self.assertEqual(a + day, self.theclass(2002, 3, 3))
644
+ self.assertEqual(day + a, self.theclass(2002, 3, 3))
645
+ self.assertEqual(a - day, self.theclass(2002, 3, 1))
646
+ self.assertEqual(-day + a, self.theclass(2002, 3, 1))
647
+ self.assertEqual(a + week, self.theclass(2002, 3, 9))
648
+ self.assertEqual(a - week, self.theclass(2002, 2, 23))
649
+ self.assertEqual(a + 52*week, self.theclass(2003, 3, 1))
650
+ self.assertEqual(a - 52*week, self.theclass(2001, 3, 3))
651
+ self.assertEqual((a + week) - a, week)
652
+ self.assertEqual((a + day) - a, day)
653
+ self.assertEqual((a - week) - a, -week)
654
+ self.assertEqual((a - day) - a, -day)
655
+ self.assertEqual(a - (a + week), -week)
656
+ self.assertEqual(a - (a + day), -day)
657
+ self.assertEqual(a - (a - week), week)
658
+ self.assertEqual(a - (a - day), day)
659
+
660
+ # Add/sub ints, longs, floats should be illegal
661
+ for i in 1, 1L, 1.0:
662
+ self.assertRaises(TypeError, lambda: a+i)
663
+ self.assertRaises(TypeError, lambda: a-i)
664
+ self.assertRaises(TypeError, lambda: i+a)
665
+ self.assertRaises(TypeError, lambda: i-a)
666
+
667
+ # delta - date is senseless.
668
+ self.assertRaises(TypeError, lambda: day - a)
669
+ # mixing date and (delta or date) via * or // is senseless
670
+ self.assertRaises(TypeError, lambda: day * a)
671
+ self.assertRaises(TypeError, lambda: a * day)
672
+ self.assertRaises(TypeError, lambda: day // a)
673
+ self.assertRaises(TypeError, lambda: a // day)
674
+ self.assertRaises(TypeError, lambda: a * a)
675
+ self.assertRaises(TypeError, lambda: a // a)
676
+ # date + date is senseless
677
+ self.assertRaises(TypeError, lambda: a + a)
678
+
679
+ def test_overflow(self):
680
+ tiny = self.theclass.resolution
681
+
682
+ dt = self.theclass.min + tiny
683
+ dt -= tiny # no problem
684
+ self.assertRaises(OverflowError, dt.__sub__, tiny)
685
+ self.assertRaises(OverflowError, dt.__add__, -tiny)
686
+
687
+ dt = self.theclass.max - tiny
688
+ dt += tiny # no problem
689
+ self.assertRaises(OverflowError, dt.__add__, tiny)
690
+ self.assertRaises(OverflowError, dt.__sub__, -tiny)
691
+
692
+ def test_fromtimestamp(self):
693
+ import time
694
+
695
+ # Try an arbitrary fixed value.
696
+ year, month, day = 1999, 9, 19
697
+ ts = time.mktime((year, month, day, 0, 0, 0, 0, 0, -1))
698
+ d = self.theclass.fromtimestamp(ts)
699
+ self.assertEqual(d.year, year)
700
+ self.assertEqual(d.month, month)
701
+ self.assertEqual(d.day, day)
702
+
703
+ def test_today(self):
704
+ import time
705
+
706
+ # We claim that today() is like fromtimestamp(time.time()), so
707
+ # prove it.
708
+ for dummy in range(3):
709
+ today = self.theclass.today()
710
+ ts = time.time()
711
+ todayagain = self.theclass.fromtimestamp(ts)
712
+ if today == todayagain:
713
+ break
714
+ # There are several legit reasons that could fail:
715
+ # 1. It recently became midnight, between the today() and the
716
+ # time() calls.
717
+ # 2. The platform time() has such fine resolution that we'll
718
+ # never get the same value twice.
719
+ # 3. The platform time() has poor resolution, and we just
720
+ # happened to call today() right before a resolution quantum
721
+ # boundary.
722
+ # 4. The system clock got fiddled between calls.
723
+ # In any case, wait a little while and try again.
724
+ time.sleep(0.1)
725
+
726
+ # It worked or it didn't. If it didn't, assume it's reason #2, and
727
+ # let the test pass if they're within half a second of each other.
728
+ self.failUnless(today == todayagain or
729
+ abs(todayagain - today) < timedelta(seconds=0.5))
730
+
731
+ def test_weekday(self):
732
+ for i in range(7):
733
+ # March 4, 2002 is a Monday
734
+ self.assertEqual(self.theclass(2002, 3, 4+i).weekday(), i)
735
+ self.assertEqual(self.theclass(2002, 3, 4+i).isoweekday(), i+1)
736
+ # January 2, 1956 is a Monday
737
+ self.assertEqual(self.theclass(1956, 1, 2+i).weekday(), i)
738
+ self.assertEqual(self.theclass(1956, 1, 2+i).isoweekday(), i+1)
739
+
740
+ def test_isocalendar(self):
741
+ # Check examples from
742
+ # http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
743
+ for i in range(7):
744
+ d = self.theclass(2003, 12, 22+i)
745
+ self.assertEqual(d.isocalendar(), (2003, 52, i+1))
746
+ d = self.theclass(2003, 12, 29) + timedelta(i)
747
+ self.assertEqual(d.isocalendar(), (2004, 1, i+1))
748
+ d = self.theclass(2004, 1, 5+i)
749
+ self.assertEqual(d.isocalendar(), (2004, 2, i+1))
750
+ d = self.theclass(2009, 12, 21+i)
751
+ self.assertEqual(d.isocalendar(), (2009, 52, i+1))
752
+ d = self.theclass(2009, 12, 28) + timedelta(i)
753
+ self.assertEqual(d.isocalendar(), (2009, 53, i+1))
754
+ d = self.theclass(2010, 1, 4+i)
755
+ self.assertEqual(d.isocalendar(), (2010, 1, i+1))
756
+
757
+ def test_iso_long_years(self):
758
+ # Calculate long ISO years and compare to table from
759
+ # http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
760
+ ISO_LONG_YEARS_TABLE = """
761
+ 4 32 60 88
762
+ 9 37 65 93
763
+ 15 43 71 99
764
+ 20 48 76
765
+ 26 54 82
766
+
767
+ 105 133 161 189
768
+ 111 139 167 195
769
+ 116 144 172
770
+ 122 150 178
771
+ 128 156 184
772
+
773
+ 201 229 257 285
774
+ 207 235 263 291
775
+ 212 240 268 296
776
+ 218 246 274
777
+ 224 252 280
778
+
779
+ 303 331 359 387
780
+ 308 336 364 392
781
+ 314 342 370 398
782
+ 320 348 376
783
+ 325 353 381
784
+ """
785
+ iso_long_years = map(int, ISO_LONG_YEARS_TABLE.split())
786
+ iso_long_years.sort()
787
+ L = []
788
+ for i in range(400):
789
+ d = self.theclass(2000+i, 12, 31)
790
+ d1 = self.theclass(1600+i, 12, 31)
791
+ self.assertEqual(d.isocalendar()[1:], d1.isocalendar()[1:])
792
+ if d.isocalendar()[1] == 53:
793
+ L.append(i)
794
+ self.assertEqual(L, iso_long_years)
795
+
796
+ def test_isoformat(self):
797
+ t = self.theclass(2, 3, 2)
798
+ self.assertEqual(t.isoformat(), "0002-03-02")
799
+
800
+ def test_ctime(self):
801
+ t = self.theclass(2002, 3, 2)
802
+ self.assertEqual(t.ctime(), "Sat Mar 2 00:00:00 2002")
803
+
804
+ def test_strftime(self):
805
+ t = self.theclass(2005, 3, 2)
806
+ self.assertEqual(t.strftime("m:%m d:%d y:%y"), "m:03 d:02 y:05")
807
+
808
+ self.assertRaises(TypeError, t.strftime) # needs an arg
809
+ self.assertRaises(TypeError, t.strftime, "one", "two") # too many args
810
+ self.assertRaises(TypeError, t.strftime, 42) # arg wrong type
811
+
812
+ # A naive object replaces %z and %Z w/ empty strings.
813
+ self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
814
+
815
+ def test_resolution_info(self):
816
+ self.assert_(isinstance(self.theclass.min, self.theclass))
817
+ self.assert_(isinstance(self.theclass.max, self.theclass))
818
+ self.assert_(isinstance(self.theclass.resolution, timedelta))
819
+ self.assert_(self.theclass.max > self.theclass.min)
820
+
821
+ def test_extreme_timedelta(self):
822
+ big = self.theclass.max - self.theclass.min
823
+ # 3652058 days, 23 hours, 59 minutes, 59 seconds, 999999 microseconds
824
+ n = (big.days*24*3600 + big.seconds)*1000000 + big.microseconds
825
+ # n == 315537897599999999 ~= 2**58.13
826
+ justasbig = timedelta(0, 0, n)
827
+ self.assertEqual(big, justasbig)
828
+ self.assertEqual(self.theclass.min + big, self.theclass.max)
829
+ self.assertEqual(self.theclass.max - big, self.theclass.min)
830
+
831
+ def test_timetuple(self):
832
+ for i in range(7):
833
+ # January 2, 1956 is a Monday (0)
834
+ d = self.theclass(1956, 1, 2+i)
835
+ t = d.timetuple()
836
+ self.assertEqual(t, (1956, 1, 2+i, 0, 0, 0, i, 2+i, -1))
837
+ # February 1, 1956 is a Wednesday (2)
838
+ d = self.theclass(1956, 2, 1+i)
839
+ t = d.timetuple()
840
+ self.assertEqual(t, (1956, 2, 1+i, 0, 0, 0, (2+i)%7, 32+i, -1))
841
+ # March 1, 1956 is a Thursday (3), and is the 31+29+1 = 61st day
842
+ # of the year.
843
+ d = self.theclass(1956, 3, 1+i)
844
+ t = d.timetuple()
845
+ self.assertEqual(t, (1956, 3, 1+i, 0, 0, 0, (3+i)%7, 61+i, -1))
846
+ self.assertEqual(t.tm_year, 1956)
847
+ self.assertEqual(t.tm_mon, 3)
848
+ self.assertEqual(t.tm_mday, 1+i)
849
+ self.assertEqual(t.tm_hour, 0)
850
+ self.assertEqual(t.tm_min, 0)
851
+ self.assertEqual(t.tm_sec, 0)
852
+ self.assertEqual(t.tm_wday, (3+i)%7)
853
+ self.assertEqual(t.tm_yday, 61+i)
854
+ self.assertEqual(t.tm_isdst, -1)
855
+
856
+ #XXX: pickling not working for jython yet.
857
+ def test_pickling(self):
858
+ args = 6, 7, 23
859
+ orig = self.theclass(*args)
860
+ for pickler, unpickler, proto in pickle_choices:
861
+ green = pickler.dumps(orig, proto)
862
+ derived = unpickler.loads(green)
863
+ self.assertEqual(orig, derived)
864
+
865
+ def test_compare(self):
866
+ t1 = self.theclass(2, 3, 4)
867
+ t2 = self.theclass(2, 3, 4)
868
+ self.failUnless(t1 == t2)
869
+ self.failUnless(t1 <= t2)
870
+ self.failUnless(t1 >= t2)
871
+ self.failUnless(not t1 != t2)
872
+ self.failUnless(not t1 < t2)
873
+ self.failUnless(not t1 > t2)
874
+ self.assertEqual(cmp(t1, t2), 0)
875
+ self.assertEqual(cmp(t2, t1), 0)
876
+
877
+ for args in (3, 3, 3), (2, 4, 4), (2, 3, 5):
878
+ t2 = self.theclass(*args) # this is larger than t1
879
+ self.failUnless(t1 < t2)
880
+ self.failUnless(t2 > t1)
881
+ self.failUnless(t1 <= t2)
882
+ self.failUnless(t2 >= t1)
883
+ self.failUnless(t1 != t2)
884
+ self.failUnless(t2 != t1)
885
+ self.failUnless(not t1 == t2)
886
+ self.failUnless(not t2 == t1)
887
+ self.failUnless(not t1 > t2)
888
+ self.failUnless(not t2 < t1)
889
+ self.failUnless(not t1 >= t2)
890
+ self.failUnless(not t2 <= t1)
891
+ self.assertEqual(cmp(t1, t2), -1)
892
+ self.assertEqual(cmp(t2, t1), 1)
893
+
894
+ for badarg in OTHERSTUFF:
895
+ self.assertEqual(t1 == badarg, False)
896
+ self.assertEqual(t1 != badarg, True)
897
+ self.assertEqual(badarg == t1, False)
898
+ self.assertEqual(badarg != t1, True)
899
+
900
+ self.assertRaises(TypeError, lambda: t1 < badarg)
901
+ self.assertRaises(TypeError, lambda: t1 > badarg)
902
+ self.assertRaises(TypeError, lambda: t1 >= badarg)
903
+ self.assertRaises(TypeError, lambda: badarg <= t1)
904
+ self.assertRaises(TypeError, lambda: badarg < t1)
905
+ self.assertRaises(TypeError, lambda: badarg > t1)
906
+ self.assertRaises(TypeError, lambda: badarg >= t1)
907
+
908
+ def test_mixed_compare(self):
909
+ our = self.theclass(2000, 4, 5)
910
+ self.assertRaises(TypeError, cmp, our, 1)
911
+ self.assertRaises(TypeError, cmp, 1, our)
912
+
913
+ class AnotherDateTimeClass(object):
914
+ def __cmp__(self, other):
915
+ # Return "equal" so calling this can't be confused with
916
+ # compare-by-address (which never says "equal" for distinct
917
+ # objects).
918
+ return 0
919
+
920
+ # This still errors, because date and datetime comparison raise
921
+ # TypeError instead of NotImplemented when they don't know what to
922
+ # do, in order to stop comparison from falling back to the default
923
+ # compare-by-address.
924
+ their = AnotherDateTimeClass()
925
+ self.assertRaises(TypeError, cmp, our, their)
926
+ # Oops: The next stab raises TypeError in the C implementation,
927
+ # but not in the Python implementation of datetime. The difference
928
+ # is due to that the Python implementation defines __cmp__ but
929
+ # the C implementation defines tp_richcompare. This is more pain
930
+ # to fix than it's worth, so commenting out the test.
931
+ # self.assertEqual(cmp(their, our), 0)
932
+
933
+ # But date and datetime comparison return NotImplemented instead if the
934
+ # other object has a timetuple attr. This gives the other object a
935
+ # chance to do the comparison.
936
+ class Comparable(AnotherDateTimeClass):
937
+ def timetuple(self):
938
+ return ()
939
+
940
+ their = Comparable()
941
+ self.assertEqual(cmp(our, their), 0)
942
+ self.assertEqual(cmp(their, our), 0)
943
+ self.failUnless(our == their)
944
+ self.failUnless(their == our)
945
+
946
+ def test_bool(self):
947
+ # All dates are considered true.
948
+ self.failUnless(self.theclass.min)
949
+ self.failUnless(self.theclass.max)
950
+
951
+ def test_srftime_out_of_range(self):
952
+ # For nasty technical reasons, we can't handle years before 1900.
953
+ cls = self.theclass
954
+ self.assertEqual(cls(1900, 1, 1).strftime("%Y"), "1900")
955
+ for y in 1, 49, 51, 99, 100, 1000, 1899:
956
+ self.assertRaises(ValueError, cls(y, 1, 1).strftime, "%Y")
957
+
958
+ def test_replace(self):
959
+ cls = self.theclass
960
+ args = [1, 2, 3]
961
+ base = cls(*args)
962
+ self.assertEqual(base, base.replace())
963
+
964
+ i = 0
965
+ for name, newval in (("year", 2),
966
+ ("month", 3),
967
+ ("day", 4)):
968
+ newargs = args[:]
969
+ newargs[i] = newval
970
+ expected = cls(*newargs)
971
+ got = base.replace(**{name: newval})
972
+ self.assertEqual(expected, got)
973
+ i += 1
974
+
975
+ # Out of bounds.
976
+ base = cls(2000, 2, 29)
977
+ self.assertRaises(ValueError, base.replace, year=2001)
978
+
979
+ #############################################################################
980
+ # datetime tests
981
+
982
+ class TestDateTime(TestDate):
983
+
984
+ theclass = datetime
985
+
986
+ def test_basic_attributes(self):
987
+ dt = self.theclass(2002, 3, 1, 12, 0)
988
+ self.assertEqual(dt.year, 2002)
989
+ self.assertEqual(dt.month, 3)
990
+ self.assertEqual(dt.day, 1)
991
+ self.assertEqual(dt.hour, 12)
992
+ self.assertEqual(dt.minute, 0)
993
+ self.assertEqual(dt.second, 0)
994
+ self.assertEqual(dt.microsecond, 0)
995
+
996
+ def test_basic_attributes_nonzero(self):
997
+ # Make sure all attributes are non-zero so bugs in
998
+ # bit-shifting access show up.
999
+ dt = self.theclass(2002, 3, 1, 12, 59, 59, 8000)
1000
+ self.assertEqual(dt.year, 2002)
1001
+ self.assertEqual(dt.month, 3)
1002
+ self.assertEqual(dt.day, 1)
1003
+ self.assertEqual(dt.hour, 12)
1004
+ self.assertEqual(dt.minute, 59)
1005
+ self.assertEqual(dt.second, 59)
1006
+ self.assertEqual(dt.microsecond, 8000)
1007
+
1008
+ def test_roundtrip(self):
1009
+ for dt in (self.theclass(1, 2, 3, 4, 5, 6, 7),
1010
+ self.theclass.now()):
1011
+ # Verify dt -> string -> datetime identity.
1012
+ s = repr(dt)
1013
+ self.failUnless(s.startswith('datetime.'))
1014
+ s = s[9:]
1015
+ dt2 = eval(s)
1016
+ self.assertEqual(dt, dt2)
1017
+
1018
+ # Verify identity via reconstructing from pieces.
1019
+ dt2 = self.theclass(dt.year, dt.month, dt.day,
1020
+ dt.hour, dt.minute, dt.second,
1021
+ dt.microsecond)
1022
+ self.assertEqual(dt, dt2)
1023
+
1024
+ def test_isoformat(self):
1025
+ t = self.theclass(2, 3, 2, 4, 5, 1, 123)
1026
+ self.assertEqual(t.isoformat(), "0002-03-02T04:05:01.000123")
1027
+ self.assertEqual(t.isoformat('T'), "0002-03-02T04:05:01.000123")
1028
+ self.assertEqual(t.isoformat(' '), "0002-03-02 04:05:01.000123")
1029
+ # str is ISO format with the separator forced to a blank.
1030
+ self.assertEqual(str(t), "0002-03-02 04:05:01.000123")
1031
+
1032
+ t = self.theclass(2, 3, 2)
1033
+ self.assertEqual(t.isoformat(), "0002-03-02T00:00:00")
1034
+ self.assertEqual(t.isoformat('T'), "0002-03-02T00:00:00")
1035
+ self.assertEqual(t.isoformat(' '), "0002-03-02 00:00:00")
1036
+ # str is ISO format with the separator forced to a blank.
1037
+ self.assertEqual(str(t), "0002-03-02 00:00:00")
1038
+
1039
+ def test_more_ctime(self):
1040
+ # Test fields that TestDate doesn't touch.
1041
+ import time
1042
+
1043
+ t = self.theclass(2002, 3, 2, 18, 3, 5, 123)
1044
+ self.assertEqual(t.ctime(), "Sat Mar 2 18:03:05 2002")
1045
+ # Oops! The next line fails on Win2K under MSVC 6, so it's commented
1046
+ # out. The difference is that t.ctime() produces " 2" for the day,
1047
+ # but platform ctime() produces "02" for the day. According to
1048
+ # C99, t.ctime() is correct here.
1049
+ # self.assertEqual(t.ctime(), time.ctime(time.mktime(t.timetuple())))
1050
+
1051
+ # So test a case where that difference doesn't matter.
1052
+ t = self.theclass(2002, 3, 22, 18, 3, 5, 123)
1053
+ self.assertEqual(t.ctime(), time.ctime(time.mktime(t.timetuple())))
1054
+
1055
+ def test_tz_independent_comparing(self):
1056
+ dt1 = self.theclass(2002, 3, 1, 9, 0, 0)
1057
+ dt2 = self.theclass(2002, 3, 1, 10, 0, 0)
1058
+ dt3 = self.theclass(2002, 3, 1, 9, 0, 0)
1059
+ self.assertEqual(dt1, dt3)
1060
+ self.assert_(dt2 > dt3)
1061
+
1062
+ # Make sure comparison doesn't forget microseconds, and isn't done
1063
+ # via comparing a float timestamp (an IEEE double doesn't have enough
1064
+ # precision to span microsecond resolution across years 1 thru 9999,
1065
+ # so comparing via timestamp necessarily calls some distinct values
1066
+ # equal).
1067
+ dt1 = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999998)
1068
+ us = timedelta(microseconds=1)
1069
+ dt2 = dt1 + us
1070
+ self.assertEqual(dt2 - dt1, us)
1071
+ self.assert_(dt1 < dt2)
1072
+
1073
+ def test_bad_constructor_arguments(self):
1074
+ # bad years
1075
+ self.theclass(MINYEAR, 1, 1) # no exception
1076
+ self.theclass(MAXYEAR, 1, 1) # no exception
1077
+ self.assertRaises(ValueError, self.theclass, MINYEAR-1, 1, 1)
1078
+ self.assertRaises(ValueError, self.theclass, MAXYEAR+1, 1, 1)
1079
+ # bad months
1080
+ self.theclass(2000, 1, 1) # no exception
1081
+ self.theclass(2000, 12, 1) # no exception
1082
+ self.assertRaises(ValueError, self.theclass, 2000, 0, 1)
1083
+ self.assertRaises(ValueError, self.theclass, 2000, 13, 1)
1084
+ # bad days
1085
+ self.theclass(2000, 2, 29) # no exception
1086
+ self.theclass(2004, 2, 29) # no exception
1087
+ self.theclass(2400, 2, 29) # no exception
1088
+ self.assertRaises(ValueError, self.theclass, 2000, 2, 30)
1089
+ self.assertRaises(ValueError, self.theclass, 2001, 2, 29)
1090
+ self.assertRaises(ValueError, self.theclass, 2100, 2, 29)
1091
+ self.assertRaises(ValueError, self.theclass, 1900, 2, 29)
1092
+ self.assertRaises(ValueError, self.theclass, 2000, 1, 0)
1093
+ self.assertRaises(ValueError, self.theclass, 2000, 1, 32)
1094
+ # bad hours
1095
+ self.theclass(2000, 1, 31, 0) # no exception
1096
+ self.theclass(2000, 1, 31, 23) # no exception
1097
+ self.assertRaises(ValueError, self.theclass, 2000, 1, 31, -1)
1098
+ self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 24)
1099
+ # bad minutes
1100
+ self.theclass(2000, 1, 31, 23, 0) # no exception
1101
+ self.theclass(2000, 1, 31, 23, 59) # no exception
1102
+ self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, -1)
1103
+ self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 60)
1104
+ # bad seconds
1105
+ self.theclass(2000, 1, 31, 23, 59, 0) # no exception
1106
+ self.theclass(2000, 1, 31, 23, 59, 59) # no exception
1107
+ self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 59, -1)
1108
+ self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 59, 60)
1109
+ # bad microseconds
1110
+ self.theclass(2000, 1, 31, 23, 59, 59, 0) # no exception
1111
+ self.theclass(2000, 1, 31, 23, 59, 59, 999999) # no exception
1112
+ self.assertRaises(ValueError, self.theclass,
1113
+ 2000, 1, 31, 23, 59, 59, -1)
1114
+ self.assertRaises(ValueError, self.theclass,
1115
+ 2000, 1, 31, 23, 59, 59,
1116
+ 1000000)
1117
+
1118
+ def test_hash_equality(self):
1119
+ d = self.theclass(2000, 12, 31, 23, 30, 17)
1120
+ e = self.theclass(2000, 12, 31, 23, 30, 17)
1121
+ self.assertEqual(d, e)
1122
+ self.assertEqual(hash(d), hash(e))
1123
+
1124
+ dic = {d: 1}
1125
+ dic[e] = 2
1126
+ self.assertEqual(len(dic), 1)
1127
+ self.assertEqual(dic[d], 2)
1128
+ self.assertEqual(dic[e], 2)
1129
+
1130
+ d = self.theclass(2001, 1, 1, 0, 5, 17)
1131
+ e = self.theclass(2001, 1, 1, 0, 5, 17)
1132
+ self.assertEqual(d, e)
1133
+ self.assertEqual(hash(d), hash(e))
1134
+
1135
+ dic = {d: 1}
1136
+ dic[e] = 2
1137
+ self.assertEqual(len(dic), 1)
1138
+ self.assertEqual(dic[d], 2)
1139
+ self.assertEqual(dic[e], 2)
1140
+
1141
+ def test_computations(self):
1142
+ a = self.theclass(2002, 1, 31)
1143
+ b = self.theclass(1956, 1, 31)
1144
+ diff = a-b
1145
+ self.assertEqual(diff.days, 46*365 + len(range(1956, 2002, 4)))
1146
+ self.assertEqual(diff.seconds, 0)
1147
+ self.assertEqual(diff.microseconds, 0)
1148
+ a = self.theclass(2002, 3, 2, 17, 6)
1149
+ millisec = timedelta(0, 0, 1000)
1150
+ hour = timedelta(0, 3600)
1151
+ day = timedelta(1)
1152
+ week = timedelta(7)
1153
+ self.assertEqual(a + hour, self.theclass(2002, 3, 2, 18, 6))
1154
+ self.assertEqual(hour + a, self.theclass(2002, 3, 2, 18, 6))
1155
+ self.assertEqual(a + 10*hour, self.theclass(2002, 3, 3, 3, 6))
1156
+ self.assertEqual(a - hour, self.theclass(2002, 3, 2, 16, 6))
1157
+ self.assertEqual(-hour + a, self.theclass(2002, 3, 2, 16, 6))
1158
+ self.assertEqual(a - hour, a + -hour)
1159
+ self.assertEqual(a - 20*hour, self.theclass(2002, 3, 1, 21, 6))
1160
+ self.assertEqual(a + day, self.theclass(2002, 3, 3, 17, 6))
1161
+ self.assertEqual(a - day, self.theclass(2002, 3, 1, 17, 6))
1162
+ self.assertEqual(a + week, self.theclass(2002, 3, 9, 17, 6))
1163
+ self.assertEqual(a - week, self.theclass(2002, 2, 23, 17, 6))
1164
+ self.assertEqual(a + 52*week, self.theclass(2003, 3, 1, 17, 6))
1165
+ self.assertEqual(a - 52*week, self.theclass(2001, 3, 3, 17, 6))
1166
+ self.assertEqual((a + week) - a, week)
1167
+ self.assertEqual((a + day) - a, day)
1168
+ self.assertEqual((a + hour) - a, hour)
1169
+ self.assertEqual((a + millisec) - a, millisec)
1170
+ self.assertEqual((a - week) - a, -week)
1171
+ self.assertEqual((a - day) - a, -day)
1172
+ self.assertEqual((a - hour) - a, -hour)
1173
+ self.assertEqual((a - millisec) - a, -millisec)
1174
+ self.assertEqual(a - (a + week), -week)
1175
+ self.assertEqual(a - (a + day), -day)
1176
+ self.assertEqual(a - (a + hour), -hour)
1177
+ self.assertEqual(a - (a + millisec), -millisec)
1178
+ self.assertEqual(a - (a - week), week)
1179
+ self.assertEqual(a - (a - day), day)
1180
+ self.assertEqual(a - (a - hour), hour)
1181
+ self.assertEqual(a - (a - millisec), millisec)
1182
+ self.assertEqual(a + (week + day + hour + millisec),
1183
+ self.theclass(2002, 3, 10, 18, 6, 0, 1000))
1184
+ self.assertEqual(a + (week + day + hour + millisec),
1185
+ (((a + week) + day) + hour) + millisec)
1186
+ self.assertEqual(a - (week + day + hour + millisec),
1187
+ self.theclass(2002, 2, 22, 16, 5, 59, 999000))
1188
+ self.assertEqual(a - (week + day + hour + millisec),
1189
+ (((a - week) - day) - hour) - millisec)
1190
+ # Add/sub ints, longs, floats should be illegal
1191
+ for i in 1, 1L, 1.0:
1192
+ self.assertRaises(TypeError, lambda: a+i)
1193
+ self.assertRaises(TypeError, lambda: a-i)
1194
+ self.assertRaises(TypeError, lambda: i+a)
1195
+ self.assertRaises(TypeError, lambda: i-a)
1196
+
1197
+ # delta - datetime is senseless.
1198
+ self.assertRaises(TypeError, lambda: day - a)
1199
+ # mixing datetime and (delta or datetime) via * or // is senseless
1200
+ self.assertRaises(TypeError, lambda: day * a)
1201
+ self.assertRaises(TypeError, lambda: a * day)
1202
+ self.assertRaises(TypeError, lambda: day // a)
1203
+ self.assertRaises(TypeError, lambda: a // day)
1204
+ self.assertRaises(TypeError, lambda: a * a)
1205
+ self.assertRaises(TypeError, lambda: a // a)
1206
+ # datetime + datetime is senseless
1207
+ self.assertRaises(TypeError, lambda: a + a)
1208
+
1209
+ #XXX: pickling not working for jython yet.
1210
+ def test_pickling(self):
1211
+ args = 6, 7, 23, 20, 59, 1, 64**2
1212
+ orig = self.theclass(*args)
1213
+ for pickler, unpickler, proto in pickle_choices:
1214
+ green = pickler.dumps(orig, proto)
1215
+ derived = unpickler.loads(green)
1216
+ self.assertEqual(orig, derived)
1217
+
1218
+ #XXX: pickling not working for jython yet.
1219
+ def test_more_pickling(self):
1220
+ a = self.theclass(2003, 2, 7, 16, 48, 37, 444116)
1221
+ s = pickle.dumps(a)
1222
+ b = pickle.loads(s)
1223
+ self.assertEqual(b.year, 2003)
1224
+ self.assertEqual(b.month, 2)
1225
+ self.assertEqual(b.day, 7)
1226
+
1227
+ def test_more_compare(self):
1228
+ # The test_compare() inherited from TestDate covers the error cases.
1229
+ # We just want to test lexicographic ordering on the members datetime
1230
+ # has that date lacks.
1231
+ args = [2000, 11, 29, 20, 58, 16, 999998]
1232
+ t1 = self.theclass(*args)
1233
+ t2 = self.theclass(*args)
1234
+ self.failUnless(t1 == t2)
1235
+ self.failUnless(t1 <= t2)
1236
+ self.failUnless(t1 >= t2)
1237
+ self.failUnless(not t1 != t2)
1238
+ self.failUnless(not t1 < t2)
1239
+ self.failUnless(not t1 > t2)
1240
+ self.assertEqual(cmp(t1, t2), 0)
1241
+ self.assertEqual(cmp(t2, t1), 0)
1242
+
1243
+ for i in range(len(args)):
1244
+ newargs = args[:]
1245
+ newargs[i] = args[i] + 1
1246
+ t2 = self.theclass(*newargs) # this is larger than t1
1247
+ self.failUnless(t1 < t2)
1248
+ self.failUnless(t2 > t1)
1249
+ self.failUnless(t1 <= t2)
1250
+ self.failUnless(t2 >= t1)
1251
+ self.failUnless(t1 != t2)
1252
+ self.failUnless(t2 != t1)
1253
+ self.failUnless(not t1 == t2)
1254
+ self.failUnless(not t2 == t1)
1255
+ self.failUnless(not t1 > t2)
1256
+ self.failUnless(not t2 < t1)
1257
+ self.failUnless(not t1 >= t2)
1258
+ self.failUnless(not t2 <= t1)
1259
+ self.assertEqual(cmp(t1, t2), -1)
1260
+ self.assertEqual(cmp(t2, t1), 1)
1261
+
1262
+
1263
+ # A helper for timestamp constructor tests.
1264
+ def verify_field_equality(self, expected, got):
1265
+ self.assertEqual(expected.tm_year, got.year)
1266
+ self.assertEqual(expected.tm_mon, got.month)
1267
+ self.assertEqual(expected.tm_mday, got.day)
1268
+ self.assertEqual(expected.tm_hour, got.hour)
1269
+ self.assertEqual(expected.tm_min, got.minute)
1270
+ self.assertEqual(expected.tm_sec, got.second)
1271
+
1272
+ def test_fromtimestamp(self):
1273
+ import time
1274
+
1275
+ ts = time.time()
1276
+ expected = time.localtime(ts)
1277
+ got = self.theclass.fromtimestamp(ts)
1278
+ self.verify_field_equality(expected, got)
1279
+
1280
+ def test_utcfromtimestamp(self):
1281
+ import time
1282
+
1283
+ ts = time.time()
1284
+ expected = time.gmtime(ts)
1285
+ got = self.theclass.utcfromtimestamp(ts)
1286
+ self.verify_field_equality(expected, got)
1287
+
1288
+ def test_utcnow(self):
1289
+ import time
1290
+
1291
+ # Call it a success if utcnow() and utcfromtimestamp() are within
1292
+ # a second of each other.
1293
+ tolerance = timedelta(seconds=1)
1294
+ for dummy in range(3):
1295
+ from_now = self.theclass.utcnow()
1296
+ from_timestamp = self.theclass.utcfromtimestamp(time.time())
1297
+ if abs(from_timestamp - from_now) <= tolerance:
1298
+ break
1299
+ # Else try again a few times.
1300
+ self.failUnless(abs(from_timestamp - from_now) <= tolerance)
1301
+
1302
+ def test_more_timetuple(self):
1303
+ # This tests fields beyond those tested by the TestDate.test_timetuple.
1304
+ t = self.theclass(2004, 12, 31, 6, 22, 33)
1305
+ self.assertEqual(t.timetuple(), (2004, 12, 31, 6, 22, 33, 4, 366, -1))
1306
+ self.assertEqual(t.timetuple(),
1307
+ (t.year, t.month, t.day,
1308
+ t.hour, t.minute, t.second,
1309
+ t.weekday(),
1310
+ t.toordinal() - date(t.year, 1, 1).toordinal() + 1,
1311
+ -1))
1312
+ tt = t.timetuple()
1313
+ self.assertEqual(tt.tm_year, t.year)
1314
+ self.assertEqual(tt.tm_mon, t.month)
1315
+ self.assertEqual(tt.tm_mday, t.day)
1316
+ self.assertEqual(tt.tm_hour, t.hour)
1317
+ self.assertEqual(tt.tm_min, t.minute)
1318
+ self.assertEqual(tt.tm_sec, t.second)
1319
+ self.assertEqual(tt.tm_wday, t.weekday())
1320
+ self.assertEqual(tt.tm_yday, t.toordinal() -
1321
+ date(t.year, 1, 1).toordinal() + 1)
1322
+ self.assertEqual(tt.tm_isdst, -1)
1323
+
1324
+ def test_more_strftime(self):
1325
+ # This tests fields beyond those tested by the TestDate.test_strftime.
1326
+ t = self.theclass(2004, 12, 31, 6, 22, 33)
1327
+ self.assertEqual(t.strftime("%m %d %y %S %M %H %j"),
1328
+ "12 31 04 33 22 06 366")
1329
+
1330
+ def test_extract(self):
1331
+ dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
1332
+ self.assertEqual(dt.date(), date(2002, 3, 4))
1333
+ self.assertEqual(dt.time(), time(18, 45, 3, 1234))
1334
+
1335
+ def test_combine(self):
1336
+ d = date(2002, 3, 4)
1337
+ t = time(18, 45, 3, 1234)
1338
+ expected = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
1339
+ combine = self.theclass.combine
1340
+ dt = combine(d, t)
1341
+ self.assertEqual(dt, expected)
1342
+
1343
+ dt = combine(time=t, date=d)
1344
+ self.assertEqual(dt, expected)
1345
+
1346
+ self.assertEqual(d, dt.date())
1347
+ self.assertEqual(t, dt.time())
1348
+ self.assertEqual(dt, combine(dt.date(), dt.time()))
1349
+
1350
+ self.assertRaises(TypeError, combine) # need an arg
1351
+ self.assertRaises(TypeError, combine, d) # need two args
1352
+ self.assertRaises(TypeError, combine, t, d) # args reversed
1353
+ self.assertRaises(TypeError, combine, d, t, 1) # too many args
1354
+ self.assertRaises(TypeError, combine, "date", "time") # wrong types
1355
+
1356
+ def test_replace(self):
1357
+ cls = self.theclass
1358
+ args = [1, 2, 3, 4, 5, 6, 7]
1359
+ base = cls(*args)
1360
+ self.assertEqual(base, base.replace())
1361
+
1362
+ i = 0
1363
+ for name, newval in (("year", 2),
1364
+ ("month", 3),
1365
+ ("day", 4),
1366
+ ("hour", 5),
1367
+ ("minute", 6),
1368
+ ("second", 7),
1369
+ ("microsecond", 8)):
1370
+ newargs = args[:]
1371
+ newargs[i] = newval
1372
+ expected = cls(*newargs)
1373
+ got = base.replace(**{name: newval})
1374
+ self.assertEqual(expected, got)
1375
+ i += 1
1376
+
1377
+ # Out of bounds.
1378
+ base = cls(2000, 2, 29)
1379
+ self.assertRaises(ValueError, base.replace, year=2001)
1380
+
1381
+ def test_astimezone(self):
1382
+ # Pretty boring! The TZ test is more interesting here. astimezone()
1383
+ # simply can't be applied to a naive object.
1384
+ dt = self.theclass.now()
1385
+ f = FixedOffset(44, "")
1386
+ self.assertRaises(TypeError, dt.astimezone) # not enough args
1387
+ self.assertRaises(TypeError, dt.astimezone, f, f) # too many args
1388
+ self.assertRaises(TypeError, dt.astimezone, dt) # arg wrong type
1389
+ self.assertRaises(ValueError, dt.astimezone, f) # naive
1390
+ self.assertRaises(ValueError, dt.astimezone, tz=f) # naive
1391
+
1392
+ class Bogus(tzinfo):
1393
+ def utcoffset(self, dt): return None
1394
+ def dst(self, dt): return timedelta(0)
1395
+ bog = Bogus()
1396
+ self.assertRaises(ValueError, dt.astimezone, bog) # naive
1397
+
1398
+ class AlsoBogus(tzinfo):
1399
+ def utcoffset(self, dt): return timedelta(0)
1400
+ def dst(self, dt): return None
1401
+ alsobog = AlsoBogus()
1402
+ self.assertRaises(ValueError, dt.astimezone, alsobog) # also naive
1403
+
1404
+ class TestTime(HarmlessMixedComparison):
1405
+
1406
+ theclass = time
1407
+
1408
+ def test_basic_attributes(self):
1409
+ t = self.theclass(12, 0)
1410
+ self.assertEqual(t.hour, 12)
1411
+ self.assertEqual(t.minute, 0)
1412
+ self.assertEqual(t.second, 0)
1413
+ self.assertEqual(t.microsecond, 0)
1414
+
1415
+ def test_basic_attributes_nonzero(self):
1416
+ # Make sure all attributes are non-zero so bugs in
1417
+ # bit-shifting access show up.
1418
+ t = self.theclass(12, 59, 59, 8000)
1419
+ self.assertEqual(t.hour, 12)
1420
+ self.assertEqual(t.minute, 59)
1421
+ self.assertEqual(t.second, 59)
1422
+ self.assertEqual(t.microsecond, 8000)
1423
+
1424
+ def test_roundtrip(self):
1425
+ t = self.theclass(1, 2, 3, 4)
1426
+
1427
+ # Verify t -> string -> time identity.
1428
+ s = repr(t)
1429
+ self.failUnless(s.startswith('datetime.'))
1430
+ s = s[9:]
1431
+ t2 = eval(s)
1432
+ self.assertEqual(t, t2)
1433
+
1434
+ # Verify identity via reconstructing from pieces.
1435
+ t2 = self.theclass(t.hour, t.minute, t.second,
1436
+ t.microsecond)
1437
+ self.assertEqual(t, t2)
1438
+
1439
+ def test_comparing(self):
1440
+ args = [1, 2, 3, 4]
1441
+ t1 = self.theclass(*args)
1442
+ t2 = self.theclass(*args)
1443
+ self.failUnless(t1 == t2)
1444
+ self.failUnless(t1 <= t2)
1445
+ self.failUnless(t1 >= t2)
1446
+ self.failUnless(not t1 != t2)
1447
+ self.failUnless(not t1 < t2)
1448
+ self.failUnless(not t1 > t2)
1449
+ self.assertEqual(cmp(t1, t2), 0)
1450
+ self.assertEqual(cmp(t2, t1), 0)
1451
+
1452
+ for i in range(len(args)):
1453
+ newargs = args[:]
1454
+ newargs[i] = args[i] + 1
1455
+ t2 = self.theclass(*newargs) # this is larger than t1
1456
+ self.failUnless(t1 < t2)
1457
+ self.failUnless(t2 > t1)
1458
+ self.failUnless(t1 <= t2)
1459
+ self.failUnless(t2 >= t1)
1460
+ self.failUnless(t1 != t2)
1461
+ self.failUnless(t2 != t1)
1462
+ self.failUnless(not t1 == t2)
1463
+ self.failUnless(not t2 == t1)
1464
+ self.failUnless(not t1 > t2)
1465
+ self.failUnless(not t2 < t1)
1466
+ self.failUnless(not t1 >= t2)
1467
+ self.failUnless(not t2 <= t1)
1468
+ self.assertEqual(cmp(t1, t2), -1)
1469
+ self.assertEqual(cmp(t2, t1), 1)
1470
+
1471
+ for badarg in OTHERSTUFF:
1472
+ self.assertEqual(t1 == badarg, False)
1473
+ self.assertEqual(t1 != badarg, True)
1474
+ self.assertEqual(badarg == t1, False)
1475
+ self.assertEqual(badarg != t1, True)
1476
+
1477
+ self.assertRaises(TypeError, lambda: t1 <= badarg)
1478
+ self.assertRaises(TypeError, lambda: t1 < badarg)
1479
+ self.assertRaises(TypeError, lambda: t1 > badarg)
1480
+ self.assertRaises(TypeError, lambda: t1 >= badarg)
1481
+ self.assertRaises(TypeError, lambda: badarg <= t1)
1482
+ self.assertRaises(TypeError, lambda: badarg < t1)
1483
+ self.assertRaises(TypeError, lambda: badarg > t1)
1484
+ self.assertRaises(TypeError, lambda: badarg >= t1)
1485
+
1486
+ def test_bad_constructor_arguments(self):
1487
+ # bad hours
1488
+ self.theclass(0, 0) # no exception
1489
+ self.theclass(23, 0) # no exception
1490
+ self.assertRaises(ValueError, self.theclass, -1, 0)
1491
+ self.assertRaises(ValueError, self.theclass, 24, 0)
1492
+ # bad minutes
1493
+ self.theclass(23, 0) # no exception
1494
+ self.theclass(23, 59) # no exception
1495
+ self.assertRaises(ValueError, self.theclass, 23, -1)
1496
+ self.assertRaises(ValueError, self.theclass, 23, 60)
1497
+ # bad seconds
1498
+ self.theclass(23, 59, 0) # no exception
1499
+ self.theclass(23, 59, 59) # no exception
1500
+ self.assertRaises(ValueError, self.theclass, 23, 59, -1)
1501
+ self.assertRaises(ValueError, self.theclass, 23, 59, 60)
1502
+ # bad microseconds
1503
+ self.theclass(23, 59, 59, 0) # no exception
1504
+ self.theclass(23, 59, 59, 999999) # no exception
1505
+ self.assertRaises(ValueError, self.theclass, 23, 59, 59, -1)
1506
+ self.assertRaises(ValueError, self.theclass, 23, 59, 59, 1000000)
1507
+
1508
+ def test_hash_equality(self):
1509
+ d = self.theclass(23, 30, 17)
1510
+ e = self.theclass(23, 30, 17)
1511
+ self.assertEqual(d, e)
1512
+ self.assertEqual(hash(d), hash(e))
1513
+
1514
+ dic = {d: 1}
1515
+ dic[e] = 2
1516
+ self.assertEqual(len(dic), 1)
1517
+ self.assertEqual(dic[d], 2)
1518
+ self.assertEqual(dic[e], 2)
1519
+
1520
+ d = self.theclass(0, 5, 17)
1521
+ e = self.theclass(0, 5, 17)
1522
+ self.assertEqual(d, e)
1523
+ self.assertEqual(hash(d), hash(e))
1524
+
1525
+ dic = {d: 1}
1526
+ dic[e] = 2
1527
+ self.assertEqual(len(dic), 1)
1528
+ self.assertEqual(dic[d], 2)
1529
+ self.assertEqual(dic[e], 2)
1530
+
1531
+ def test_isoformat(self):
1532
+ t = self.theclass(4, 5, 1, 123)
1533
+ self.assertEqual(t.isoformat(), "04:05:01.000123")
1534
+ self.assertEqual(t.isoformat(), str(t))
1535
+
1536
+ t = self.theclass()
1537
+ self.assertEqual(t.isoformat(), "00:00:00")
1538
+ self.assertEqual(t.isoformat(), str(t))
1539
+
1540
+ t = self.theclass(microsecond=1)
1541
+ self.assertEqual(t.isoformat(), "00:00:00.000001")
1542
+ self.assertEqual(t.isoformat(), str(t))
1543
+
1544
+ t = self.theclass(microsecond=10)
1545
+ self.assertEqual(t.isoformat(), "00:00:00.000010")
1546
+ self.assertEqual(t.isoformat(), str(t))
1547
+
1548
+ t = self.theclass(microsecond=100)
1549
+ self.assertEqual(t.isoformat(), "00:00:00.000100")
1550
+ self.assertEqual(t.isoformat(), str(t))
1551
+
1552
+ t = self.theclass(microsecond=1000)
1553
+ self.assertEqual(t.isoformat(), "00:00:00.001000")
1554
+ self.assertEqual(t.isoformat(), str(t))
1555
+
1556
+ t = self.theclass(microsecond=10000)
1557
+ self.assertEqual(t.isoformat(), "00:00:00.010000")
1558
+ self.assertEqual(t.isoformat(), str(t))
1559
+
1560
+ t = self.theclass(microsecond=100000)
1561
+ self.assertEqual(t.isoformat(), "00:00:00.100000")
1562
+ self.assertEqual(t.isoformat(), str(t))
1563
+
1564
+ def test_strftime(self):
1565
+ t = self.theclass(1, 2, 3, 4)
1566
+ self.assertEqual(t.strftime('%H %M %S'), "01 02 03")
1567
+ # A naive object replaces %z and %Z with empty strings.
1568
+ self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
1569
+
1570
+ def test_str(self):
1571
+ self.assertEqual(str(self.theclass(1, 2, 3, 4)), "01:02:03.000004")
1572
+ self.assertEqual(str(self.theclass(10, 2, 3, 4000)), "10:02:03.004000")
1573
+ self.assertEqual(str(self.theclass(0, 2, 3, 400000)), "00:02:03.400000")
1574
+ self.assertEqual(str(self.theclass(12, 2, 3, 0)), "12:02:03")
1575
+ self.assertEqual(str(self.theclass(23, 15, 0, 0)), "23:15:00")
1576
+
1577
+ def test_repr(self):
1578
+ name = 'datetime.' + self.theclass.__name__
1579
+ self.assertEqual(repr(self.theclass(1, 2, 3, 4)),
1580
+ "%s(1, 2, 3, 4)" % name)
1581
+ self.assertEqual(repr(self.theclass(10, 2, 3, 4000)),
1582
+ "%s(10, 2, 3, 4000)" % name)
1583
+ self.assertEqual(repr(self.theclass(0, 2, 3, 400000)),
1584
+ "%s(0, 2, 3, 400000)" % name)
1585
+ self.assertEqual(repr(self.theclass(12, 2, 3, 0)),
1586
+ "%s(12, 2, 3)" % name)
1587
+ self.assertEqual(repr(self.theclass(23, 15, 0, 0)),
1588
+ "%s(23, 15)" % name)
1589
+
1590
+ def test_resolution_info(self):
1591
+ self.assert_(isinstance(self.theclass.min, self.theclass))
1592
+ self.assert_(isinstance(self.theclass.max, self.theclass))
1593
+ self.assert_(isinstance(self.theclass.resolution, timedelta))
1594
+ self.assert_(self.theclass.max > self.theclass.min)
1595
+
1596
+ #XXX: pickling not working for jython yet.
1597
+ def test_pickling(self):
1598
+ args = 20, 59, 16, 64**2
1599
+ orig = self.theclass(*args)
1600
+ for pickler, unpickler, proto in pickle_choices:
1601
+ green = pickler.dumps(orig, proto)
1602
+ derived = unpickler.loads(green)
1603
+ self.assertEqual(orig, derived)
1604
+
1605
+ def test_bool(self):
1606
+ cls = self.theclass
1607
+ self.failUnless(cls(1))
1608
+ self.failUnless(cls(0, 1))
1609
+ self.failUnless(cls(0, 0, 1))
1610
+ self.failUnless(cls(0, 0, 0, 1))
1611
+ self.failUnless(not cls(0))
1612
+ self.failUnless(not cls())
1613
+
1614
+ def test_replace(self):
1615
+ cls = self.theclass
1616
+ args = [1, 2, 3, 4]
1617
+ base = cls(*args)
1618
+ self.assertEqual(base, base.replace())
1619
+
1620
+ i = 0
1621
+ for name, newval in (("hour", 5),
1622
+ ("minute", 6),
1623
+ ("second", 7),
1624
+ ("microsecond", 8)):
1625
+ newargs = args[:]
1626
+ newargs[i] = newval
1627
+ expected = cls(*newargs)
1628
+ got = base.replace(**{name: newval})
1629
+ self.assertEqual(expected, got)
1630
+ i += 1
1631
+
1632
+ # Out of bounds.
1633
+ base = cls(1)
1634
+ self.assertRaises(ValueError, base.replace, hour=24)
1635
+ self.assertRaises(ValueError, base.replace, minute=-1)
1636
+ self.assertRaises(ValueError, base.replace, second=100)
1637
+ self.assertRaises(ValueError, base.replace, microsecond=1000000)
1638
+
1639
+ # A mixin for classes with a tzinfo= argument. Subclasses must define
1640
+ # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever)
1641
+ # must be legit (which is true for time and datetime).
1642
+ class TZInfoBase(unittest.TestCase):
1643
+
1644
+ def test_argument_passing(self):
1645
+ cls = self.theclass
1646
+ # A datetime passes itself on, a time passes None.
1647
+ class introspective(tzinfo):
1648
+ def tzname(self, dt): return dt and "real" or "none"
1649
+ def utcoffset(self, dt):
1650
+ return timedelta(minutes = dt and 42 or -42)
1651
+ dst = utcoffset
1652
+
1653
+ obj = cls(1, 2, 3, tzinfo=introspective())
1654
+
1655
+ expected = cls is time and "none" or "real"
1656
+ self.assertEqual(obj.tzname(), expected)
1657
+
1658
+ expected = timedelta(minutes=(cls is time and -42 or 42))
1659
+ self.assertEqual(obj.utcoffset(), expected)
1660
+ self.assertEqual(obj.dst(), expected)
1661
+
1662
+ def test_bad_tzinfo_classes(self):
1663
+ cls = self.theclass
1664
+ self.assertRaises(TypeError, cls, 1, 1, 1, tzinfo=12)
1665
+
1666
+ class NiceTry(object):
1667
+ def __init__(self): pass
1668
+ def utcoffset(self, dt): pass
1669
+ self.assertRaises(TypeError, cls, 1, 1, 1, tzinfo=NiceTry)
1670
+
1671
+ class BetterTry(tzinfo):
1672
+ def __init__(self): pass
1673
+ def utcoffset(self, dt): pass
1674
+ b = BetterTry()
1675
+ t = cls(1, 1, 1, tzinfo=b)
1676
+ self.failUnless(t.tzinfo is b)
1677
+
1678
+ def test_utc_offset_out_of_bounds(self):
1679
+ class Edgy(tzinfo):
1680
+ def __init__(self, offset):
1681
+ self.offset = timedelta(minutes=offset)
1682
+ def utcoffset(self, dt):
1683
+ return self.offset
1684
+
1685
+ cls = self.theclass
1686
+ for offset, legit in ((-1440, False),
1687
+ (-1439, True),
1688
+ (1439, True),
1689
+ (1440, False)):
1690
+ if cls is time:
1691
+ t = cls(1, 2, 3, tzinfo=Edgy(offset))
1692
+ elif cls is datetime:
1693
+ t = cls(6, 6, 6, 1, 2, 3, tzinfo=Edgy(offset))
1694
+ else:
1695
+ assert 0, "impossible"
1696
+ if legit:
1697
+ aofs = abs(offset)
1698
+ h, m = divmod(aofs, 60)
1699
+ tag = "%c%02d:%02d" % (offset < 0 and '-' or '+', h, m)
1700
+ if isinstance(t, datetime):
1701
+ t = t.timetz()
1702
+ self.assertEqual(str(t), "01:02:03" + tag)
1703
+ else:
1704
+ self.assertRaises(ValueError, str, t)
1705
+
1706
+ def test_tzinfo_classes(self):
1707
+ cls = self.theclass
1708
+ class C1(tzinfo):
1709
+ def utcoffset(self, dt): return None
1710
+ def dst(self, dt): return None
1711
+ def tzname(self, dt): return None
1712
+ for t in (cls(1, 1, 1),
1713
+ cls(1, 1, 1, tzinfo=None),
1714
+ cls(1, 1, 1, tzinfo=C1())):
1715
+ self.failUnless(t.utcoffset() is None)
1716
+ self.failUnless(t.dst() is None)
1717
+ self.failUnless(t.tzname() is None)
1718
+
1719
+ class C3(tzinfo):
1720
+ def utcoffset(self, dt): return timedelta(minutes=-1439)
1721
+ def dst(self, dt): return timedelta(minutes=1439)
1722
+ def tzname(self, dt): return "aname"
1723
+ t = cls(1, 1, 1, tzinfo=C3())
1724
+ self.assertEqual(t.utcoffset(), timedelta(minutes=-1439))
1725
+ self.assertEqual(t.dst(), timedelta(minutes=1439))
1726
+ self.assertEqual(t.tzname(), "aname")
1727
+
1728
+ # Wrong types.
1729
+ class C4(tzinfo):
1730
+ def utcoffset(self, dt): return "aname"
1731
+ def dst(self, dt): return 7
1732
+ def tzname(self, dt): return 0
1733
+ t = cls(1, 1, 1, tzinfo=C4())
1734
+ self.assertRaises(TypeError, t.utcoffset)
1735
+ self.assertRaises(TypeError, t.dst)
1736
+ self.assertRaises(TypeError, t.tzname)
1737
+
1738
+ # Offset out of range.
1739
+ class C6(tzinfo):
1740
+ def utcoffset(self, dt): return timedelta(hours=-24)
1741
+ def dst(self, dt): return timedelta(hours=24)
1742
+ t = cls(1, 1, 1, tzinfo=C6())
1743
+ self.assertRaises(ValueError, t.utcoffset)
1744
+ self.assertRaises(ValueError, t.dst)
1745
+
1746
+ # Not a whole number of minutes.
1747
+ class C7(tzinfo):
1748
+ def utcoffset(self, dt): return timedelta(seconds=61)
1749
+ def dst(self, dt): return timedelta(microseconds=-81)
1750
+ t = cls(1, 1, 1, tzinfo=C7())
1751
+ self.assertRaises(ValueError, t.utcoffset)
1752
+ self.assertRaises(ValueError, t.dst)
1753
+
1754
+ def test_aware_compare(self):
1755
+ cls = self.theclass
1756
+
1757
+ # Ensure that utcoffset() gets ignored if the comparands have
1758
+ # the same tzinfo member.
1759
+ class OperandDependentOffset(tzinfo):
1760
+ def utcoffset(self, t):
1761
+ if t.minute < 10:
1762
+ # d0 and d1 equal after adjustment
1763
+ return timedelta(minutes=t.minute)
1764
+ else:
1765
+ # d2 off in the weeds
1766
+ return timedelta(minutes=59)
1767
+
1768
+ base = cls(8, 9, 10, tzinfo=OperandDependentOffset())
1769
+ d0 = base.replace(minute=3)
1770
+ d1 = base.replace(minute=9)
1771
+ d2 = base.replace(minute=11)
1772
+ for x in d0, d1, d2:
1773
+ for y in d0, d1, d2:
1774
+ got = cmp(x, y)
1775
+ expected = cmp(x.minute, y.minute)
1776
+ self.assertEqual(got, expected)
1777
+
1778
+ # However, if they're different members, uctoffset is not ignored.
1779
+ # Note that a time can't actually have an operand-depedent offset,
1780
+ # though (and time.utcoffset() passes None to tzinfo.utcoffset()),
1781
+ # so skip this test for time.
1782
+ if cls is not time:
1783
+ d0 = base.replace(minute=3, tzinfo=OperandDependentOffset())
1784
+ d1 = base.replace(minute=9, tzinfo=OperandDependentOffset())
1785
+ d2 = base.replace(minute=11, tzinfo=OperandDependentOffset())
1786
+ for x in d0, d1, d2:
1787
+ for y in d0, d1, d2:
1788
+ got = cmp(x, y)
1789
+ if (x is d0 or x is d1) and (y is d0 or y is d1):
1790
+ expected = 0
1791
+ elif x is y is d2:
1792
+ expected = 0
1793
+ elif x is d2:
1794
+ expected = -1
1795
+ else:
1796
+ assert y is d2
1797
+ expected = 1
1798
+ self.assertEqual(got, expected)
1799
+
1800
+
1801
+ # Testing time objects with a non-None tzinfo.
1802
+ class TestTimeTZ(TestTime, TZInfoBase):
1803
+ theclass = time
1804
+
1805
+ def test_empty(self):
1806
+ t = self.theclass()
1807
+ self.assertEqual(t.hour, 0)
1808
+ self.assertEqual(t.minute, 0)
1809
+ self.assertEqual(t.second, 0)
1810
+ self.assertEqual(t.microsecond, 0)
1811
+ self.failUnless(t.tzinfo is None)
1812
+
1813
+ def test_zones(self):
1814
+ est = FixedOffset(-300, "EST", 1)
1815
+ utc = FixedOffset(0, "UTC", -2)
1816
+ met = FixedOffset(60, "MET", 3)
1817
+ t1 = time( 7, 47, tzinfo=est)
1818
+ t2 = time(12, 47, tzinfo=utc)
1819
+ t3 = time(13, 47, tzinfo=met)
1820
+ t4 = time(microsecond=40)
1821
+ t5 = time(microsecond=40, tzinfo=utc)
1822
+
1823
+ self.assertEqual(t1.tzinfo, est)
1824
+ self.assertEqual(t2.tzinfo, utc)
1825
+ self.assertEqual(t3.tzinfo, met)
1826
+ self.failUnless(t4.tzinfo is None)
1827
+ self.assertEqual(t5.tzinfo, utc)
1828
+
1829
+ self.assertEqual(t1.utcoffset(), timedelta(minutes=-300))
1830
+ self.assertEqual(t2.utcoffset(), timedelta(minutes=0))
1831
+ self.assertEqual(t3.utcoffset(), timedelta(minutes=60))
1832
+ self.failUnless(t4.utcoffset() is None)
1833
+ self.assertRaises(TypeError, t1.utcoffset, "no args")
1834
+
1835
+ self.assertEqual(t1.tzname(), "EST")
1836
+ self.assertEqual(t2.tzname(), "UTC")
1837
+ self.assertEqual(t3.tzname(), "MET")
1838
+ self.failUnless(t4.tzname() is None)
1839
+ self.assertRaises(TypeError, t1.tzname, "no args")
1840
+
1841
+ self.assertEqual(t1.dst(), timedelta(minutes=1))
1842
+ self.assertEqual(t2.dst(), timedelta(minutes=-2))
1843
+ self.assertEqual(t3.dst(), timedelta(minutes=3))
1844
+ self.failUnless(t4.dst() is None)
1845
+ self.assertRaises(TypeError, t1.dst, "no args")
1846
+
1847
+ self.assertEqual(hash(t1), hash(t2))
1848
+ self.assertEqual(hash(t1), hash(t3))
1849
+ self.assertEqual(hash(t2), hash(t3))
1850
+
1851
+ self.assertEqual(t1, t2)
1852
+ self.assertEqual(t1, t3)
1853
+ self.assertEqual(t2, t3)
1854
+ self.assertRaises(TypeError, lambda: t4 == t5) # mixed tz-aware & naive
1855
+ self.assertRaises(TypeError, lambda: t4 < t5) # mixed tz-aware & naive
1856
+ self.assertRaises(TypeError, lambda: t5 < t4) # mixed tz-aware & naive
1857
+
1858
+ self.assertEqual(str(t1), "07:47:00-05:00")
1859
+ self.assertEqual(str(t2), "12:47:00+00:00")
1860
+ self.assertEqual(str(t3), "13:47:00+01:00")
1861
+ self.assertEqual(str(t4), "00:00:00.000040")
1862
+ self.assertEqual(str(t5), "00:00:00.000040+00:00")
1863
+
1864
+ self.assertEqual(t1.isoformat(), "07:47:00-05:00")
1865
+ self.assertEqual(t2.isoformat(), "12:47:00+00:00")
1866
+ self.assertEqual(t3.isoformat(), "13:47:00+01:00")
1867
+ self.assertEqual(t4.isoformat(), "00:00:00.000040")
1868
+ self.assertEqual(t5.isoformat(), "00:00:00.000040+00:00")
1869
+
1870
+ d = 'datetime.time'
1871
+ self.assertEqual(repr(t1), d + "(7, 47, tzinfo=est)")
1872
+ self.assertEqual(repr(t2), d + "(12, 47, tzinfo=utc)")
1873
+ self.assertEqual(repr(t3), d + "(13, 47, tzinfo=met)")
1874
+ self.assertEqual(repr(t4), d + "(0, 0, 0, 40)")
1875
+ self.assertEqual(repr(t5), d + "(0, 0, 0, 40, tzinfo=utc)")
1876
+
1877
+ self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z"),
1878
+ "07:47:00 %Z=EST %z=-0500")
1879
+ self.assertEqual(t2.strftime("%H:%M:%S %Z %z"), "12:47:00 UTC +0000")
1880
+ self.assertEqual(t3.strftime("%H:%M:%S %Z %z"), "13:47:00 MET +0100")
1881
+
1882
+ yuck = FixedOffset(-1439, "%z %Z %%z%%Z")
1883
+ t1 = time(23, 59, tzinfo=yuck)
1884
+ self.assertEqual(t1.strftime("%H:%M %%Z='%Z' %%z='%z'"),
1885
+ "23:59 %Z='%z %Z %%z%%Z' %z='-2359'")
1886
+
1887
+ # Check that an invalid tzname result raises an exception.
1888
+ class Badtzname(tzinfo):
1889
+ def tzname(self, dt): return 42
1890
+ t = time(2, 3, 4, tzinfo=Badtzname())
1891
+ self.assertEqual(t.strftime("%H:%M:%S"), "02:03:04")
1892
+ self.assertRaises(TypeError, t.strftime, "%Z")
1893
+
1894
+ def test_hash_edge_cases(self):
1895
+ # Offsets that overflow a basic time.
1896
+ t1 = self.theclass(0, 1, 2, 3, tzinfo=FixedOffset(1439, ""))
1897
+ t2 = self.theclass(0, 0, 2, 3, tzinfo=FixedOffset(1438, ""))
1898
+ self.assertEqual(hash(t1), hash(t2))
1899
+
1900
+ t1 = self.theclass(23, 58, 6, 100, tzinfo=FixedOffset(-1000, ""))
1901
+ t2 = self.theclass(23, 48, 6, 100, tzinfo=FixedOffset(-1010, ""))
1902
+ self.assertEqual(hash(t1), hash(t2))
1903
+
1904
+ #XXX: pickling not working for jython yet.
1905
+ def test_pickling(self):
1906
+ # Try one without a tzinfo.
1907
+ args = 20, 59, 16, 64**2
1908
+ orig = self.theclass(*args)
1909
+ for pickler, unpickler, proto in pickle_choices:
1910
+ green = pickler.dumps(orig, proto)
1911
+ derived = unpickler.loads(green)
1912
+ self.assertEqual(orig, derived)
1913
+
1914
+ # Try one with a tzinfo.
1915
+ tinfo = PicklableFixedOffset(-300, 'cookie')
1916
+ orig = self.theclass(5, 6, 7, tzinfo=tinfo)
1917
+ for pickler, unpickler, proto in pickle_choices:
1918
+ green = pickler.dumps(orig, proto)
1919
+ derived = unpickler.loads(green)
1920
+ self.assertEqual(orig, derived)
1921
+ self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset))
1922
+ self.assertEqual(derived.utcoffset(), timedelta(minutes=-300))
1923
+ self.assertEqual(derived.tzname(), 'cookie')
1924
+
1925
+ def test_more_bool(self):
1926
+ # Test cases with non-None tzinfo.
1927
+ cls = self.theclass
1928
+
1929
+ t = cls(0, tzinfo=FixedOffset(-300, ""))
1930
+ self.failUnless(t)
1931
+
1932
+ t = cls(5, tzinfo=FixedOffset(-300, ""))
1933
+ self.failUnless(t)
1934
+
1935
+ t = cls(5, tzinfo=FixedOffset(300, ""))
1936
+ self.failUnless(not t)
1937
+
1938
+ t = cls(23, 59, tzinfo=FixedOffset(23*60 + 59, ""))
1939
+ self.failUnless(not t)
1940
+
1941
+ # Mostly ensuring this doesn't overflow internally.
1942
+ t = cls(0, tzinfo=FixedOffset(23*60 + 59, ""))
1943
+ self.failUnless(t)
1944
+
1945
+ # But this should yield a value error -- the utcoffset is bogus.
1946
+ t = cls(0, tzinfo=FixedOffset(24*60, ""))
1947
+ self.assertRaises(ValueError, lambda: bool(t))
1948
+
1949
+ # Likewise.
1950
+ t = cls(0, tzinfo=FixedOffset(-24*60, ""))
1951
+ self.assertRaises(ValueError, lambda: bool(t))
1952
+
1953
+ def test_replace(self):
1954
+ cls = self.theclass
1955
+ z100 = FixedOffset(100, "+100")
1956
+ zm200 = FixedOffset(timedelta(minutes=-200), "-200")
1957
+ args = [1, 2, 3, 4, z100]
1958
+ base = cls(*args)
1959
+ self.assertEqual(base, base.replace())
1960
+
1961
+ i = 0
1962
+ for name, newval in (("hour", 5),
1963
+ ("minute", 6),
1964
+ ("second", 7),
1965
+ ("microsecond", 8),
1966
+ ("tzinfo", zm200)):
1967
+ newargs = args[:]
1968
+ newargs[i] = newval
1969
+ expected = cls(*newargs)
1970
+ got = base.replace(**{name: newval})
1971
+ self.assertEqual(expected, got)
1972
+ i += 1
1973
+
1974
+ # Ensure we can get rid of a tzinfo.
1975
+ self.assertEqual(base.tzname(), "+100")
1976
+ base2 = base.replace(tzinfo=None)
1977
+ self.failUnless(base2.tzinfo is None)
1978
+ self.failUnless(base2.tzname() is None)
1979
+
1980
+ # Ensure we can add one.
1981
+ base3 = base2.replace(tzinfo=z100)
1982
+ self.assertEqual(base, base3)
1983
+ self.failUnless(base.tzinfo is base3.tzinfo)
1984
+
1985
+ # Out of bounds.
1986
+ base = cls(1)
1987
+ self.assertRaises(ValueError, base.replace, hour=24)
1988
+ self.assertRaises(ValueError, base.replace, minute=-1)
1989
+ self.assertRaises(ValueError, base.replace, second=100)
1990
+ self.assertRaises(ValueError, base.replace, microsecond=1000000)
1991
+
1992
+ def test_mixed_compare(self):
1993
+ t1 = time(1, 2, 3)
1994
+ t2 = time(1, 2, 3)
1995
+ self.assertEqual(t1, t2)
1996
+ t2 = t2.replace(tzinfo=None)
1997
+ self.assertEqual(t1, t2)
1998
+ t2 = t2.replace(tzinfo=FixedOffset(None, ""))
1999
+ self.assertEqual(t1, t2)
2000
+ t2 = t2.replace(tzinfo=FixedOffset(0, ""))
2001
+ self.assertRaises(TypeError, lambda: t1 == t2)
2002
+
2003
+ # In time w/ identical tzinfo objects, utcoffset is ignored.
2004
+ class Varies(tzinfo):
2005
+ def __init__(self):
2006
+ self.offset = timedelta(minutes=22)
2007
+ def utcoffset(self, t):
2008
+ self.offset += timedelta(minutes=1)
2009
+ return self.offset
2010
+
2011
+ v = Varies()
2012
+ t1 = t2.replace(tzinfo=v)
2013
+ t2 = t2.replace(tzinfo=v)
2014
+ self.assertEqual(t1.utcoffset(), timedelta(minutes=23))
2015
+ self.assertEqual(t2.utcoffset(), timedelta(minutes=24))
2016
+ self.assertEqual(t1, t2)
2017
+
2018
+ # But if they're not identical, it isn't ignored.
2019
+ t2 = t2.replace(tzinfo=Varies())
2020
+ self.failUnless(t1 < t2) # t1's offset counter still going up
2021
+
2022
+
2023
+ # Testing datetime objects with a non-None tzinfo.
2024
+
2025
+ class TestDateTimeTZ(TestDateTime, TZInfoBase):
2026
+ theclass = datetime
2027
+
2028
+ def test_trivial(self):
2029
+ dt = self.theclass(1, 2, 3, 4, 5, 6, 7)
2030
+ self.assertEqual(dt.year, 1)
2031
+ self.assertEqual(dt.month, 2)
2032
+ self.assertEqual(dt.day, 3)
2033
+ self.assertEqual(dt.hour, 4)
2034
+ self.assertEqual(dt.minute, 5)
2035
+ self.assertEqual(dt.second, 6)
2036
+ self.assertEqual(dt.microsecond, 7)
2037
+ self.assertEqual(dt.tzinfo, None)
2038
+
2039
+ def test_even_more_compare(self):
2040
+ # The test_compare() and test_more_compare() inherited from TestDate
2041
+ # and TestDateTime covered non-tzinfo cases.
2042
+
2043
+ # Smallest possible after UTC adjustment.
2044
+ t1 = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, ""))
2045
+ # Largest possible after UTC adjustment.
2046
+ t2 = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999,
2047
+ tzinfo=FixedOffset(-1439, ""))
2048
+
2049
+ # Make sure those compare correctly, and w/o overflow.
2050
+ self.failUnless(t1 < t2)
2051
+ self.failUnless(t1 != t2)
2052
+ self.failUnless(t2 > t1)
2053
+
2054
+ self.failUnless(t1 == t1)
2055
+ self.failUnless(t2 == t2)
2056
+
2057
+ # Equal afer adjustment.
2058
+ t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""))
2059
+ t2 = self.theclass(2, 1, 1, 3, 13, tzinfo=FixedOffset(3*60+13+2, ""))
2060
+ self.assertEqual(t1, t2)
2061
+
2062
+ # Change t1 not to subtract a minute, and t1 should be larger.
2063
+ t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(0, ""))
2064
+ self.failUnless(t1 > t2)
2065
+
2066
+ # Change t1 to subtract 2 minutes, and t1 should be smaller.
2067
+ t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(2, ""))
2068
+ self.failUnless(t1 < t2)
2069
+
2070
+ # Back to the original t1, but make seconds resolve it.
2071
+ t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""),
2072
+ second=1)
2073
+ self.failUnless(t1 > t2)
2074
+
2075
+ # Likewise, but make microseconds resolve it.
2076
+ t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""),
2077
+ microsecond=1)
2078
+ self.failUnless(t1 > t2)
2079
+
2080
+ # Make t2 naive and it should fail.
2081
+ t2 = self.theclass.min
2082
+ self.assertRaises(TypeError, lambda: t1 == t2)
2083
+ self.assertEqual(t2, t2)
2084
+
2085
+ # It's also naive if it has tzinfo but tzinfo.utcoffset() is None.
2086
+ class Naive(tzinfo):
2087
+ def utcoffset(self, dt): return None
2088
+ t2 = self.theclass(5, 6, 7, tzinfo=Naive())
2089
+ self.assertRaises(TypeError, lambda: t1 == t2)
2090
+ self.assertEqual(t2, t2)
2091
+
2092
+ # OTOH, it's OK to compare two of these mixing the two ways of being
2093
+ # naive.
2094
+ t1 = self.theclass(5, 6, 7)
2095
+ self.assertEqual(t1, t2)
2096
+
2097
+ # Try a bogus uctoffset.
2098
+ class Bogus(tzinfo):
2099
+ def utcoffset(self, dt):
2100
+ return timedelta(minutes=1440) # out of bounds
2101
+ t1 = self.theclass(2, 2, 2, tzinfo=Bogus())
2102
+ t2 = self.theclass(2, 2, 2, tzinfo=FixedOffset(0, ""))
2103
+ self.assertRaises(ValueError, lambda: t1 == t2)
2104
+
2105
+ #XXX: pickling not working for jython yet.
2106
+ def test_pickling(self):
2107
+ # Try one without a tzinfo.
2108
+ args = 6, 7, 23, 20, 59, 1, 64**2
2109
+ orig = self.theclass(*args)
2110
+ for pickler, unpickler, proto in pickle_choices:
2111
+ green = pickler.dumps(orig, proto)
2112
+ derived = unpickler.loads(green)
2113
+ self.assertEqual(orig, derived)
2114
+
2115
+ # Try one with a tzinfo.
2116
+ tinfo = PicklableFixedOffset(-300, 'cookie')
2117
+ orig = self.theclass(*args, **{'tzinfo': tinfo})
2118
+ derived = self.theclass(1, 1, 1, tzinfo=FixedOffset(0, "", 0))
2119
+ for pickler, unpickler, proto in pickle_choices:
2120
+ green = pickler.dumps(orig, proto)
2121
+ derived = unpickler.loads(green)
2122
+ self.assertEqual(orig, derived)
2123
+ self.failUnless(isinstance(derived.tzinfo,
2124
+ PicklableFixedOffset))
2125
+ self.assertEqual(derived.utcoffset(), timedelta(minutes=-300))
2126
+ self.assertEqual(derived.tzname(), 'cookie')
2127
+
2128
+ def test_extreme_hashes(self):
2129
+ # If an attempt is made to hash these via subtracting the offset
2130
+ # then hashing a datetime object, OverflowError results. The
2131
+ # Python implementation used to blow up here.
2132
+ t = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, ""))
2133
+ hash(t)
2134
+ t = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999,
2135
+ tzinfo=FixedOffset(-1439, ""))
2136
+ hash(t)
2137
+
2138
+ # OTOH, an OOB offset should blow up.
2139
+ t = self.theclass(5, 5, 5, tzinfo=FixedOffset(-1440, ""))
2140
+ self.assertRaises(ValueError, hash, t)
2141
+
2142
+ def test_zones(self):
2143
+ est = FixedOffset(-300, "EST")
2144
+ utc = FixedOffset(0, "UTC")
2145
+ met = FixedOffset(60, "MET")
2146
+ t1 = datetime(2002, 3, 19, 7, 47, tzinfo=est)
2147
+ t2 = datetime(2002, 3, 19, 12, 47, tzinfo=utc)
2148
+ t3 = datetime(2002, 3, 19, 13, 47, tzinfo=met)
2149
+ self.assertEqual(t1.tzinfo, est)
2150
+ self.assertEqual(t2.tzinfo, utc)
2151
+ self.assertEqual(t3.tzinfo, met)
2152
+ self.assertEqual(t1.utcoffset(), timedelta(minutes=-300))
2153
+ self.assertEqual(t2.utcoffset(), timedelta(minutes=0))
2154
+ self.assertEqual(t3.utcoffset(), timedelta(minutes=60))
2155
+ self.assertEqual(t1.tzname(), "EST")
2156
+ self.assertEqual(t2.tzname(), "UTC")
2157
+ self.assertEqual(t3.tzname(), "MET")
2158
+ self.assertEqual(hash(t1), hash(t2))
2159
+ self.assertEqual(hash(t1), hash(t3))
2160
+ self.assertEqual(hash(t2), hash(t3))
2161
+ self.assertEqual(t1, t2)
2162
+ self.assertEqual(t1, t3)
2163
+ self.assertEqual(t2, t3)
2164
+ self.assertEqual(str(t1), "2002-03-19 07:47:00-05:00")
2165
+ self.assertEqual(str(t2), "2002-03-19 12:47:00+00:00")
2166
+ self.assertEqual(str(t3), "2002-03-19 13:47:00+01:00")
2167
+ d = 'datetime.datetime(2002, 3, 19, '
2168
+ self.assertEqual(repr(t1), d + "7, 47, tzinfo=est)")
2169
+ self.assertEqual(repr(t2), d + "12, 47, tzinfo=utc)")
2170
+ self.assertEqual(repr(t3), d + "13, 47, tzinfo=met)")
2171
+
2172
+ def test_combine(self):
2173
+ met = FixedOffset(60, "MET")
2174
+ d = date(2002, 3, 4)
2175
+ tz = time(18, 45, 3, 1234, tzinfo=met)
2176
+ dt = datetime.combine(d, tz)
2177
+ self.assertEqual(dt, datetime(2002, 3, 4, 18, 45, 3, 1234,
2178
+ tzinfo=met))
2179
+
2180
+ def test_extract(self):
2181
+ met = FixedOffset(60, "MET")
2182
+ dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234, tzinfo=met)
2183
+ self.assertEqual(dt.date(), date(2002, 3, 4))
2184
+ self.assertEqual(dt.time(), time(18, 45, 3, 1234))
2185
+ self.assertEqual(dt.timetz(), time(18, 45, 3, 1234, tzinfo=met))
2186
+
2187
+ def test_tz_aware_arithmetic(self):
2188
+ import random
2189
+
2190
+ now = self.theclass.now()
2191
+ tz55 = FixedOffset(-330, "west 5:30")
2192
+ timeaware = now.time().replace(tzinfo=tz55)
2193
+ nowaware = self.theclass.combine(now.date(), timeaware)
2194
+ self.failUnless(nowaware.tzinfo is tz55)
2195
+ self.assertEqual(nowaware.timetz(), timeaware)
2196
+
2197
+ # Can't mix aware and non-aware.
2198
+ self.assertRaises(TypeError, lambda: now - nowaware)
2199
+ self.assertRaises(TypeError, lambda: nowaware - now)
2200
+
2201
+ # And adding datetime's doesn't make sense, aware or not.
2202
+ self.assertRaises(TypeError, lambda: now + nowaware)
2203
+ self.assertRaises(TypeError, lambda: nowaware + now)
2204
+ self.assertRaises(TypeError, lambda: nowaware + nowaware)
2205
+
2206
+ # Subtracting should yield 0.
2207
+ self.assertEqual(now - now, timedelta(0))
2208
+ self.assertEqual(nowaware - nowaware, timedelta(0))
2209
+
2210
+ # Adding a delta should preserve tzinfo.
2211
+ delta = timedelta(weeks=1, minutes=12, microseconds=5678)
2212
+ nowawareplus = nowaware + delta
2213
+ self.failUnless(nowaware.tzinfo is tz55)
2214
+ nowawareplus2 = delta + nowaware
2215
+ self.failUnless(nowawareplus2.tzinfo is tz55)
2216
+ self.assertEqual(nowawareplus, nowawareplus2)
2217
+
2218
+ # that - delta should be what we started with, and that - what we
2219
+ # started with should be delta.
2220
+ diff = nowawareplus - delta
2221
+ self.failUnless(diff.tzinfo is tz55)
2222
+ self.assertEqual(nowaware, diff)
2223
+ self.assertRaises(TypeError, lambda: delta - nowawareplus)
2224
+ self.assertEqual(nowawareplus - nowaware, delta)
2225
+
2226
+ # Make up a random timezone.
2227
+ tzr = FixedOffset(random.randrange(-1439, 1440), "randomtimezone")
2228
+ # Attach it to nowawareplus.
2229
+ nowawareplus = nowawareplus.replace(tzinfo=tzr)
2230
+ self.failUnless(nowawareplus.tzinfo is tzr)
2231
+ # Make sure the difference takes the timezone adjustments into account.
2232
+ got = nowaware - nowawareplus
2233
+ # Expected: (nowaware base - nowaware offset) -
2234
+ # (nowawareplus base - nowawareplus offset) =
2235
+ # (nowaware base - nowawareplus base) +
2236
+ # (nowawareplus offset - nowaware offset) =
2237
+ # -delta + nowawareplus offset - nowaware offset
2238
+ expected = nowawareplus.utcoffset() - nowaware.utcoffset() - delta
2239
+ self.assertEqual(got, expected)
2240
+
2241
+ # Try max possible difference.
2242
+ min = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, "min"))
2243
+ max = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999,
2244
+ tzinfo=FixedOffset(-1439, "max"))
2245
+ maxdiff = max - min
2246
+ self.assertEqual(maxdiff, self.theclass.max - self.theclass.min +
2247
+ timedelta(minutes=2*1439))
2248
+
2249
+ def test_tzinfo_now(self):
2250
+ meth = self.theclass.now
2251
+ # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
2252
+ base = meth()
2253
+ # Try with and without naming the keyword.
2254
+ off42 = FixedOffset(42, "42")
2255
+ another = meth(off42)
2256
+ again = meth(tz=off42)
2257
+ self.failUnless(another.tzinfo is again.tzinfo)
2258
+ self.assertEqual(another.utcoffset(), timedelta(minutes=42))
2259
+ # Bad argument with and w/o naming the keyword.
2260
+ self.assertRaises(TypeError, meth, 16)
2261
+ self.assertRaises(TypeError, meth, tzinfo=16)
2262
+ # Bad keyword name.
2263
+ self.assertRaises(TypeError, meth, tinfo=off42)
2264
+ # Too many args.
2265
+ self.assertRaises(TypeError, meth, off42, off42)
2266
+
2267
+ # We don't know which time zone we're in, and don't have a tzinfo
2268
+ # class to represent it, so seeing whether a tz argument actually
2269
+ # does a conversion is tricky.
2270
+ weirdtz = FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0)
2271
+ utc = FixedOffset(0, "utc", 0)
2272
+ for dummy in range(3):
2273
+ now = datetime.now(weirdtz)
2274
+ self.failUnless(now.tzinfo is weirdtz)
2275
+ utcnow = datetime.utcnow().replace(tzinfo=utc)
2276
+ now2 = utcnow.astimezone(weirdtz)
2277
+ if abs(now - now2) < timedelta(seconds=30):
2278
+ break
2279
+ # Else the code is broken, or more than 30 seconds passed between
2280
+ # calls; assuming the latter, just try again.
2281
+ else:
2282
+ # Three strikes and we're out.
2283
+ self.fail("utcnow(), now(tz), or astimezone() may be broken")
2284
+
2285
+ def test_tzinfo_fromtimestamp(self):
2286
+ import time
2287
+ meth = self.theclass.fromtimestamp
2288
+ ts = time.time()
2289
+ # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
2290
+ base = meth(ts)
2291
+ # Try with and without naming the keyword.
2292
+ off42 = FixedOffset(42, "42")
2293
+ another = meth(ts, off42)
2294
+ again = meth(ts, tz=off42)
2295
+ self.failUnless(another.tzinfo is again.tzinfo)
2296
+ self.assertEqual(another.utcoffset(), timedelta(minutes=42))
2297
+ # Bad argument with and w/o naming the keyword.
2298
+ self.assertRaises(TypeError, meth, ts, 16)
2299
+ self.assertRaises(TypeError, meth, ts, tzinfo=16)
2300
+ # Bad keyword name.
2301
+ self.assertRaises(TypeError, meth, ts, tinfo=off42)
2302
+ # Too many args.
2303
+ self.assertRaises(TypeError, meth, ts, off42, off42)
2304
+ # Too few args.
2305
+ self.assertRaises(TypeError, meth)
2306
+
2307
+ # Try to make sure tz= actually does some conversion.
2308
+ timestamp = 1000000000
2309
+ utcdatetime = datetime.utcfromtimestamp(timestamp)
2310
+ # In POSIX (epoch 1970), that's 2001-09-09 01:46:40 UTC, give or take.
2311
+ # But on some flavor of Mac, it's nowhere near that. So we can't have
2312
+ # any idea here what time that actually is, we can only test that
2313
+ # relative changes match.
2314
+ utcoffset = timedelta(hours=-15, minutes=39) # arbitrary, but not zero
2315
+ tz = FixedOffset(utcoffset, "tz", 0)
2316
+ expected = utcdatetime + utcoffset
2317
+ got = datetime.fromtimestamp(timestamp, tz)
2318
+ self.assertEqual(expected, got.replace(tzinfo=None))
2319
+
2320
+ def test_tzinfo_utcnow(self):
2321
+ meth = self.theclass.utcnow
2322
+ # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
2323
+ base = meth()
2324
+ # Try with and without naming the keyword; for whatever reason,
2325
+ # utcnow() doesn't accept a tzinfo argument.
2326
+ off42 = FixedOffset(42, "42")
2327
+ self.assertRaises(TypeError, meth, off42)
2328
+ self.assertRaises(TypeError, meth, tzinfo=off42)
2329
+
2330
+ def test_tzinfo_utcfromtimestamp(self):
2331
+ import time
2332
+ meth = self.theclass.utcfromtimestamp
2333
+ ts = time.time()
2334
+ # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
2335
+ base = meth(ts)
2336
+ # Try with and without naming the keyword; for whatever reason,
2337
+ # utcfromtimestamp() doesn't accept a tzinfo argument.
2338
+ off42 = FixedOffset(42, "42")
2339
+ self.assertRaises(TypeError, meth, ts, off42)
2340
+ self.assertRaises(TypeError, meth, ts, tzinfo=off42)
2341
+
2342
+ def test_tzinfo_timetuple(self):
2343
+ # TestDateTime tested most of this. datetime adds a twist to the
2344
+ # DST flag.
2345
+ class DST(tzinfo):
2346
+ def __init__(self, dstvalue):
2347
+ if isinstance(dstvalue, int):
2348
+ dstvalue = timedelta(minutes=dstvalue)
2349
+ self.dstvalue = dstvalue
2350
+ def dst(self, dt):
2351
+ return self.dstvalue
2352
+
2353
+ cls = self.theclass
2354
+ for dstvalue, flag in (-33, 1), (33, 1), (0, 0), (None, -1):
2355
+ d = cls(1, 1, 1, 10, 20, 30, 40, tzinfo=DST(dstvalue))
2356
+ t = d.timetuple()
2357
+ self.assertEqual(1, t.tm_year)
2358
+ self.assertEqual(1, t.tm_mon)
2359
+ self.assertEqual(1, t.tm_mday)
2360
+ self.assertEqual(10, t.tm_hour)
2361
+ self.assertEqual(20, t.tm_min)
2362
+ self.assertEqual(30, t.tm_sec)
2363
+ self.assertEqual(0, t.tm_wday)
2364
+ self.assertEqual(1, t.tm_yday)
2365
+ self.assertEqual(flag, t.tm_isdst)
2366
+
2367
+ # dst() returns wrong type.
2368
+ self.assertRaises(TypeError, cls(1, 1, 1, tzinfo=DST("x")).timetuple)
2369
+
2370
+ # dst() at the edge.
2371
+ self.assertEqual(cls(1,1,1, tzinfo=DST(1439)).timetuple().tm_isdst, 1)
2372
+ self.assertEqual(cls(1,1,1, tzinfo=DST(-1439)).timetuple().tm_isdst, 1)
2373
+
2374
+ # dst() out of range.
2375
+ self.assertRaises(ValueError, cls(1,1,1, tzinfo=DST(1440)).timetuple)
2376
+ self.assertRaises(ValueError, cls(1,1,1, tzinfo=DST(-1440)).timetuple)
2377
+
2378
+ def test_utctimetuple(self):
2379
+ class DST(tzinfo):
2380
+ def __init__(self, dstvalue):
2381
+ if isinstance(dstvalue, int):
2382
+ dstvalue = timedelta(minutes=dstvalue)
2383
+ self.dstvalue = dstvalue
2384
+ def dst(self, dt):
2385
+ return self.dstvalue
2386
+
2387
+ cls = self.theclass
2388
+ # This can't work: DST didn't implement utcoffset.
2389
+ self.assertRaises(NotImplementedError,
2390
+ cls(1, 1, 1, tzinfo=DST(0)).utcoffset)
2391
+
2392
+ class UOFS(DST):
2393
+ def __init__(self, uofs, dofs=None):
2394
+ DST.__init__(self, dofs)
2395
+ self.uofs = timedelta(minutes=uofs)
2396
+ def utcoffset(self, dt):
2397
+ return self.uofs
2398
+
2399
+ # Ensure tm_isdst is 0 regardless of what dst() says: DST is never
2400
+ # in effect for a UTC time.
2401
+ for dstvalue in -33, 33, 0, None:
2402
+ d = cls(1, 2, 3, 10, 20, 30, 40, tzinfo=UOFS(-53, dstvalue))
2403
+ t = d.utctimetuple()
2404
+ self.assertEqual(d.year, t.tm_year)
2405
+ self.assertEqual(d.month, t.tm_mon)
2406
+ self.assertEqual(d.day, t.tm_mday)
2407
+ self.assertEqual(11, t.tm_hour) # 20mm + 53mm = 1hn + 13mm
2408
+ self.assertEqual(13, t.tm_min)
2409
+ self.assertEqual(d.second, t.tm_sec)
2410
+ self.assertEqual(d.weekday(), t.tm_wday)
2411
+ self.assertEqual(d.toordinal() - date(1, 1, 1).toordinal() + 1,
2412
+ t.tm_yday)
2413
+ self.assertEqual(0, t.tm_isdst)
2414
+
2415
+ # At the edges, UTC adjustment can normalize into years out-of-range
2416
+ # for a datetime object. Ensure that a correct timetuple is
2417
+ # created anyway.
2418
+ tiny = cls(MINYEAR, 1, 1, 0, 0, 37, tzinfo=UOFS(1439))
2419
+ # That goes back 1 minute less than a full day.
2420
+ t = tiny.utctimetuple()
2421
+ self.assertEqual(t.tm_year, MINYEAR-1)
2422
+ self.assertEqual(t.tm_mon, 12)
2423
+ self.assertEqual(t.tm_mday, 31)
2424
+ self.assertEqual(t.tm_hour, 0)
2425
+ self.assertEqual(t.tm_min, 1)
2426
+ self.assertEqual(t.tm_sec, 37)
2427
+ self.assertEqual(t.tm_yday, 366) # "year 0" is a leap year
2428
+ self.assertEqual(t.tm_isdst, 0)
2429
+
2430
+ huge = cls(MAXYEAR, 12, 31, 23, 59, 37, 999999, tzinfo=UOFS(-1439))
2431
+ # That goes forward 1 minute less than a full day.
2432
+ t = huge.utctimetuple()
2433
+ self.assertEqual(t.tm_year, MAXYEAR+1)
2434
+ self.assertEqual(t.tm_mon, 1)
2435
+ self.assertEqual(t.tm_mday, 1)
2436
+ self.assertEqual(t.tm_hour, 23)
2437
+ self.assertEqual(t.tm_min, 58)
2438
+ self.assertEqual(t.tm_sec, 37)
2439
+ self.assertEqual(t.tm_yday, 1)
2440
+ self.assertEqual(t.tm_isdst, 0)
2441
+
2442
+ def test_tzinfo_isoformat(self):
2443
+ zero = FixedOffset(0, "+00:00")
2444
+ plus = FixedOffset(220, "+03:40")
2445
+ minus = FixedOffset(-231, "-03:51")
2446
+ unknown = FixedOffset(None, "")
2447
+
2448
+ cls = self.theclass
2449
+ datestr = '0001-02-03'
2450
+ for ofs in None, zero, plus, minus, unknown:
2451
+ for us in 0, 987001:
2452
+ d = cls(1, 2, 3, 4, 5, 59, us, tzinfo=ofs)
2453
+ timestr = '04:05:59' + (us and '.987001' or '')
2454
+ ofsstr = ofs is not None and d.tzname() or ''
2455
+ tailstr = timestr + ofsstr
2456
+ iso = d.isoformat()
2457
+ self.assertEqual(iso, datestr + 'T' + tailstr)
2458
+ self.assertEqual(iso, d.isoformat('T'))
2459
+ self.assertEqual(d.isoformat('k'), datestr + 'k' + tailstr)
2460
+ self.assertEqual(str(d), datestr + ' ' + tailstr)
2461
+
2462
+ def test_replace(self):
2463
+ cls = self.theclass
2464
+ z100 = FixedOffset(100, "+100")
2465
+ zm200 = FixedOffset(timedelta(minutes=-200), "-200")
2466
+ args = [1, 2, 3, 4, 5, 6, 7, z100]
2467
+ base = cls(*args)
2468
+ self.assertEqual(base, base.replace())
2469
+
2470
+ i = 0
2471
+ for name, newval in (("year", 2),
2472
+ ("month", 3),
2473
+ ("day", 4),
2474
+ ("hour", 5),
2475
+ ("minute", 6),
2476
+ ("second", 7),
2477
+ ("microsecond", 8),
2478
+ ("tzinfo", zm200)):
2479
+ newargs = args[:]
2480
+ newargs[i] = newval
2481
+ expected = cls(*newargs)
2482
+ got = base.replace(**{name: newval})
2483
+ self.assertEqual(expected, got)
2484
+ i += 1
2485
+
2486
+ # Ensure we can get rid of a tzinfo.
2487
+ self.assertEqual(base.tzname(), "+100")
2488
+ base2 = base.replace(tzinfo=None)
2489
+ self.failUnless(base2.tzinfo is None)
2490
+ self.failUnless(base2.tzname() is None)
2491
+
2492
+ # Ensure we can add one.
2493
+ base3 = base2.replace(tzinfo=z100)
2494
+ self.assertEqual(base, base3)
2495
+ self.failUnless(base.tzinfo is base3.tzinfo)
2496
+
2497
+ # Out of bounds.
2498
+ base = cls(2000, 2, 29)
2499
+ self.assertRaises(ValueError, base.replace, year=2001)
2500
+
2501
+ def test_more_astimezone(self):
2502
+ # The inherited test_astimezone covered some trivial and error cases.
2503
+ fnone = FixedOffset(None, "None")
2504
+ f44m = FixedOffset(44, "44")
2505
+ fm5h = FixedOffset(-timedelta(hours=5), "m300")
2506
+
2507
+ dt = self.theclass.now(tz=f44m)
2508
+ self.failUnless(dt.tzinfo is f44m)
2509
+ # Replacing with degenerate tzinfo raises an exception.
2510
+ self.assertRaises(ValueError, dt.astimezone, fnone)
2511
+ # Ditto with None tz.
2512
+ self.assertRaises(TypeError, dt.astimezone, None)
2513
+ # Replacing with same tzinfo makes no change.
2514
+ x = dt.astimezone(dt.tzinfo)
2515
+ self.failUnless(x.tzinfo is f44m)
2516
+ self.assertEqual(x.date(), dt.date())
2517
+ self.assertEqual(x.time(), dt.time())
2518
+
2519
+ # Replacing with different tzinfo does adjust.
2520
+ got = dt.astimezone(fm5h)
2521
+ self.failUnless(got.tzinfo is fm5h)
2522
+ self.assertEqual(got.utcoffset(), timedelta(hours=-5))
2523
+ expected = dt - dt.utcoffset() # in effect, convert to UTC
2524
+ expected += fm5h.utcoffset(dt) # and from there to local time
2525
+ expected = expected.replace(tzinfo=fm5h) # and attach new tzinfo
2526
+ self.assertEqual(got.date(), expected.date())
2527
+ self.assertEqual(got.time(), expected.time())
2528
+ self.assertEqual(got.timetz(), expected.timetz())
2529
+ self.failUnless(got.tzinfo is expected.tzinfo)
2530
+ self.assertEqual(got, expected)
2531
+
2532
+ def test_aware_subtract(self):
2533
+ cls = self.theclass
2534
+
2535
+ # Ensure that utcoffset() is ignored when the operands have the
2536
+ # same tzinfo member.
2537
+ class OperandDependentOffset(tzinfo):
2538
+ def utcoffset(self, t):
2539
+ if t.minute < 10:
2540
+ # d0 and d1 equal after adjustment
2541
+ return timedelta(minutes=t.minute)
2542
+ else:
2543
+ # d2 off in the weeds
2544
+ return timedelta(minutes=59)
2545
+
2546
+ base = cls(8, 9, 10, 11, 12, 13, 14, tzinfo=OperandDependentOffset())
2547
+ d0 = base.replace(minute=3)
2548
+ d1 = base.replace(minute=9)
2549
+ d2 = base.replace(minute=11)
2550
+ for x in d0, d1, d2:
2551
+ for y in d0, d1, d2:
2552
+ got = x - y
2553
+ expected = timedelta(minutes=x.minute - y.minute)
2554
+ self.assertEqual(got, expected)
2555
+
2556
+ # OTOH, if the tzinfo members are distinct, utcoffsets aren't
2557
+ # ignored.
2558
+ base = cls(8, 9, 10, 11, 12, 13, 14)
2559
+ d0 = base.replace(minute=3, tzinfo=OperandDependentOffset())
2560
+ d1 = base.replace(minute=9, tzinfo=OperandDependentOffset())
2561
+ d2 = base.replace(minute=11, tzinfo=OperandDependentOffset())
2562
+ for x in d0, d1, d2:
2563
+ for y in d0, d1, d2:
2564
+ got = x - y
2565
+ if (x is d0 or x is d1) and (y is d0 or y is d1):
2566
+ expected = timedelta(0)
2567
+ elif x is y is d2:
2568
+ expected = timedelta(0)
2569
+ elif x is d2:
2570
+ expected = timedelta(minutes=(11-59)-0)
2571
+ else:
2572
+ assert y is d2
2573
+ expected = timedelta(minutes=0-(11-59))
2574
+ self.assertEqual(got, expected)
2575
+
2576
+ def test_mixed_compare(self):
2577
+ t1 = datetime(1, 2, 3, 4, 5, 6, 7)
2578
+ t2 = datetime(1, 2, 3, 4, 5, 6, 7)
2579
+ self.assertEqual(t1, t2)
2580
+ t2 = t2.replace(tzinfo=None)
2581
+ self.assertEqual(t1, t2)
2582
+ t2 = t2.replace(tzinfo=FixedOffset(None, ""))
2583
+ self.assertEqual(t1, t2)
2584
+ t2 = t2.replace(tzinfo=FixedOffset(0, ""))
2585
+ self.assertRaises(TypeError, lambda: t1 == t2)
2586
+
2587
+ # In datetime w/ identical tzinfo objects, utcoffset is ignored.
2588
+ class Varies(tzinfo):
2589
+ def __init__(self):
2590
+ self.offset = timedelta(minutes=22)
2591
+ def utcoffset(self, t):
2592
+ self.offset += timedelta(minutes=1)
2593
+ return self.offset
2594
+
2595
+ v = Varies()
2596
+ t1 = t2.replace(tzinfo=v)
2597
+ t2 = t2.replace(tzinfo=v)
2598
+ self.assertEqual(t1.utcoffset(), timedelta(minutes=23))
2599
+ self.assertEqual(t2.utcoffset(), timedelta(minutes=24))
2600
+ self.assertEqual(t1, t2)
2601
+
2602
+ # But if they're not identical, it isn't ignored.
2603
+ t2 = t2.replace(tzinfo=Varies())
2604
+ self.failUnless(t1 < t2) # t1's offset counter still going up
2605
+
2606
+ # Pain to set up DST-aware tzinfo classes.
2607
+
2608
+ def first_sunday_on_or_after(dt):
2609
+ days_to_go = 6 - dt.weekday()
2610
+ if days_to_go:
2611
+ dt += timedelta(days_to_go)
2612
+ return dt
2613
+
2614
+ ZERO = timedelta(0)
2615
+ HOUR = timedelta(hours=1)
2616
+ DAY = timedelta(days=1)
2617
+ # In the US, DST starts at 2am (standard time) on the first Sunday in April.
2618
+ DSTSTART = datetime(1, 4, 1, 2)
2619
+ # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct,
2620
+ # which is the first Sunday on or after Oct 25. Because we view 1:MM as
2621
+ # being standard time on that day, there is no spelling in local time of
2622
+ # the last hour of DST (that's 1:MM DST, but 1:MM is taken as standard time).
2623
+ DSTEND = datetime(1, 10, 25, 1)
2624
+
2625
+ class USTimeZone(tzinfo):
2626
+
2627
+ def __init__(self, hours, reprname, stdname, dstname):
2628
+ self.stdoffset = timedelta(hours=hours)
2629
+ self.reprname = reprname
2630
+ self.stdname = stdname
2631
+ self.dstname = dstname
2632
+
2633
+ def __repr__(self):
2634
+ return self.reprname
2635
+
2636
+ def tzname(self, dt):
2637
+ if self.dst(dt):
2638
+ return self.dstname
2639
+ else:
2640
+ return self.stdname
2641
+
2642
+ def utcoffset(self, dt):
2643
+ return self.stdoffset + self.dst(dt)
2644
+
2645
+ def dst(self, dt):
2646
+ if dt is None or dt.tzinfo is None:
2647
+ # An exception instead may be sensible here, in one or more of
2648
+ # the cases.
2649
+ return ZERO
2650
+ assert dt.tzinfo is self
2651
+
2652
+ # Find first Sunday in April.
2653
+ start = first_sunday_on_or_after(DSTSTART.replace(year=dt.year))
2654
+ assert start.weekday() == 6 and start.month == 4 and start.day <= 7
2655
+
2656
+ # Find last Sunday in October.
2657
+ end = first_sunday_on_or_after(DSTEND.replace(year=dt.year))
2658
+ assert end.weekday() == 6 and end.month == 10 and end.day >= 25
2659
+
2660
+ # Can't compare naive to aware objects, so strip the timezone from
2661
+ # dt first.
2662
+ if start <= dt.replace(tzinfo=None) < end:
2663
+ return HOUR
2664
+ else:
2665
+ return ZERO
2666
+
2667
+ Eastern = USTimeZone(-5, "Eastern", "EST", "EDT")
2668
+ Central = USTimeZone(-6, "Central", "CST", "CDT")
2669
+ Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
2670
+ Pacific = USTimeZone(-8, "Pacific", "PST", "PDT")
2671
+ utc_real = FixedOffset(0, "UTC", 0)
2672
+ # For better test coverage, we want another flavor of UTC that's west of
2673
+ # the Eastern and Pacific timezones.
2674
+ utc_fake = FixedOffset(-12*60, "UTCfake", 0)
2675
+
2676
+ class TestTimezoneConversions(unittest.TestCase):
2677
+ # The DST switch times for 2002, in std time.
2678
+ dston = datetime(2002, 4, 7, 2)
2679
+ dstoff = datetime(2002, 10, 27, 1)
2680
+
2681
+ theclass = datetime
2682
+
2683
+ # Check a time that's inside DST.
2684
+ def checkinside(self, dt, tz, utc, dston, dstoff):
2685
+ self.assertEqual(dt.dst(), HOUR)
2686
+
2687
+ # Conversion to our own timezone is always an identity.
2688
+ self.assertEqual(dt.astimezone(tz), dt)
2689
+
2690
+ asutc = dt.astimezone(utc)
2691
+ there_and_back = asutc.astimezone(tz)
2692
+
2693
+ # Conversion to UTC and back isn't always an identity here,
2694
+ # because there are redundant spellings (in local time) of
2695
+ # UTC time when DST begins: the clock jumps from 1:59:59
2696
+ # to 3:00:00, and a local time of 2:MM:SS doesn't really
2697
+ # make sense then. The classes above treat 2:MM:SS as
2698
+ # daylight time then (it's "after 2am"), really an alias
2699
+ # for 1:MM:SS standard time. The latter form is what
2700
+ # conversion back from UTC produces.
2701
+ if dt.date() == dston.date() and dt.hour == 2:
2702
+ # We're in the redundant hour, and coming back from
2703
+ # UTC gives the 1:MM:SS standard-time spelling.
2704
+ self.assertEqual(there_and_back + HOUR, dt)
2705
+ # Although during was considered to be in daylight
2706
+ # time, there_and_back is not.
2707
+ self.assertEqual(there_and_back.dst(), ZERO)
2708
+ # They're the same times in UTC.
2709
+ self.assertEqual(there_and_back.astimezone(utc),
2710
+ dt.astimezone(utc))
2711
+ else:
2712
+ # We're not in the redundant hour.
2713
+ self.assertEqual(dt, there_and_back)
2714
+
2715
+ # Because we have a redundant spelling when DST begins, there is
2716
+ # (unforunately) an hour when DST ends that can't be spelled at all in
2717
+ # local time. When DST ends, the clock jumps from 1:59 back to 1:00
2718
+ # again. The hour 1:MM DST has no spelling then: 1:MM is taken to be
2719
+ # standard time. 1:MM DST == 0:MM EST, but 0:MM is taken to be
2720
+ # daylight time. The hour 1:MM daylight == 0:MM standard can't be
2721
+ # expressed in local time. Nevertheless, we want conversion back
2722
+ # from UTC to mimic the local clock's "repeat an hour" behavior.
2723
+ nexthour_utc = asutc + HOUR
2724
+ nexthour_tz = nexthour_utc.astimezone(tz)
2725
+ if dt.date() == dstoff.date() and dt.hour == 0:
2726
+ # We're in the hour before the last DST hour. The last DST hour
2727
+ # is ineffable. We want the conversion back to repeat 1:MM.
2728
+ self.assertEqual(nexthour_tz, dt.replace(hour=1))
2729
+ nexthour_utc += HOUR
2730
+ nexthour_tz = nexthour_utc.astimezone(tz)
2731
+ self.assertEqual(nexthour_tz, dt.replace(hour=1))
2732
+ else:
2733
+ self.assertEqual(nexthour_tz - dt, HOUR)
2734
+
2735
+ # Check a time that's outside DST.
2736
+ def checkoutside(self, dt, tz, utc):
2737
+ self.assertEqual(dt.dst(), ZERO)
2738
+
2739
+ # Conversion to our own timezone is always an identity.
2740
+ self.assertEqual(dt.astimezone(tz), dt)
2741
+
2742
+ # Converting to UTC and back is an identity too.
2743
+ asutc = dt.astimezone(utc)
2744
+ there_and_back = asutc.astimezone(tz)
2745
+ self.assertEqual(dt, there_and_back)
2746
+
2747
+ def convert_between_tz_and_utc(self, tz, utc):
2748
+ dston = self.dston.replace(tzinfo=tz)
2749
+ # Because 1:MM on the day DST ends is taken as being standard time,
2750
+ # there is no spelling in tz for the last hour of daylight time.
2751
+ # For purposes of the test, the last hour of DST is 0:MM, which is
2752
+ # taken as being daylight time (and 1:MM is taken as being standard
2753
+ # time).
2754
+ dstoff = self.dstoff.replace(tzinfo=tz)
2755
+ for delta in (timedelta(weeks=13),
2756
+ DAY,
2757
+ HOUR,
2758
+ timedelta(minutes=1),
2759
+ timedelta(microseconds=1)):
2760
+
2761
+ self.checkinside(dston, tz, utc, dston, dstoff)
2762
+ for during in dston + delta, dstoff - delta:
2763
+ self.checkinside(during, tz, utc, dston, dstoff)
2764
+
2765
+ self.checkoutside(dstoff, tz, utc)
2766
+ for outside in dston - delta, dstoff + delta:
2767
+ self.checkoutside(outside, tz, utc)
2768
+
2769
+ def test_easy(self):
2770
+ # Despite the name of this test, the endcases are excruciating.
2771
+ self.convert_between_tz_and_utc(Eastern, utc_real)
2772
+ self.convert_between_tz_and_utc(Pacific, utc_real)
2773
+ self.convert_between_tz_and_utc(Eastern, utc_fake)
2774
+ self.convert_between_tz_and_utc(Pacific, utc_fake)
2775
+ # The next is really dancing near the edge. It works because
2776
+ # Pacific and Eastern are far enough apart that their "problem
2777
+ # hours" don't overlap.
2778
+ self.convert_between_tz_and_utc(Eastern, Pacific)
2779
+ self.convert_between_tz_and_utc(Pacific, Eastern)
2780
+ # OTOH, these fail! Don't enable them. The difficulty is that
2781
+ # the edge case tests assume that every hour is representable in
2782
+ # the "utc" class. This is always true for a fixed-offset tzinfo
2783
+ # class (lke utc_real and utc_fake), but not for Eastern or Central.
2784
+ # For these adjacent DST-aware time zones, the range of time offsets
2785
+ # tested ends up creating hours in the one that aren't representable
2786
+ # in the other. For the same reason, we would see failures in the
2787
+ # Eastern vs Pacific tests too if we added 3*HOUR to the list of
2788
+ # offset deltas in convert_between_tz_and_utc().
2789
+ #
2790
+ # self.convert_between_tz_and_utc(Eastern, Central) # can't work
2791
+ # self.convert_between_tz_and_utc(Central, Eastern) # can't work
2792
+
2793
+ def test_tricky(self):
2794
+ # 22:00 on day before daylight starts.
2795
+ fourback = self.dston - timedelta(hours=4)
2796
+ ninewest = FixedOffset(-9*60, "-0900", 0)
2797
+ fourback = fourback.replace(tzinfo=ninewest)
2798
+ # 22:00-0900 is 7:00 UTC == 2:00 EST == 3:00 DST. Since it's "after
2799
+ # 2", we should get the 3 spelling.
2800
+ # If we plug 22:00 the day before into Eastern, it "looks like std
2801
+ # time", so its offset is returned as -5, and -5 - -9 = 4. Adding 4
2802
+ # to 22:00 lands on 2:00, which makes no sense in local time (the
2803
+ # local clock jumps from 1 to 3). The point here is to make sure we
2804
+ # get the 3 spelling.
2805
+ expected = self.dston.replace(hour=3)
2806
+ got = fourback.astimezone(Eastern).replace(tzinfo=None)
2807
+ self.assertEqual(expected, got)
2808
+
2809
+ # Similar, but map to 6:00 UTC == 1:00 EST == 2:00 DST. In that
2810
+ # case we want the 1:00 spelling.
2811
+ sixutc = self.dston.replace(hour=6, tzinfo=utc_real)
2812
+ # Now 6:00 "looks like daylight", so the offset wrt Eastern is -4,
2813
+ # and adding -4-0 == -4 gives the 2:00 spelling. We want the 1:00 EST
2814
+ # spelling.
2815
+ expected = self.dston.replace(hour=1)
2816
+ got = sixutc.astimezone(Eastern).replace(tzinfo=None)
2817
+ self.assertEqual(expected, got)
2818
+
2819
+ # Now on the day DST ends, we want "repeat an hour" behavior.
2820
+ # UTC 4:MM 5:MM 6:MM 7:MM checking these
2821
+ # EST 23:MM 0:MM 1:MM 2:MM
2822
+ # EDT 0:MM 1:MM 2:MM 3:MM
2823
+ # wall 0:MM 1:MM 1:MM 2:MM against these
2824
+ for utc in utc_real, utc_fake:
2825
+ for tz in Eastern, Pacific:
2826
+ first_std_hour = self.dstoff - timedelta(hours=2) # 23:MM
2827
+ # Convert that to UTC.
2828
+ first_std_hour -= tz.utcoffset(None)
2829
+ # Adjust for possibly fake UTC.
2830
+ asutc = first_std_hour + utc.utcoffset(None)
2831
+ # First UTC hour to convert; this is 4:00 when utc=utc_real &
2832
+ # tz=Eastern.
2833
+ asutcbase = asutc.replace(tzinfo=utc)
2834
+ for tzhour in (0, 1, 1, 2):
2835
+ expectedbase = self.dstoff.replace(hour=tzhour)
2836
+ for minute in 0, 30, 59:
2837
+ expected = expectedbase.replace(minute=minute)
2838
+ asutc = asutcbase.replace(minute=minute)
2839
+ astz = asutc.astimezone(tz)
2840
+ self.assertEqual(astz.replace(tzinfo=None), expected)
2841
+ asutcbase += HOUR
2842
+
2843
+
2844
+ def test_bogus_dst(self):
2845
+ class ok(tzinfo):
2846
+ def utcoffset(self, dt): return HOUR
2847
+ def dst(self, dt): return HOUR
2848
+
2849
+ now = self.theclass.now().replace(tzinfo=utc_real)
2850
+ # Doesn't blow up.
2851
+ now.astimezone(ok())
2852
+
2853
+ # Does blow up.
2854
+ class notok(ok):
2855
+ def dst(self, dt): return None
2856
+ self.assertRaises(ValueError, now.astimezone, notok())
2857
+
2858
+ def test_fromutc(self):
2859
+ self.assertRaises(TypeError, Eastern.fromutc) # not enough args
2860
+ now = datetime.utcnow().replace(tzinfo=utc_real)
2861
+ self.assertRaises(ValueError, Eastern.fromutc, now) # wrong tzinfo
2862
+ now = now.replace(tzinfo=Eastern) # insert correct tzinfo
2863
+ enow = Eastern.fromutc(now) # doesn't blow up
2864
+ self.assertEqual(enow.tzinfo, Eastern) # has right tzinfo member
2865
+ self.assertRaises(TypeError, Eastern.fromutc, now, now) # too many args
2866
+ self.assertRaises(TypeError, Eastern.fromutc, date.today()) # wrong type
2867
+
2868
+ # Always converts UTC to standard time.
2869
+ class FauxUSTimeZone(USTimeZone):
2870
+ def fromutc(self, dt):
2871
+ return dt + self.stdoffset
2872
+ FEastern = FauxUSTimeZone(-5, "FEastern", "FEST", "FEDT")
2873
+
2874
+ # UTC 4:MM 5:MM 6:MM 7:MM 8:MM 9:MM
2875
+ # EST 23:MM 0:MM 1:MM 2:MM 3:MM 4:MM
2876
+ # EDT 0:MM 1:MM 2:MM 3:MM 4:MM 5:MM
2877
+
2878
+ # Check around DST start.
2879
+ start = self.dston.replace(hour=4, tzinfo=Eastern)
2880
+ fstart = start.replace(tzinfo=FEastern)
2881
+ for wall in 23, 0, 1, 3, 4, 5:
2882
+ expected = start.replace(hour=wall)
2883
+ if wall == 23:
2884
+ expected -= timedelta(days=1)
2885
+ got = Eastern.fromutc(start)
2886
+ self.assertEqual(expected, got)
2887
+
2888
+ expected = fstart + FEastern.stdoffset
2889
+ got = FEastern.fromutc(fstart)
2890
+ self.assertEqual(expected, got)
2891
+
2892
+ # Ensure astimezone() calls fromutc() too.
2893
+ got = fstart.replace(tzinfo=utc_real).astimezone(FEastern)
2894
+ self.assertEqual(expected, got)
2895
+
2896
+ start += HOUR
2897
+ fstart += HOUR
2898
+
2899
+ # Check around DST end.
2900
+ start = self.dstoff.replace(hour=4, tzinfo=Eastern)
2901
+ fstart = start.replace(tzinfo=FEastern)
2902
+ for wall in 0, 1, 1, 2, 3, 4:
2903
+ expected = start.replace(hour=wall)
2904
+ got = Eastern.fromutc(start)
2905
+ self.assertEqual(expected, got)
2906
+
2907
+ expected = fstart + FEastern.stdoffset
2908
+ got = FEastern.fromutc(fstart)
2909
+ self.assertEqual(expected, got)
2910
+
2911
+ # Ensure astimezone() calls fromutc() too.
2912
+ got = fstart.replace(tzinfo=utc_real).astimezone(FEastern)
2913
+ self.assertEqual(expected, got)
2914
+
2915
+ start += HOUR
2916
+ fstart += HOUR
2917
+
2918
+ def test_suite():
2919
+ allsuites = [unittest.makeSuite(klass, 'test')
2920
+ for klass in (TestModule,
2921
+ TestTZInfo,
2922
+ TestTimeDelta,
2923
+ TestDateOnly,
2924
+ TestDate,
2925
+ TestDateTime,
2926
+ TestTime,
2927
+ TestTimeTZ,
2928
+ TestDateTimeTZ,
2929
+ TestTimezoneConversions,
2930
+ )
2931
+ ]
2932
+ return unittest.TestSuite(allsuites)
2933
+
2934
+ def test_main():
2935
+ #import gc
2936
+ import sys
2937
+
2938
+ s = test_suite()
2939
+ lastrc = None
2940
+ while True:
2941
+ test_support.run_suite(s)
2942
+ if 1: # change to 0, under a debug build, for some leak detection
2943
+ break
2944
+ gc.collect()
2945
+ if gc.garbage:
2946
+ raise SystemError("gc.garbage not empty after test run: %r" %
2947
+ gc.garbage)
2948
+ if hasattr(sys, 'gettotalrefcount'):
2949
+ thisrc = sys.gettotalrefcount()
2950
+ print >> sys.stderr, '*' * 10, 'total refs:', thisrc,
2951
+ if lastrc:
2952
+ print >> sys.stderr, 'delta:', thisrc - lastrc
2953
+ else:
2954
+ print >> sys.stderr
2955
+ lastrc = thisrc
2956
+
2957
+ if __name__ == "__main__":
2958
+ test_main()