rubyfox-server 2.3.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (993) hide show
  1. data/.gitignore +17 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +23 -0
  6. data/Rakefile +1 -0
  7. data/bin/smartfox +7 -0
  8. data/lib/rubyfox/server/cli.rb +59 -0
  9. data/lib/rubyfox/server/data/config/.keep +0 -0
  10. data/lib/rubyfox/server/data/config/_backups/.keep +0 -0
  11. data/lib/rubyfox/server/data/config/ascii/boot.txt +5 -0
  12. data/lib/rubyfox/server/data/config/ascii/ready.txt +9 -0
  13. data/lib/rubyfox/server/data/config/core.xml +44 -0
  14. data/lib/rubyfox/server/data/config/crossdomain.xml +10 -0
  15. data/lib/rubyfox/server/data/config/descriptors/.keep +0 -0
  16. data/lib/rubyfox/server/data/config/descriptors/config_room.txt +323 -0
  17. data/lib/rubyfox/server/data/config/descriptors/config_server.txt +621 -0
  18. data/lib/rubyfox/server/data/config/descriptors/config_zone.txt +1021 -0
  19. data/lib/rubyfox/server/data/config/descriptors/runtime_game.txt +63 -0
  20. data/lib/rubyfox/server/data/config/descriptors/runtime_room.txt +377 -0
  21. data/lib/rubyfox/server/data/config/descriptors/runtime_user.txt +589 -0
  22. data/lib/rubyfox/server/data/config/descriptors/runtime_zone.txt +354 -0
  23. data/lib/rubyfox/server/data/config/jetty/.keep +0 -0
  24. data/lib/rubyfox/server/data/config/jetty/jetty.xml +214 -0
  25. data/lib/rubyfox/server/data/config/jetty/realm.properties +21 -0
  26. data/lib/rubyfox/server/data/config/jetty/webdefault.xml +410 -0
  27. data/lib/rubyfox/server/data/config/log4j.properties +75 -0
  28. data/lib/rubyfox/server/data/config/myprop.properties +5 -0
  29. data/lib/rubyfox/server/data/config/server.xml +65 -0
  30. data/lib/rubyfox/server/data/config/templates/sfs2x.unix.txt +12 -0
  31. data/lib/rubyfox/server/data/config/templates/sfs2x.windows.txt +1 -0
  32. data/lib/rubyfox/server/data/config/templates/vmoptions.txt +3 -0
  33. data/lib/rubyfox/server/data/config/wordsFile.txt +13 -0
  34. data/lib/rubyfox/server/data/data/bannedusers/.keep +0 -0
  35. data/lib/rubyfox/server/data/data/bannedusers/users.bin +0 -0
  36. data/lib/rubyfox/server/data/data/buddylists/.keep +0 -0
  37. data/lib/rubyfox/server/data/data/buddylists/BasicExamples/7364666773646667 +0 -0
  38. data/lib/rubyfox/server/data/extensions/.keep +0 -0
  39. data/lib/rubyfox/server/data/extensions/__lib__/.keep +0 -0
  40. data/lib/rubyfox/server/data/lib/Jetty/.keep +0 -0
  41. data/lib/rubyfox/server/data/lib/Jetty/ant-1.6.5.jar +0 -0
  42. data/lib/rubyfox/server/data/lib/Jetty/core-3.1.1.jar +0 -0
  43. data/lib/rubyfox/server/data/lib/Jetty/jetty-6.1.26.jar +0 -0
  44. data/lib/rubyfox/server/data/lib/Jetty/jetty-util-6.1.26.jar +0 -0
  45. data/lib/rubyfox/server/data/lib/Jetty/jsp-2.1-glassfish-2.1.v20091210.jar +0 -0
  46. data/lib/rubyfox/server/data/lib/Jetty/jsp-2.1-jetty-6.1.26.jar +0 -0
  47. data/lib/rubyfox/server/data/lib/Jetty/jsp-api-2.1-glassfish-2.1.v20091210.jar +0 -0
  48. data/lib/rubyfox/server/data/lib/Jetty/servlet-api-2.5-20081211.jar +0 -0
  49. data/lib/rubyfox/server/data/lib/Lib/BaseHTTPServer.py +484 -0
  50. data/lib/rubyfox/server/data/lib/Lib/CGIHTTPServer.py +325 -0
  51. data/lib/rubyfox/server/data/lib/Lib/ConfigParser.py +472 -0
  52. data/lib/rubyfox/server/data/lib/Lib/Cookie.py +742 -0
  53. data/lib/rubyfox/server/data/lib/Lib/HTMLParser.py +383 -0
  54. data/lib/rubyfox/server/data/lib/Lib/MimeWriter.py +181 -0
  55. data/lib/rubyfox/server/data/lib/Lib/Queue.py +151 -0
  56. data/lib/rubyfox/server/data/lib/Lib/SimpleHTTPServer.py +198 -0
  57. data/lib/rubyfox/server/data/lib/Lib/SimpleXMLRPCServer.py +274 -0
  58. data/lib/rubyfox/server/data/lib/Lib/SocketServer.py +576 -0
  59. data/lib/rubyfox/server/data/lib/Lib/StringIO.py +239 -0
  60. data/lib/rubyfox/server/data/lib/Lib/UserDict$py.class +0 -0
  61. data/lib/rubyfox/server/data/lib/Lib/UserDict.py +60 -0
  62. data/lib/rubyfox/server/data/lib/Lib/UserList.py +94 -0
  63. data/lib/rubyfox/server/data/lib/Lib/UserString.py +182 -0
  64. data/lib/rubyfox/server/data/lib/Lib/__future__$py.class +0 -0
  65. data/lib/rubyfox/server/data/lib/Lib/__future__.py +104 -0
  66. data/lib/rubyfox/server/data/lib/Lib/aifc.py +961 -0
  67. data/lib/rubyfox/server/data/lib/Lib/anydbm.py +86 -0
  68. data/lib/rubyfox/server/data/lib/Lib/atexit.py +50 -0
  69. data/lib/rubyfox/server/data/lib/Lib/base64.py +77 -0
  70. data/lib/rubyfox/server/data/lib/Lib/bdb.py +563 -0
  71. data/lib/rubyfox/server/data/lib/Lib/binhex.py +531 -0
  72. data/lib/rubyfox/server/data/lib/Lib/bisect.py +78 -0
  73. data/lib/rubyfox/server/data/lib/Lib/calendar.py +246 -0
  74. data/lib/rubyfox/server/data/lib/Lib/cgi.py +1040 -0
  75. data/lib/rubyfox/server/data/lib/Lib/chunk.py +167 -0
  76. data/lib/rubyfox/server/data/lib/Lib/cmd.py +336 -0
  77. data/lib/rubyfox/server/data/lib/Lib/code$py.class +0 -0
  78. data/lib/rubyfox/server/data/lib/Lib/code.py +311 -0
  79. data/lib/rubyfox/server/data/lib/Lib/codecs$py.class +0 -0
  80. data/lib/rubyfox/server/data/lib/Lib/codecs.py +636 -0
  81. data/lib/rubyfox/server/data/lib/Lib/codeop$py.class +0 -0
  82. data/lib/rubyfox/server/data/lib/Lib/codeop.py +131 -0
  83. data/lib/rubyfox/server/data/lib/Lib/colorsys.py +123 -0
  84. data/lib/rubyfox/server/data/lib/Lib/commands.py +84 -0
  85. data/lib/rubyfox/server/data/lib/Lib/compileall.py +148 -0
  86. data/lib/rubyfox/server/data/lib/Lib/copy.py +330 -0
  87. data/lib/rubyfox/server/data/lib/Lib/copy_reg$py.class +0 -0
  88. data/lib/rubyfox/server/data/lib/Lib/copy_reg.py +78 -0
  89. data/lib/rubyfox/server/data/lib/Lib/datetime$py.class +0 -0
  90. data/lib/rubyfox/server/data/lib/Lib/datetime.py +2007 -0
  91. data/lib/rubyfox/server/data/lib/Lib/dbexts.py +726 -0
  92. data/lib/rubyfox/server/data/lib/Lib/difflib.py +1088 -0
  93. data/lib/rubyfox/server/data/lib/Lib/dircache.py +44 -0
  94. data/lib/rubyfox/server/data/lib/Lib/doctest.py +1173 -0
  95. data/lib/rubyfox/server/data/lib/Lib/dospath.py +341 -0
  96. data/lib/rubyfox/server/data/lib/Lib/dumbdbm.py +170 -0
  97. data/lib/rubyfox/server/data/lib/Lib/email/Charset.py +393 -0
  98. data/lib/rubyfox/server/data/lib/Lib/email/Encoders.py +94 -0
  99. data/lib/rubyfox/server/data/lib/Lib/email/Errors.py +26 -0
  100. data/lib/rubyfox/server/data/lib/Lib/email/Generator.py +378 -0
  101. data/lib/rubyfox/server/data/lib/Lib/email/Header.py +515 -0
  102. data/lib/rubyfox/server/data/lib/Lib/email/Iterators.py +25 -0
  103. data/lib/rubyfox/server/data/lib/Lib/email/MIMEAudio.py +71 -0
  104. data/lib/rubyfox/server/data/lib/Lib/email/MIMEBase.py +24 -0
  105. data/lib/rubyfox/server/data/lib/Lib/email/MIMEImage.py +45 -0
  106. data/lib/rubyfox/server/data/lib/Lib/email/MIMEMessage.py +32 -0
  107. data/lib/rubyfox/server/data/lib/Lib/email/MIMEMultipart.py +37 -0
  108. data/lib/rubyfox/server/data/lib/Lib/email/MIMENonMultipart.py +24 -0
  109. data/lib/rubyfox/server/data/lib/Lib/email/MIMEText.py +45 -0
  110. data/lib/rubyfox/server/data/lib/Lib/email/Message.py +837 -0
  111. data/lib/rubyfox/server/data/lib/Lib/email/Parser.py +292 -0
  112. data/lib/rubyfox/server/data/lib/Lib/email/Utils.py +340 -0
  113. data/lib/rubyfox/server/data/lib/Lib/email/__init__.py +72 -0
  114. data/lib/rubyfox/server/data/lib/Lib/email/_compat21.py +69 -0
  115. data/lib/rubyfox/server/data/lib/Lib/email/_compat22.py +70 -0
  116. data/lib/rubyfox/server/data/lib/Lib/email/_parseaddr.py +480 -0
  117. data/lib/rubyfox/server/data/lib/Lib/email/base64MIME.py +184 -0
  118. data/lib/rubyfox/server/data/lib/Lib/email/quopriMIME.py +323 -0
  119. data/lib/rubyfox/server/data/lib/Lib/email/test/__init__.py +2 -0
  120. data/lib/rubyfox/server/data/lib/Lib/email/test/data/PyBanner048.gif +0 -0
  121. data/lib/rubyfox/server/data/lib/Lib/email/test/data/audiotest.au +0 -0
  122. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_01.txt +19 -0
  123. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_02.txt +135 -0
  124. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_03.txt +16 -0
  125. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_04.txt +37 -0
  126. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_05.txt +28 -0
  127. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_06.txt +33 -0
  128. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_07.txt +83 -0
  129. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_08.txt +24 -0
  130. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_09.txt +24 -0
  131. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_10.txt +32 -0
  132. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_11.txt +7 -0
  133. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_12.txt +36 -0
  134. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_13.txt +94 -0
  135. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_14.txt +23 -0
  136. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_15.txt +52 -0
  137. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_16.txt +123 -0
  138. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_17.txt +12 -0
  139. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_18.txt +6 -0
  140. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_19.txt +43 -0
  141. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_20.txt +22 -0
  142. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_21.txt +20 -0
  143. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_22.txt +46 -0
  144. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_23.txt +8 -0
  145. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_24.txt +10 -0
  146. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_25.txt +117 -0
  147. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_26.txt +45 -0
  148. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_27.txt +15 -0
  149. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_28.txt +25 -0
  150. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_29.txt +22 -0
  151. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_30.txt +23 -0
  152. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_31.txt +15 -0
  153. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_32.txt +14 -0
  154. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_33.txt +29 -0
  155. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_34.txt +19 -0
  156. data/lib/rubyfox/server/data/lib/Lib/email/test/data/msg_35.txt +4 -0
  157. data/lib/rubyfox/server/data/lib/Lib/email/test/test_email.py +2718 -0
  158. data/lib/rubyfox/server/data/lib/Lib/email/test/test_email_codecs.py +68 -0
  159. data/lib/rubyfox/server/data/lib/Lib/email/test/test_email_torture.py +136 -0
  160. data/lib/rubyfox/server/data/lib/Lib/encodings/__init__$py.class +0 -0
  161. data/lib/rubyfox/server/data/lib/Lib/encodings/__init__.py +97 -0
  162. data/lib/rubyfox/server/data/lib/Lib/encodings/aliases$py.class +0 -0
  163. data/lib/rubyfox/server/data/lib/Lib/encodings/aliases.py +115 -0
  164. data/lib/rubyfox/server/data/lib/Lib/encodings/ascii.py +35 -0
  165. data/lib/rubyfox/server/data/lib/Lib/encodings/base64_codec.py +62 -0
  166. data/lib/rubyfox/server/data/lib/Lib/encodings/charmap.py +51 -0
  167. data/lib/rubyfox/server/data/lib/Lib/encodings/cp037.py +280 -0
  168. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1006.py +138 -0
  169. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1026.py +280 -0
  170. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1140.py +45 -0
  171. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1250.py +123 -0
  172. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1251.py +157 -0
  173. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1252.py +76 -0
  174. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1253.py +151 -0
  175. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1254.py +82 -0
  176. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1255.py +143 -0
  177. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1256.py +129 -0
  178. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1257.py +131 -0
  179. data/lib/rubyfox/server/data/lib/Lib/encodings/cp1258.py +90 -0
  180. data/lib/rubyfox/server/data/lib/Lib/encodings/cp424.py +280 -0
  181. data/lib/rubyfox/server/data/lib/Lib/encodings/cp437.py +172 -0
  182. data/lib/rubyfox/server/data/lib/Lib/encodings/cp500.py +280 -0
  183. data/lib/rubyfox/server/data/lib/Lib/encodings/cp737.py +172 -0
  184. data/lib/rubyfox/server/data/lib/Lib/encodings/cp775.py +172 -0
  185. data/lib/rubyfox/server/data/lib/Lib/encodings/cp850.py +172 -0
  186. data/lib/rubyfox/server/data/lib/Lib/encodings/cp852.py +172 -0
  187. data/lib/rubyfox/server/data/lib/Lib/encodings/cp855.py +172 -0
  188. data/lib/rubyfox/server/data/lib/Lib/encodings/cp856.py +172 -0
  189. data/lib/rubyfox/server/data/lib/Lib/encodings/cp857.py +171 -0
  190. data/lib/rubyfox/server/data/lib/Lib/encodings/cp860.py +172 -0
  191. data/lib/rubyfox/server/data/lib/Lib/encodings/cp861.py +172 -0
  192. data/lib/rubyfox/server/data/lib/Lib/encodings/cp862.py +172 -0
  193. data/lib/rubyfox/server/data/lib/Lib/encodings/cp863.py +172 -0
  194. data/lib/rubyfox/server/data/lib/Lib/encodings/cp864.py +170 -0
  195. data/lib/rubyfox/server/data/lib/Lib/encodings/cp865.py +172 -0
  196. data/lib/rubyfox/server/data/lib/Lib/encodings/cp866.py +172 -0
  197. data/lib/rubyfox/server/data/lib/Lib/encodings/cp869.py +172 -0
  198. data/lib/rubyfox/server/data/lib/Lib/encodings/cp874.py +171 -0
  199. data/lib/rubyfox/server/data/lib/Lib/encodings/cp875.py +281 -0
  200. data/lib/rubyfox/server/data/lib/Lib/encodings/hex_codec.py +62 -0
  201. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_1.py +44 -0
  202. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_10.py +90 -0
  203. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_13.py +100 -0
  204. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_14.py +75 -0
  205. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_15.py +52 -0
  206. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_2.py +101 -0
  207. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_3.py +79 -0
  208. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_4.py +94 -0
  209. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_5.py +138 -0
  210. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_6.py +137 -0
  211. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_7.py +124 -0
  212. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_8.py +112 -0
  213. data/lib/rubyfox/server/data/lib/Lib/encodings/iso8859_9.py +50 -0
  214. data/lib/rubyfox/server/data/lib/Lib/encodings/koi8_r.py +172 -0
  215. data/lib/rubyfox/server/data/lib/Lib/encodings/koi8_u.py +54 -0
  216. data/lib/rubyfox/server/data/lib/Lib/encodings/latin_1.py +35 -0
  217. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_cyrillic.py +167 -0
  218. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_greek.py +170 -0
  219. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_iceland.py +166 -0
  220. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_latin2.py +170 -0
  221. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_roman.py +167 -0
  222. data/lib/rubyfox/server/data/lib/Lib/encodings/mac_turkish.py +167 -0
  223. data/lib/rubyfox/server/data/lib/Lib/encodings/mbcs.py +36 -0
  224. data/lib/rubyfox/server/data/lib/Lib/encodings/quopri_codec.py +58 -0
  225. data/lib/rubyfox/server/data/lib/Lib/encodings/raw_unicode_escape.py +30 -0
  226. data/lib/rubyfox/server/data/lib/Lib/encodings/rot_13.py +105 -0
  227. data/lib/rubyfox/server/data/lib/Lib/encodings/undefined.py +34 -0
  228. data/lib/rubyfox/server/data/lib/Lib/encodings/unicode_escape.py +30 -0
  229. data/lib/rubyfox/server/data/lib/Lib/encodings/unicode_internal.py +30 -0
  230. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_16.py +61 -0
  231. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_16_be.py +31 -0
  232. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_16_le.py +31 -0
  233. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_7.py +27 -0
  234. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_8$py.class +0 -0
  235. data/lib/rubyfox/server/data/lib/Lib/encodings/utf_8.py +31 -0
  236. data/lib/rubyfox/server/data/lib/Lib/encodings/uu_codec.py +112 -0
  237. data/lib/rubyfox/server/data/lib/Lib/encodings/zlib_codec.py +63 -0
  238. data/lib/rubyfox/server/data/lib/Lib/fileinput.py +349 -0
  239. data/lib/rubyfox/server/data/lib/Lib/fnmatch.py +107 -0
  240. data/lib/rubyfox/server/data/lib/Lib/formatter.py +454 -0
  241. data/lib/rubyfox/server/data/lib/Lib/fpformat.py +142 -0
  242. data/lib/rubyfox/server/data/lib/Lib/ftplib.py +804 -0
  243. data/lib/rubyfox/server/data/lib/Lib/getopt.py +143 -0
  244. data/lib/rubyfox/server/data/lib/Lib/glob.py +56 -0
  245. data/lib/rubyfox/server/data/lib/Lib/gopherlib.py +205 -0
  246. data/lib/rubyfox/server/data/lib/Lib/gzip.py +390 -0
  247. data/lib/rubyfox/server/data/lib/Lib/hmac.py +99 -0
  248. data/lib/rubyfox/server/data/lib/Lib/htmlentitydefs.py +257 -0
  249. data/lib/rubyfox/server/data/lib/Lib/htmllib.py +475 -0
  250. data/lib/rubyfox/server/data/lib/Lib/httplib.py +1238 -0
  251. data/lib/rubyfox/server/data/lib/Lib/imaplib.py +1208 -0
  252. data/lib/rubyfox/server/data/lib/Lib/imghdr.py +154 -0
  253. data/lib/rubyfox/server/data/lib/Lib/inspect$py.class +0 -0
  254. data/lib/rubyfox/server/data/lib/Lib/inspect.py +787 -0
  255. data/lib/rubyfox/server/data/lib/Lib/isql.py +238 -0
  256. data/lib/rubyfox/server/data/lib/Lib/javaos$py.class +0 -0
  257. data/lib/rubyfox/server/data/lib/Lib/javaos.py +395 -0
  258. data/lib/rubyfox/server/data/lib/Lib/javapath$py.class +0 -0
  259. data/lib/rubyfox/server/data/lib/Lib/javapath.py +349 -0
  260. data/lib/rubyfox/server/data/lib/Lib/javashell.py +194 -0
  261. data/lib/rubyfox/server/data/lib/Lib/jreload.py +119 -0
  262. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/DiscardHelp.java +59 -0
  263. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/JavaLoaderFactory.java +9 -0
  264. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/PackageManager.java +58 -0
  265. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/PathVFS.java +98 -0
  266. data/lib/rubyfox/server/data/lib/Lib/jxxload_help/PathVFSJavaLoader.java +49 -0
  267. data/lib/rubyfox/server/data/lib/Lib/keyword.py +97 -0
  268. data/lib/rubyfox/server/data/lib/Lib/linecache$py.class +0 -0
  269. data/lib/rubyfox/server/data/lib/Lib/linecache.py +101 -0
  270. data/lib/rubyfox/server/data/lib/Lib/macpath.py +242 -0
  271. data/lib/rubyfox/server/data/lib/Lib/macurl2path.py +95 -0
  272. data/lib/rubyfox/server/data/lib/Lib/mailbox.py +313 -0
  273. data/lib/rubyfox/server/data/lib/Lib/mailcap.py +255 -0
  274. data/lib/rubyfox/server/data/lib/Lib/markupbase.py +317 -0
  275. data/lib/rubyfox/server/data/lib/Lib/marshal.py +315 -0
  276. data/lib/rubyfox/server/data/lib/Lib/mhlib.py +1003 -0
  277. data/lib/rubyfox/server/data/lib/Lib/mimetools.py +226 -0
  278. data/lib/rubyfox/server/data/lib/Lib/mimetypes.py +435 -0
  279. data/lib/rubyfox/server/data/lib/Lib/mimify.py +464 -0
  280. data/lib/rubyfox/server/data/lib/Lib/multifile.py +160 -0
  281. data/lib/rubyfox/server/data/lib/Lib/mutex.py +51 -0
  282. data/lib/rubyfox/server/data/lib/Lib/netrc.py +108 -0
  283. data/lib/rubyfox/server/data/lib/Lib/nntplib.py +575 -0
  284. data/lib/rubyfox/server/data/lib/Lib/ntpath.py +482 -0
  285. data/lib/rubyfox/server/data/lib/Lib/nturl2path.py +66 -0
  286. data/lib/rubyfox/server/data/lib/Lib/pawt/__init__.py +35 -0
  287. data/lib/rubyfox/server/data/lib/Lib/pawt/colors.py +144 -0
  288. data/lib/rubyfox/server/data/lib/Lib/pawt/swing.py +42 -0
  289. data/lib/rubyfox/server/data/lib/Lib/pdb.py +979 -0
  290. data/lib/rubyfox/server/data/lib/Lib/pickle.py +990 -0
  291. data/lib/rubyfox/server/data/lib/Lib/pipes.py +297 -0
  292. data/lib/rubyfox/server/data/lib/Lib/popen2.py +304 -0
  293. data/lib/rubyfox/server/data/lib/Lib/poplib.py +335 -0
  294. data/lib/rubyfox/server/data/lib/Lib/posixfile.py +240 -0
  295. data/lib/rubyfox/server/data/lib/Lib/posixpath.py +414 -0
  296. data/lib/rubyfox/server/data/lib/Lib/pprint.py +310 -0
  297. data/lib/rubyfox/server/data/lib/Lib/profile.py +556 -0
  298. data/lib/rubyfox/server/data/lib/Lib/pstats.py +641 -0
  299. data/lib/rubyfox/server/data/lib/Lib/pyclbr.py +337 -0
  300. data/lib/rubyfox/server/data/lib/Lib/quopri.py +237 -0
  301. data/lib/rubyfox/server/data/lib/Lib/random$py.class +0 -0
  302. data/lib/rubyfox/server/data/lib/Lib/random.py +779 -0
  303. data/lib/rubyfox/server/data/lib/Lib/re$py.class +0 -0
  304. data/lib/rubyfox/server/data/lib/Lib/re.py +11 -0
  305. data/lib/rubyfox/server/data/lib/Lib/reconvert.py +192 -0
  306. data/lib/rubyfox/server/data/lib/Lib/reindex$py.class +0 -0
  307. data/lib/rubyfox/server/data/lib/Lib/repr.py +95 -0
  308. data/lib/rubyfox/server/data/lib/Lib/rfc822.py +1010 -0
  309. data/lib/rubyfox/server/data/lib/Lib/sched.py +106 -0
  310. data/lib/rubyfox/server/data/lib/Lib/select.py +211 -0
  311. data/lib/rubyfox/server/data/lib/Lib/servlet-api-2.5-20081211.jar +0 -0
  312. data/lib/rubyfox/server/data/lib/Lib/setsfactory.py +10 -0
  313. data/lib/rubyfox/server/data/lib/Lib/sfs2x-lms.jar +0 -0
  314. data/lib/rubyfox/server/data/lib/Lib/sgmllib.py +516 -0
  315. data/lib/rubyfox/server/data/lib/Lib/shelve.py +158 -0
  316. data/lib/rubyfox/server/data/lib/Lib/shlex.py +209 -0
  317. data/lib/rubyfox/server/data/lib/Lib/shutil$py.class +0 -0
  318. data/lib/rubyfox/server/data/lib/Lib/shutil.py +138 -0
  319. data/lib/rubyfox/server/data/lib/Lib/site.py +263 -0
  320. data/lib/rubyfox/server/data/lib/Lib/smtplib.py +729 -0
  321. data/lib/rubyfox/server/data/lib/Lib/sndhdr.py +228 -0
  322. data/lib/rubyfox/server/data/lib/Lib/socket.py +902 -0
  323. data/lib/rubyfox/server/data/lib/Lib/sre$py.class +0 -0
  324. data/lib/rubyfox/server/data/lib/Lib/sre.py +311 -0
  325. data/lib/rubyfox/server/data/lib/Lib/sre_compile$py.class +0 -0
  326. data/lib/rubyfox/server/data/lib/Lib/sre_compile.py +455 -0
  327. data/lib/rubyfox/server/data/lib/Lib/sre_constants$py.class +0 -0
  328. data/lib/rubyfox/server/data/lib/Lib/sre_constants.py +259 -0
  329. data/lib/rubyfox/server/data/lib/Lib/sre_parse$py.class +0 -0
  330. data/lib/rubyfox/server/data/lib/Lib/sre_parse.py +738 -0
  331. data/lib/rubyfox/server/data/lib/Lib/stat$py.class +0 -0
  332. data/lib/rubyfox/server/data/lib/Lib/stat.py +86 -0
  333. data/lib/rubyfox/server/data/lib/Lib/string$py.class +0 -0
  334. data/lib/rubyfox/server/data/lib/Lib/string.py +437 -0
  335. data/lib/rubyfox/server/data/lib/Lib/symbol.py +95 -0
  336. data/lib/rubyfox/server/data/lib/Lib/telnetlib.py +662 -0
  337. data/lib/rubyfox/server/data/lib/Lib/tempfile.py +255 -0
  338. data/lib/rubyfox/server/data/lib/Lib/test/Graph.py +62 -0
  339. data/lib/rubyfox/server/data/lib/Lib/test/README +372 -0
  340. data/lib/rubyfox/server/data/lib/Lib/test/__init__.py +1 -0
  341. data/lib/rubyfox/server/data/lib/Lib/test/audiotest.au +0 -0
  342. data/lib/rubyfox/server/data/lib/Lib/test/autotest.py +6 -0
  343. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future3.py +10 -0
  344. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future4.py +10 -0
  345. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future5.py +12 -0
  346. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future6.py +10 -0
  347. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_future7.py +11 -0
  348. data/lib/rubyfox/server/data/lib/Lib/test/badsyntax_nocaret.py +2 -0
  349. data/lib/rubyfox/server/data/lib/Lib/test/blob.jar +0 -0
  350. data/lib/rubyfox/server/data/lib/Lib/test/bugs/bugs100.py +139 -0
  351. data/lib/rubyfox/server/data/lib/Lib/test/bugs/bugs101.py +57 -0
  352. data/lib/rubyfox/server/data/lib/Lib/test/bugs/jdkbugs.py +10 -0
  353. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr101.py +59 -0
  354. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr104.py +9 -0
  355. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr112.py +14 -0
  356. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr119.py +16 -0
  357. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr127.py +10 -0
  358. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr133/__init__.py +1 -0
  359. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr133/test.py +2 -0
  360. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr133.py +12 -0
  361. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr134.py +9 -0
  362. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr139.py +7 -0
  363. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr142.py +1 -0
  364. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr144.py +2 -0
  365. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr148.py +2 -0
  366. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr149.py +7 -0
  367. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr155.py +13 -0
  368. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr170.py +7 -0
  369. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr171.py +9 -0
  370. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr174.py +9 -0
  371. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr178.py +10 -0
  372. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr183.py +5 -0
  373. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr186.py +10 -0
  374. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr191.py +5 -0
  375. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr192.py +81 -0
  376. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr195.py +11 -0
  377. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr208.py +26 -0
  378. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr233.py +8 -0
  379. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr234.py +16 -0
  380. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr235.py +14 -0
  381. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr239.py +6 -0
  382. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr241.py +16 -0
  383. data/lib/rubyfox/server/data/lib/Lib/test/bugs/pr242.py +12 -0
  384. data/lib/rubyfox/server/data/lib/Lib/test/data/PyBanner048.gif +0 -0
  385. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_01.txt +19 -0
  386. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_02.txt +135 -0
  387. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_03.txt +16 -0
  388. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_04.txt +37 -0
  389. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_05.txt +28 -0
  390. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_06.txt +33 -0
  391. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_07.txt +83 -0
  392. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_08.txt +24 -0
  393. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_09.txt +24 -0
  394. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_10.txt +32 -0
  395. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_11.txt +7 -0
  396. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_12.txt +36 -0
  397. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_13.txt +94 -0
  398. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_14.txt +23 -0
  399. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_15.txt +52 -0
  400. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_16.txt +123 -0
  401. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_17.txt +12 -0
  402. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_18.txt +6 -0
  403. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_19.txt +43 -0
  404. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_20.txt +22 -0
  405. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_21.txt +22 -0
  406. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_22.txt +46 -0
  407. data/lib/rubyfox/server/data/lib/Lib/test/data/msg_23.txt +8 -0
  408. data/lib/rubyfox/server/data/lib/Lib/test/double_const.py +30 -0
  409. data/lib/rubyfox/server/data/lib/Lib/test/greyrgb.uue +1547 -0
  410. data/lib/rubyfox/server/data/lib/Lib/test/javatests/AnonInner.java +20 -0
  411. data/lib/rubyfox/server/data/lib/Lib/test/javatests/Foo.java +3 -0
  412. data/lib/rubyfox/server/data/lib/Lib/test/javatests/JOverload.java +132 -0
  413. data/lib/rubyfox/server/data/lib/Lib/test/javatests/ListTest.java +638 -0
  414. data/lib/rubyfox/server/data/lib/Lib/test/javatests/SubFoo.java +3 -0
  415. data/lib/rubyfox/server/data/lib/Lib/test/javatests/TestSupport.java +49 -0
  416. data/lib/rubyfox/server/data/lib/Lib/test/javatests/__init__.py +0 -0
  417. data/lib/rubyfox/server/data/lib/Lib/test/jser2_classes.py +47 -0
  418. data/lib/rubyfox/server/data/lib/Lib/test/output/test_MimeWriter +110 -0
  419. data/lib/rubyfox/server/data/lib/Lib/test/output/test_array +4 -0
  420. data/lib/rubyfox/server/data/lib/Lib/test/output/test_asynchat +3 -0
  421. data/lib/rubyfox/server/data/lib/Lib/test/output/test_augassign +51 -0
  422. data/lib/rubyfox/server/data/lib/Lib/test/output/test_binascii +29 -0
  423. data/lib/rubyfox/server/data/lib/Lib/test/output/test_builtin +53 -0
  424. data/lib/rubyfox/server/data/lib/Lib/test/output/test_cfgparser +9 -0
  425. data/lib/rubyfox/server/data/lib/Lib/test/output/test_cgi +29 -0
  426. data/lib/rubyfox/server/data/lib/Lib/test/output/test_charmapcodec +16 -0
  427. data/lib/rubyfox/server/data/lib/Lib/test/output/test_class +101 -0
  428. data/lib/rubyfox/server/data/lib/Lib/test/output/test_coercion +1054 -0
  429. data/lib/rubyfox/server/data/lib/Lib/test/output/test_compare +101 -0
  430. data/lib/rubyfox/server/data/lib/Lib/test/output/test_compile +7 -0
  431. data/lib/rubyfox/server/data/lib/Lib/test/output/test_cookie +32 -0
  432. data/lib/rubyfox/server/data/lib/Lib/test/output/test_exceptions +52 -0
  433. data/lib/rubyfox/server/data/lib/Lib/test/output/test_extcall +112 -0
  434. data/lib/rubyfox/server/data/lib/Lib/test/output/test_frozen +4 -0
  435. data/lib/rubyfox/server/data/lib/Lib/test/output/test_future +9 -0
  436. data/lib/rubyfox/server/data/lib/Lib/test/output/test_gettext +46 -0
  437. data/lib/rubyfox/server/data/lib/Lib/test/output/test_global +5 -0
  438. data/lib/rubyfox/server/data/lib/Lib/test/output/test_grammar +66 -0
  439. data/lib/rubyfox/server/data/lib/Lib/test/output/test_httplib +10 -0
  440. data/lib/rubyfox/server/data/lib/Lib/test/output/test_janoninner +5 -0
  441. data/lib/rubyfox/server/data/lib/Lib/test/output/test_javalist +6 -0
  442. data/lib/rubyfox/server/data/lib/Lib/test/output/test_jbasic +13 -0
  443. data/lib/rubyfox/server/data/lib/Lib/test/output/test_jser +12 -0
  444. data/lib/rubyfox/server/data/lib/Lib/test/output/test_jsubclass +5 -0
  445. data/lib/rubyfox/server/data/lib/Lib/test/output/test_linuxaudiodev +7 -0
  446. data/lib/rubyfox/server/data/lib/Lib/test/output/test_longexp +2 -0
  447. data/lib/rubyfox/server/data/lib/Lib/test/output/test_math +26 -0
  448. data/lib/rubyfox/server/data/lib/Lib/test/output/test_md5 +9 -0
  449. data/lib/rubyfox/server/data/lib/Lib/test/output/test_methods +6 -0
  450. data/lib/rubyfox/server/data/lib/Lib/test/output/test_mimetools +5 -0
  451. data/lib/rubyfox/server/data/lib/Lib/test/output/test_mmap +34 -0
  452. data/lib/rubyfox/server/data/lib/Lib/test/output/test_new +7 -0
  453. data/lib/rubyfox/server/data/lib/Lib/test/output/test_nis +2 -0
  454. data/lib/rubyfox/server/data/lib/Lib/test/output/test_opcodes +4 -0
  455. data/lib/rubyfox/server/data/lib/Lib/test/output/test_openpty +2 -0
  456. data/lib/rubyfox/server/data/lib/Lib/test/output/test_operations +28 -0
  457. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pkg +45 -0
  458. data/lib/rubyfox/server/data/lib/Lib/test/output/test_poll +17 -0
  459. data/lib/rubyfox/server/data/lib/Lib/test/output/test_popen2 +9 -0
  460. data/lib/rubyfox/server/data/lib/Lib/test/output/test_posixpath +2 -0
  461. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pow +17 -0
  462. data/lib/rubyfox/server/data/lib/Lib/test/output/test_profile +17 -0
  463. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pty +3 -0
  464. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pwd +7 -0
  465. data/lib/rubyfox/server/data/lib/Lib/test/output/test_pyexpat +110 -0
  466. data/lib/rubyfox/server/data/lib/Lib/test/output/test_re +15 -0
  467. data/lib/rubyfox/server/data/lib/Lib/test/output/test_regex +29 -0
  468. data/lib/rubyfox/server/data/lib/Lib/test/output/test_rgbimg +2 -0
  469. data/lib/rubyfox/server/data/lib/Lib/test/output/test_richcmp +187 -0
  470. data/lib/rubyfox/server/data/lib/Lib/test/output/test_rotor +5 -0
  471. data/lib/rubyfox/server/data/lib/Lib/test/output/test_scope +24 -0
  472. data/lib/rubyfox/server/data/lib/Lib/test/output/test_signal +2 -0
  473. data/lib/rubyfox/server/data/lib/Lib/test/output/test_string +18 -0
  474. data/lib/rubyfox/server/data/lib/Lib/test/output/test_thread +4 -0
  475. data/lib/rubyfox/server/data/lib/Lib/test/output/test_threadedtempfile +5 -0
  476. data/lib/rubyfox/server/data/lib/Lib/test/output/test_time +9 -0
  477. data/lib/rubyfox/server/data/lib/Lib/test/output/test_tokenize +648 -0
  478. data/lib/rubyfox/server/data/lib/Lib/test/output/test_types +15 -0
  479. data/lib/rubyfox/server/data/lib/Lib/test/output/test_ucn +7 -0
  480. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unicode +21 -0
  481. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unicode_file +2 -0
  482. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unicodedata +5 -0
  483. data/lib/rubyfox/server/data/lib/Lib/test/output/test_unpack +15 -0
  484. data/lib/rubyfox/server/data/lib/Lib/test/output/test_urlparse +47 -0
  485. data/lib/rubyfox/server/data/lib/Lib/test/output/test_winreg +3 -0
  486. data/lib/rubyfox/server/data/lib/Lib/test/output/test_winsound +2 -0
  487. data/lib/rubyfox/server/data/lib/Lib/test/output/test_xreadline +4 -0
  488. data/lib/rubyfox/server/data/lib/Lib/test/pickletester.py +285 -0
  489. data/lib/rubyfox/server/data/lib/Lib/test/pydocfodder.py +210 -0
  490. data/lib/rubyfox/server/data/lib/Lib/test/pystone.py +252 -0
  491. data/lib/rubyfox/server/data/lib/Lib/test/re_tests.py +590 -0
  492. data/lib/rubyfox/server/data/lib/Lib/test/regex_tests.py +287 -0
  493. data/lib/rubyfox/server/data/lib/Lib/test/regrtest.py +1096 -0
  494. data/lib/rubyfox/server/data/lib/Lib/test/reperf.py +23 -0
  495. data/lib/rubyfox/server/data/lib/Lib/test/sortperf.py +141 -0
  496. data/lib/rubyfox/server/data/lib/Lib/test/string_tests.py +265 -0
  497. data/lib/rubyfox/server/data/lib/Lib/test/test.xml +115 -0
  498. data/lib/rubyfox/server/data/lib/Lib/test/test.xml.out +115 -0
  499. data/lib/rubyfox/server/data/lib/Lib/test/test_MimeWriter.py +170 -0
  500. data/lib/rubyfox/server/data/lib/Lib/test/test_SimpleXMLRPCServer.py +88 -0
  501. data/lib/rubyfox/server/data/lib/Lib/test/test_StringIO.py +113 -0
  502. data/lib/rubyfox/server/data/lib/Lib/test/test___all__.py +158 -0
  503. data/lib/rubyfox/server/data/lib/Lib/test/test___future__.py +59 -0
  504. data/lib/rubyfox/server/data/lib/Lib/test/test_al.py +23 -0
  505. data/lib/rubyfox/server/data/lib/Lib/test/test_array.py +438 -0
  506. data/lib/rubyfox/server/data/lib/Lib/test/test_asynchat.py +58 -0
  507. data/lib/rubyfox/server/data/lib/Lib/test/test_atexit.py +66 -0
  508. data/lib/rubyfox/server/data/lib/Lib/test/test_audioop.py +264 -0
  509. data/lib/rubyfox/server/data/lib/Lib/test/test_augassign.py +261 -0
  510. data/lib/rubyfox/server/data/lib/Lib/test/test_b1.py +632 -0
  511. data/lib/rubyfox/server/data/lib/Lib/test/test_b2.py +365 -0
  512. data/lib/rubyfox/server/data/lib/Lib/test/test_base64.py +53 -0
  513. data/lib/rubyfox/server/data/lib/Lib/test/test_bastion.py +3 -0
  514. data/lib/rubyfox/server/data/lib/Lib/test/test_binascii.py +119 -0
  515. data/lib/rubyfox/server/data/lib/Lib/test/test_binhex.py +50 -0
  516. data/lib/rubyfox/server/data/lib/Lib/test/test_binop.py +328 -0
  517. data/lib/rubyfox/server/data/lib/Lib/test/test_bisect.py +127 -0
  518. data/lib/rubyfox/server/data/lib/Lib/test/test_bsddb.py +76 -0
  519. data/lib/rubyfox/server/data/lib/Lib/test/test_bufio.py +60 -0
  520. data/lib/rubyfox/server/data/lib/Lib/test/test_bugfixes.py +31 -0
  521. data/lib/rubyfox/server/data/lib/Lib/test/test_builtin.py +13 -0
  522. data/lib/rubyfox/server/data/lib/Lib/test/test_calendar.py +61 -0
  523. data/lib/rubyfox/server/data/lib/Lib/test/test_call.py +131 -0
  524. data/lib/rubyfox/server/data/lib/Lib/test/test_capi.py +16 -0
  525. data/lib/rubyfox/server/data/lib/Lib/test/test_cd.py +26 -0
  526. data/lib/rubyfox/server/data/lib/Lib/test/test_cfgparser.py +284 -0
  527. data/lib/rubyfox/server/data/lib/Lib/test/test_cgi.py +188 -0
  528. data/lib/rubyfox/server/data/lib/Lib/test/test_charmapcodec.py +43 -0
  529. data/lib/rubyfox/server/data/lib/Lib/test/test_cl.py +78 -0
  530. data/lib/rubyfox/server/data/lib/Lib/test/test_class.py +317 -0
  531. data/lib/rubyfox/server/data/lib/Lib/test/test_cmath.py +35 -0
  532. data/lib/rubyfox/server/data/lib/Lib/test/test_codecs.py +31 -0
  533. data/lib/rubyfox/server/data/lib/Lib/test/test_codeop.py +190 -0
  534. data/lib/rubyfox/server/data/lib/Lib/test/test_coercion.py +118 -0
  535. data/lib/rubyfox/server/data/lib/Lib/test/test_commands.py +52 -0
  536. data/lib/rubyfox/server/data/lib/Lib/test/test_compare.py +56 -0
  537. data/lib/rubyfox/server/data/lib/Lib/test/test_compile.py +129 -0
  538. data/lib/rubyfox/server/data/lib/Lib/test/test_complex.py +68 -0
  539. data/lib/rubyfox/server/data/lib/Lib/test/test_contains.py +133 -0
  540. data/lib/rubyfox/server/data/lib/Lib/test/test_cookie.py +47 -0
  541. data/lib/rubyfox/server/data/lib/Lib/test/test_copy_reg.py +30 -0
  542. data/lib/rubyfox/server/data/lib/Lib/test/test_cpickle.py +81 -0
  543. data/lib/rubyfox/server/data/lib/Lib/test/test_crypt.py +11 -0
  544. data/lib/rubyfox/server/data/lib/Lib/test/test_curses.py +210 -0
  545. data/lib/rubyfox/server/data/lib/Lib/test/test_datetime.py +2958 -0
  546. data/lib/rubyfox/server/data/lib/Lib/test/test_dbm.py +43 -0
  547. data/lib/rubyfox/server/data/lib/Lib/test/test_descr.py +4094 -0
  548. data/lib/rubyfox/server/data/lib/Lib/test/test_descrtut.py +501 -0
  549. data/lib/rubyfox/server/data/lib/Lib/test/test_difflib.py +2 -0
  550. data/lib/rubyfox/server/data/lib/Lib/test/test_dircache.py +74 -0
  551. data/lib/rubyfox/server/data/lib/Lib/test/test_dl.py +33 -0
  552. data/lib/rubyfox/server/data/lib/Lib/test/test_doctest.py +2 -0
  553. data/lib/rubyfox/server/data/lib/Lib/test/test_doctest2.py +108 -0
  554. data/lib/rubyfox/server/data/lib/Lib/test/test_dospath.py +61 -0
  555. data/lib/rubyfox/server/data/lib/Lib/test/test_dumbdbm.py +79 -0
  556. data/lib/rubyfox/server/data/lib/Lib/test/test_email.py +13 -0
  557. data/lib/rubyfox/server/data/lib/Lib/test/test_email_codecs.py +11 -0
  558. data/lib/rubyfox/server/data/lib/Lib/test/test_enumerate.py +150 -0
  559. data/lib/rubyfox/server/data/lib/Lib/test/test_errno.py +49 -0
  560. data/lib/rubyfox/server/data/lib/Lib/test/test_exceptions.py +206 -0
  561. data/lib/rubyfox/server/data/lib/Lib/test/test_extcall.py +268 -0
  562. data/lib/rubyfox/server/data/lib/Lib/test/test_fcntl.py +53 -0
  563. data/lib/rubyfox/server/data/lib/Lib/test/test_file.py +63 -0
  564. data/lib/rubyfox/server/data/lib/Lib/test/test_fileinput.py +159 -0
  565. data/lib/rubyfox/server/data/lib/Lib/test/test_fnmatch.py +46 -0
  566. data/lib/rubyfox/server/data/lib/Lib/test/test_fork1.py +75 -0
  567. data/lib/rubyfox/server/data/lib/Lib/test/test_format.py +218 -0
  568. data/lib/rubyfox/server/data/lib/Lib/test/test_fpformat.py +75 -0
  569. data/lib/rubyfox/server/data/lib/Lib/test/test_frozen.py +26 -0
  570. data/lib/rubyfox/server/data/lib/Lib/test/test_funcattrs.py +384 -0
  571. data/lib/rubyfox/server/data/lib/Lib/test/test_future.py +47 -0
  572. data/lib/rubyfox/server/data/lib/Lib/test/test_future1.py +11 -0
  573. data/lib/rubyfox/server/data/lib/Lib/test/test_future2.py +10 -0
  574. data/lib/rubyfox/server/data/lib/Lib/test/test_future3.py +11 -0
  575. data/lib/rubyfox/server/data/lib/Lib/test/test_gc.py +346 -0
  576. data/lib/rubyfox/server/data/lib/Lib/test/test_gdbm.py +46 -0
  577. data/lib/rubyfox/server/data/lib/Lib/test/test_generators.py +1385 -0
  578. data/lib/rubyfox/server/data/lib/Lib/test/test_getargs.py +26 -0
  579. data/lib/rubyfox/server/data/lib/Lib/test/test_getopt.py +110 -0
  580. data/lib/rubyfox/server/data/lib/Lib/test/test_gettext.py +200 -0
  581. data/lib/rubyfox/server/data/lib/Lib/test/test_gl.py +150 -0
  582. data/lib/rubyfox/server/data/lib/Lib/test/test_glob.py +115 -0
  583. data/lib/rubyfox/server/data/lib/Lib/test/test_global.py +51 -0
  584. data/lib/rubyfox/server/data/lib/Lib/test/test_grammar.py +732 -0
  585. data/lib/rubyfox/server/data/lib/Lib/test/test_grp.py +27 -0
  586. data/lib/rubyfox/server/data/lib/Lib/test/test_gzip.py +82 -0
  587. data/lib/rubyfox/server/data/lib/Lib/test/test_hash.py +36 -0
  588. data/lib/rubyfox/server/data/lib/Lib/test/test_hmac.py +108 -0
  589. data/lib/rubyfox/server/data/lib/Lib/test/test_hotshot.py +117 -0
  590. data/lib/rubyfox/server/data/lib/Lib/test/test_htmllib.py +42 -0
  591. data/lib/rubyfox/server/data/lib/Lib/test/test_htmlparser.py +294 -0
  592. data/lib/rubyfox/server/data/lib/Lib/test/test_httplib.py +58 -0
  593. data/lib/rubyfox/server/data/lib/Lib/test/test_imageop.py +171 -0
  594. data/lib/rubyfox/server/data/lib/Lib/test/test_imgfile.py +116 -0
  595. data/lib/rubyfox/server/data/lib/Lib/test/test_import.py +71 -0
  596. data/lib/rubyfox/server/data/lib/Lib/test/test_importhooks.py +215 -0
  597. data/lib/rubyfox/server/data/lib/Lib/test/test_inspect.py +365 -0
  598. data/lib/rubyfox/server/data/lib/Lib/test/test_iter.py +784 -0
  599. data/lib/rubyfox/server/data/lib/Lib/test/test_janoninner.py +15 -0
  600. data/lib/rubyfox/server/data/lib/Lib/test/test_javalist.py +53 -0
  601. data/lib/rubyfox/server/data/lib/Lib/test/test_javashell.py +182 -0
  602. data/lib/rubyfox/server/data/lib/Lib/test/test_jbasic.py +119 -0
  603. data/lib/rubyfox/server/data/lib/Lib/test/test_joverload.py +138 -0
  604. data/lib/rubyfox/server/data/lib/Lib/test/test_jreload.py +33 -0
  605. data/lib/rubyfox/server/data/lib/Lib/test/test_jser.py +57 -0
  606. data/lib/rubyfox/server/data/lib/Lib/test/test_jser2.py +93 -0
  607. data/lib/rubyfox/server/data/lib/Lib/test/test_jsubclass.py +49 -0
  608. data/lib/rubyfox/server/data/lib/Lib/test/test_jy_compile.py +168 -0
  609. data/lib/rubyfox/server/data/lib/Lib/test/test_jy_generators.py +165 -0
  610. data/lib/rubyfox/server/data/lib/Lib/test/test_jy_internals.py +130 -0
  611. data/lib/rubyfox/server/data/lib/Lib/test/test_largefile.py +169 -0
  612. data/lib/rubyfox/server/data/lib/Lib/test/test_linuxaudiodev.py +89 -0
  613. data/lib/rubyfox/server/data/lib/Lib/test/test_locale.py +44 -0
  614. data/lib/rubyfox/server/data/lib/Lib/test/test_long.py +445 -0
  615. data/lib/rubyfox/server/data/lib/Lib/test/test_long_future.py +55 -0
  616. data/lib/rubyfox/server/data/lib/Lib/test/test_long_int_args.py +61 -0
  617. data/lib/rubyfox/server/data/lib/Lib/test/test_longexp.py +16 -0
  618. data/lib/rubyfox/server/data/lib/Lib/test/test_mailbox.py +113 -0
  619. data/lib/rubyfox/server/data/lib/Lib/test/test_marshal.py +44 -0
  620. data/lib/rubyfox/server/data/lib/Lib/test/test_math.py +153 -0
  621. data/lib/rubyfox/server/data/lib/Lib/test/test_md5.py +30 -0
  622. data/lib/rubyfox/server/data/lib/Lib/test/test_methods.py +62 -0
  623. data/lib/rubyfox/server/data/lib/Lib/test/test_mhlib.py +353 -0
  624. data/lib/rubyfox/server/data/lib/Lib/test/test_mimetools.py +18 -0
  625. data/lib/rubyfox/server/data/lib/Lib/test/test_mimetypes.py +59 -0
  626. data/lib/rubyfox/server/data/lib/Lib/test/test_minidom.py +648 -0
  627. data/lib/rubyfox/server/data/lib/Lib/test/test_mmap.py +317 -0
  628. data/lib/rubyfox/server/data/lib/Lib/test/test_module.py +77 -0
  629. data/lib/rubyfox/server/data/lib/Lib/test/test_multifile.py +66 -0
  630. data/lib/rubyfox/server/data/lib/Lib/test/test_mutants.py +285 -0
  631. data/lib/rubyfox/server/data/lib/Lib/test/test_netrc.py +42 -0
  632. data/lib/rubyfox/server/data/lib/Lib/test/test_new.py +108 -0
  633. data/lib/rubyfox/server/data/lib/Lib/test/test_nis.py +32 -0
  634. data/lib/rubyfox/server/data/lib/Lib/test/test_ntpath.py +114 -0
  635. data/lib/rubyfox/server/data/lib/Lib/test/test_opcodes.py +65 -0
  636. data/lib/rubyfox/server/data/lib/Lib/test/test_openpty.py +21 -0
  637. data/lib/rubyfox/server/data/lib/Lib/test/test_operations.py +475 -0
  638. data/lib/rubyfox/server/data/lib/Lib/test/test_operator.py +218 -0
  639. data/lib/rubyfox/server/data/lib/Lib/test/test_os.py +187 -0
  640. data/lib/rubyfox/server/data/lib/Lib/test/test_parser.py +383 -0
  641. data/lib/rubyfox/server/data/lib/Lib/test/test_pep247.py +50 -0
  642. data/lib/rubyfox/server/data/lib/Lib/test/test_pickle.py +40 -0
  643. data/lib/rubyfox/server/data/lib/Lib/test/test_pkg.py +259 -0
  644. data/lib/rubyfox/server/data/lib/Lib/test/test_pkgimport.py +84 -0
  645. data/lib/rubyfox/server/data/lib/Lib/test/test_poll.py +3 -0
  646. data/lib/rubyfox/server/data/lib/Lib/test/test_popen2.py +72 -0
  647. data/lib/rubyfox/server/data/lib/Lib/test/test_posixpath.py +40 -0
  648. data/lib/rubyfox/server/data/lib/Lib/test/test_pow.py +107 -0
  649. data/lib/rubyfox/server/data/lib/Lib/test/test_pprint.py +104 -0
  650. data/lib/rubyfox/server/data/lib/Lib/test/test_profile.py +86 -0
  651. data/lib/rubyfox/server/data/lib/Lib/test/test_profilehooks.py +360 -0
  652. data/lib/rubyfox/server/data/lib/Lib/test/test_pty.py +98 -0
  653. data/lib/rubyfox/server/data/lib/Lib/test/test_pwd.py +71 -0
  654. data/lib/rubyfox/server/data/lib/Lib/test/test_pyclbr.py +154 -0
  655. data/lib/rubyfox/server/data/lib/Lib/test/test_pyexpat.py +202 -0
  656. data/lib/rubyfox/server/data/lib/Lib/test/test_queue.py +158 -0
  657. data/lib/rubyfox/server/data/lib/Lib/test/test_quopri.py +157 -0
  658. data/lib/rubyfox/server/data/lib/Lib/test/test_random.py +19 -0
  659. data/lib/rubyfox/server/data/lib/Lib/test/test_re.py +304 -0
  660. data/lib/rubyfox/server/data/lib/Lib/test/test_regex.py +113 -0
  661. data/lib/rubyfox/server/data/lib/Lib/test/test_repr.py +278 -0
  662. data/lib/rubyfox/server/data/lib/Lib/test/test_rfc822.py +211 -0
  663. data/lib/rubyfox/server/data/lib/Lib/test/test_rgbimg.py +63 -0
  664. data/lib/rubyfox/server/data/lib/Lib/test/test_richcmp.py +261 -0
  665. data/lib/rubyfox/server/data/lib/Lib/test/test_rotor.py +28 -0
  666. data/lib/rubyfox/server/data/lib/Lib/test/test_sax.py +727 -0
  667. data/lib/rubyfox/server/data/lib/Lib/test/test_scope.py +530 -0
  668. data/lib/rubyfox/server/data/lib/Lib/test/test_select.py +228 -0
  669. data/lib/rubyfox/server/data/lib/Lib/test/test_select_new.py +229 -0
  670. data/lib/rubyfox/server/data/lib/Lib/test/test_sets.py +793 -0
  671. data/lib/rubyfox/server/data/lib/Lib/test/test_sgmllib.py +314 -0
  672. data/lib/rubyfox/server/data/lib/Lib/test/test_sha.py +52 -0
  673. data/lib/rubyfox/server/data/lib/Lib/test/test_signal.py +66 -0
  674. data/lib/rubyfox/server/data/lib/Lib/test/test_socket.py +1116 -0
  675. data/lib/rubyfox/server/data/lib/Lib/test/test_socket_ssl.py +27 -0
  676. data/lib/rubyfox/server/data/lib/Lib/test/test_socketserver.py +165 -0
  677. data/lib/rubyfox/server/data/lib/Lib/test/test_sre.py +434 -0
  678. data/lib/rubyfox/server/data/lib/Lib/test/test_str2unicode.py +90 -0
  679. data/lib/rubyfox/server/data/lib/Lib/test/test_strftime.py +146 -0
  680. data/lib/rubyfox/server/data/lib/Lib/test/test_string.py +223 -0
  681. data/lib/rubyfox/server/data/lib/Lib/test/test_strop.py +133 -0
  682. data/lib/rubyfox/server/data/lib/Lib/test/test_struct.py +441 -0
  683. data/lib/rubyfox/server/data/lib/Lib/test/test_structseq.py +28 -0
  684. data/lib/rubyfox/server/data/lib/Lib/test/test_subclasses.py +204 -0
  685. data/lib/rubyfox/server/data/lib/Lib/test/test_sunaudiodev.py +28 -0
  686. data/lib/rubyfox/server/data/lib/Lib/test/test_sundry.py +102 -0
  687. data/lib/rubyfox/server/data/lib/Lib/test/test_support.py +265 -0
  688. data/lib/rubyfox/server/data/lib/Lib/test/test_symtable.py +8 -0
  689. data/lib/rubyfox/server/data/lib/Lib/test/test_tempfile.py +10 -0
  690. data/lib/rubyfox/server/data/lib/Lib/test/test_thread.py +116 -0
  691. data/lib/rubyfox/server/data/lib/Lib/test/test_threaded_import.py +56 -0
  692. data/lib/rubyfox/server/data/lib/Lib/test/test_threadedtempfile.py +86 -0
  693. data/lib/rubyfox/server/data/lib/Lib/test/test_threading.py +55 -0
  694. data/lib/rubyfox/server/data/lib/Lib/test/test_time.py +47 -0
  695. data/lib/rubyfox/server/data/lib/Lib/test/test_timing.py +21 -0
  696. data/lib/rubyfox/server/data/lib/Lib/test/test_tokenize.py +9 -0
  697. data/lib/rubyfox/server/data/lib/Lib/test/test_trace.py +219 -0
  698. data/lib/rubyfox/server/data/lib/Lib/test/test_traceback.py +49 -0
  699. data/lib/rubyfox/server/data/lib/Lib/test/test_types.py +762 -0
  700. data/lib/rubyfox/server/data/lib/Lib/test/test_ucn.py +113 -0
  701. data/lib/rubyfox/server/data/lib/Lib/test/test_unary.py +58 -0
  702. data/lib/rubyfox/server/data/lib/Lib/test/test_unicode.py +815 -0
  703. data/lib/rubyfox/server/data/lib/Lib/test/test_unicode_file.py +95 -0
  704. data/lib/rubyfox/server/data/lib/Lib/test/test_unicodedata.py +125 -0
  705. data/lib/rubyfox/server/data/lib/Lib/test/test_unpack.py +105 -0
  706. data/lib/rubyfox/server/data/lib/Lib/test/test_urllib.py +109 -0
  707. data/lib/rubyfox/server/data/lib/Lib/test/test_urllib2.py +31 -0
  708. data/lib/rubyfox/server/data/lib/Lib/test/test_urlparse.py +94 -0
  709. data/lib/rubyfox/server/data/lib/Lib/test/test_userdict.py +120 -0
  710. data/lib/rubyfox/server/data/lib/Lib/test/test_userlist.py +269 -0
  711. data/lib/rubyfox/server/data/lib/Lib/test/test_userstring.py +43 -0
  712. data/lib/rubyfox/server/data/lib/Lib/test/test_uu.py +158 -0
  713. data/lib/rubyfox/server/data/lib/Lib/test/test_wave.py +34 -0
  714. data/lib/rubyfox/server/data/lib/Lib/test/test_weakref.py +573 -0
  715. data/lib/rubyfox/server/data/lib/Lib/test/test_winreg.py +151 -0
  716. data/lib/rubyfox/server/data/lib/Lib/test/test_winsound.py +6 -0
  717. data/lib/rubyfox/server/data/lib/Lib/test/test_xmllib.py +35 -0
  718. data/lib/rubyfox/server/data/lib/Lib/test/test_xmlrpc.py +37 -0
  719. data/lib/rubyfox/server/data/lib/Lib/test/test_xreadline.py +43 -0
  720. data/lib/rubyfox/server/data/lib/Lib/test/test_zipfile.py +78 -0
  721. data/lib/rubyfox/server/data/lib/Lib/test/test_zlib.py +482 -0
  722. data/lib/rubyfox/server/data/lib/Lib/test/testall.py +43 -0
  723. data/lib/rubyfox/server/data/lib/Lib/test/testcodec.py +48 -0
  724. data/lib/rubyfox/server/data/lib/Lib/test/testimg.uue +1170 -0
  725. data/lib/rubyfox/server/data/lib/Lib/test/testimgr.uue +1170 -0
  726. data/lib/rubyfox/server/data/lib/Lib/test/testrgb.uue +971 -0
  727. data/lib/rubyfox/server/data/lib/Lib/test/tokenize_tests.py +175 -0
  728. data/lib/rubyfox/server/data/lib/Lib/test/whrandom.py +96 -0
  729. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/dbextstest.py +266 -0
  730. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/jndi.py +33 -0
  731. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/runner.py +204 -0
  732. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/sptest.py +227 -0
  733. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/test.xml +363 -0
  734. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/test_zxjdbc_dbapi20.py +26 -0
  735. data/lib/rubyfox/server/data/lib/Lib/test/zxjdbc/zxtest.py +1242 -0
  736. data/lib/rubyfox/server/data/lib/Lib/this.py +28 -0
  737. data/lib/rubyfox/server/data/lib/Lib/threading.py +698 -0
  738. data/lib/rubyfox/server/data/lib/Lib/token$py.class +0 -0
  739. data/lib/rubyfox/server/data/lib/Lib/token.py +140 -0
  740. data/lib/rubyfox/server/data/lib/Lib/tokenize$py.class +0 -0
  741. data/lib/rubyfox/server/data/lib/Lib/tokenize.py +287 -0
  742. data/lib/rubyfox/server/data/lib/Lib/traceback$py.class +0 -0
  743. data/lib/rubyfox/server/data/lib/Lib/traceback.py +301 -0
  744. data/lib/rubyfox/server/data/lib/Lib/tzparse.py +98 -0
  745. data/lib/rubyfox/server/data/lib/Lib/unittest.py +723 -0
  746. data/lib/rubyfox/server/data/lib/Lib/urllib.py +1465 -0
  747. data/lib/rubyfox/server/data/lib/Lib/urllib2.py +1144 -0
  748. data/lib/rubyfox/server/data/lib/Lib/urlparse.py +276 -0
  749. data/lib/rubyfox/server/data/lib/Lib/user.py +45 -0
  750. data/lib/rubyfox/server/data/lib/Lib/uu.py +195 -0
  751. data/lib/rubyfox/server/data/lib/Lib/warnings$py.class +0 -0
  752. data/lib/rubyfox/server/data/lib/Lib/warnings.py +258 -0
  753. data/lib/rubyfox/server/data/lib/Lib/weakref.py +280 -0
  754. data/lib/rubyfox/server/data/lib/Lib/whichdb.py +87 -0
  755. data/lib/rubyfox/server/data/lib/Lib/whrandom.py +140 -0
  756. data/lib/rubyfox/server/data/lib/Lib/xdrlib.py +285 -0
  757. data/lib/rubyfox/server/data/lib/Lib/xml/FtCore.py +58 -0
  758. data/lib/rubyfox/server/data/lib/Lib/xml/Uri.py +380 -0
  759. data/lib/rubyfox/server/data/lib/Lib/xml/__init__.py +41 -0
  760. data/lib/rubyfox/server/data/lib/Lib/xml/dom/MessageSource.py +54 -0
  761. data/lib/rubyfox/server/data/lib/Lib/xml/dom/NodeFilter.py +27 -0
  762. data/lib/rubyfox/server/data/lib/Lib/xml/dom/__init__.py +232 -0
  763. data/lib/rubyfox/server/data/lib/Lib/xml/dom/domreg.py +99 -0
  764. data/lib/rubyfox/server/data/lib/Lib/xml/dom/minicompat.py +184 -0
  765. data/lib/rubyfox/server/data/lib/Lib/xml/dom/minidom.py +1943 -0
  766. data/lib/rubyfox/server/data/lib/Lib/xml/dom/pulldom.py +350 -0
  767. data/lib/rubyfox/server/data/lib/Lib/xml/dom/xmlbuilder.py +388 -0
  768. data/lib/rubyfox/server/data/lib/Lib/xml/sax/__init__.py +102 -0
  769. data/lib/rubyfox/server/data/lib/Lib/xml/sax/_exceptions.py +127 -0
  770. data/lib/rubyfox/server/data/lib/Lib/xml/sax/drivers2/__init__.py +1 -0
  771. data/lib/rubyfox/server/data/lib/Lib/xml/sax/drivers2/drv_javasax.py +333 -0
  772. data/lib/rubyfox/server/data/lib/Lib/xml/sax/handler.py +345 -0
  773. data/lib/rubyfox/server/data/lib/Lib/xml/sax/saxlib.py +430 -0
  774. data/lib/rubyfox/server/data/lib/Lib/xml/sax/saxutils.py +813 -0
  775. data/lib/rubyfox/server/data/lib/Lib/xml/sax/xmlreader.py +378 -0
  776. data/lib/rubyfox/server/data/lib/Lib/xmllib.py +926 -0
  777. data/lib/rubyfox/server/data/lib/Lib/xmlrpclib.py +1019 -0
  778. data/lib/rubyfox/server/data/lib/Lib/zipfile.py +586 -0
  779. data/lib/rubyfox/server/data/lib/Lib/zlib.py +156 -0
  780. data/lib/rubyfox/server/data/lib/boot.jar +0 -0
  781. data/lib/rubyfox/server/data/lib/cachedir/.keep +0 -0
  782. data/lib/rubyfox/server/data/lib/commons-beanutils-1.7.0.jar +0 -0
  783. data/lib/rubyfox/server/data/lib/commons-collections-3.2.1.jar +0 -0
  784. data/lib/rubyfox/server/data/lib/commons-dbcp-1.4.jar +0 -0
  785. data/lib/rubyfox/server/data/lib/commons-io-1.4.jar +0 -0
  786. data/lib/rubyfox/server/data/lib/commons-lang-2.4.jar +0 -0
  787. data/lib/rubyfox/server/data/lib/commons-logging-1.1.1.jar +0 -0
  788. data/lib/rubyfox/server/data/lib/commons-pool-1.5.4.jar +0 -0
  789. data/lib/rubyfox/server/data/lib/commons-vfs-1.0.jar +0 -0
  790. data/lib/rubyfox/server/data/lib/ezmorph-1.0.6.jar +0 -0
  791. data/lib/rubyfox/server/data/lib/httpclient-4.0.3.jar +0 -0
  792. data/lib/rubyfox/server/data/lib/httpcore-4.0.1.jar +0 -0
  793. data/lib/rubyfox/server/data/lib/imap.jar +0 -0
  794. data/lib/rubyfox/server/data/lib/jconsole/COPYING.txt +504 -0
  795. data/lib/rubyfox/server/data/lib/jconsole/bug_test_case.py +49 -0
  796. data/lib/rubyfox/server/data/lib/jconsole/console$py.class +0 -0
  797. data/lib/rubyfox/server/data/lib/jconsole/console.py +439 -0
  798. data/lib/rubyfox/server/data/lib/jconsole/history$py.class +0 -0
  799. data/lib/rubyfox/server/data/lib/jconsole/history.py +82 -0
  800. data/lib/rubyfox/server/data/lib/jconsole/history_test_case.py +133 -0
  801. data/lib/rubyfox/server/data/lib/jconsole/introspect$py.class +0 -0
  802. data/lib/rubyfox/server/data/lib/jconsole/introspect.py +373 -0
  803. data/lib/rubyfox/server/data/lib/jconsole/introspect_test_case.py +19 -0
  804. data/lib/rubyfox/server/data/lib/jconsole/issue_17_test_case.py +36 -0
  805. data/lib/rubyfox/server/data/lib/jconsole/jintrospect$py.class +0 -0
  806. data/lib/rubyfox/server/data/lib/jconsole/jintrospect.py +316 -0
  807. data/lib/rubyfox/server/data/lib/jconsole/jintrospect_test_case.py +107 -0
  808. data/lib/rubyfox/server/data/lib/jconsole/popup$py.class +0 -0
  809. data/lib/rubyfox/server/data/lib/jconsole/popup.py +178 -0
  810. data/lib/rubyfox/server/data/lib/jconsole/run_tests.py +8 -0
  811. data/lib/rubyfox/server/data/lib/jconsole/static_test_case.py +36 -0
  812. data/lib/rubyfox/server/data/lib/jconsole/testcase.py +38 -0
  813. data/lib/rubyfox/server/data/lib/jconsole/tip$py.class +0 -0
  814. data/lib/rubyfox/server/data/lib/jconsole/tip.py +47 -0
  815. data/lib/rubyfox/server/data/lib/jmx-util-1.2.3.jar +0 -0
  816. data/lib/rubyfox/server/data/lib/joda-time-1.6.jar +0 -0
  817. data/lib/rubyfox/server/data/lib/js.jar +0 -0
  818. data/lib/rubyfox/server/data/lib/json-lib-2.2.3-jdk15.jar +0 -0
  819. data/lib/rubyfox/server/data/lib/jython.jar +0 -0
  820. data/lib/rubyfox/server/data/lib/log4j-1.2.15.jar +0 -0
  821. data/lib/rubyfox/server/data/lib/logs-backup-app.jar +0 -0
  822. data/lib/rubyfox/server/data/lib/mailapi.jar +0 -0
  823. data/lib/rubyfox/server/data/lib/pop3.jar +0 -0
  824. data/lib/rubyfox/server/data/lib/scala-library.jar +0 -0
  825. data/lib/rubyfox/server/data/lib/sfs2x-admin.jar +0 -0
  826. data/lib/rubyfox/server/data/lib/sfs2x-core.jar +0 -0
  827. data/lib/rubyfox/server/data/lib/sfs2x-util.jar +0 -0
  828. data/lib/rubyfox/server/data/lib/sfs2x.jar +0 -0
  829. data/lib/rubyfox/server/data/lib/slf4j-api-1.5.10.jar +0 -0
  830. data/lib/rubyfox/server/data/lib/slf4j-log4j12.jar +0 -0
  831. data/lib/rubyfox/server/data/lib/smtp.jar +0 -0
  832. data/lib/rubyfox/server/data/lib/terracotta-api-1.1.1.jar +0 -0
  833. data/lib/rubyfox/server/data/lib/ws-engine.jar +0 -0
  834. data/lib/rubyfox/server/data/lib/xpp3_min-1.1.4c.jar +0 -0
  835. data/lib/rubyfox/server/data/lib/xstream-1.3.1.jar +0 -0
  836. data/lib/rubyfox/server/data/logs/.keep +0 -0
  837. data/lib/rubyfox/server/data/logs/bluebox/.keep +0 -0
  838. data/lib/rubyfox/server/data/logs/boot/.keep +0 -0
  839. data/lib/rubyfox/server/data/logs/http/.keep +0 -0
  840. data/lib/rubyfox/server/data/logs/smartfox.log +295 -0
  841. data/lib/rubyfox/server/data/root/.keep +0 -0
  842. data/lib/rubyfox/server/data/root/_css_/default.css +170 -0
  843. data/lib/rubyfox/server/data/root/_css_/reset.css +49 -0
  844. data/lib/rubyfox/server/data/root/_images_/background_gradient.png +0 -0
  845. data/lib/rubyfox/server/data/root/_images_/background_logo.png +0 -0
  846. data/lib/rubyfox/server/data/root/_images_/favicon.png +0 -0
  847. data/lib/rubyfox/server/data/root/_images_/logo_smartfoxserver.png +0 -0
  848. data/lib/rubyfox/server/data/root/admin/.keep +0 -0
  849. data/lib/rubyfox/server/data/root/admin/AdminTool.html +108 -0
  850. data/lib/rubyfox/server/data/root/admin/AdminTool.swf +0 -0
  851. data/lib/rubyfox/server/data/root/admin/ReleaseNotes.txt +29 -0
  852. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/adobeFlashPlayer.png +0 -0
  853. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/advanced.png +0 -0
  854. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/banManager.png +0 -0
  855. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bannedIPs.png +0 -0
  856. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bannedUsernames.png +0 -0
  857. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bookmarks.png +0 -0
  858. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/bootLog.png +0 -0
  859. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/buddyList.png +0 -0
  860. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/buddyProperties.png +0 -0
  861. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/connection.png +0 -0
  862. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/databaseManager.png +0 -0
  863. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/floodFilter.png +0 -0
  864. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/gameSettings.png +0 -0
  865. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/general.png +0 -0
  866. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/globalServerStatus.png +0 -0
  867. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/iPFilter.png +0 -0
  868. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/jVMSettings.png +0 -0
  869. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/logsDownload.png +0 -0
  870. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/mailer.png +0 -0
  871. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/permissionsAndEvents.png +0 -0
  872. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/privilegeManager.png +0 -0
  873. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/remoteAdmin.png +0 -0
  874. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/roomExtension.png +0 -0
  875. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/roomVariables.png +0 -0
  876. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/roomsAndGroups.png +0 -0
  877. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeLog.png +0 -0
  878. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeRoomSettings.png +0 -0
  879. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeUserSettings.png +0 -0
  880. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/runtimeZoneSettings.png +0 -0
  881. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/systemQueueStatus.png +0 -0
  882. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/userManagement.png +0 -0
  883. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/userVariables.png +0 -0
  884. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/usersTraffic.png +0 -0
  885. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/webServer.png +0 -0
  886. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/wordsFilter.png +0 -0
  887. data/lib/rubyfox/server/data/root/admin/assets/icons/tabs/zoneExtension.png +0 -0
  888. data/lib/rubyfox/server/data/root/admin/index.html +108 -0
  889. data/lib/rubyfox/server/data/root/admin/modules/BanManager/BanManager.swf +0 -0
  890. data/lib/rubyfox/server/data/root/admin/modules/BanManager/icon.png +0 -0
  891. data/lib/rubyfox/server/data/root/admin/modules/BlueBoxMonitor/BlueBoxMonitor.swf +0 -0
  892. data/lib/rubyfox/server/data/root/admin/modules/BlueBoxMonitor/icon.png +0 -0
  893. data/lib/rubyfox/server/data/root/admin/modules/LicenseManager/LicenseManager.swf +0 -0
  894. data/lib/rubyfox/server/data/root/admin/modules/LicenseManager/icon.png +0 -0
  895. data/lib/rubyfox/server/data/root/admin/modules/LogViewer/LogViewer.swf +0 -0
  896. data/lib/rubyfox/server/data/root/admin/modules/LogViewer/icon.png +0 -0
  897. data/lib/rubyfox/server/data/root/admin/modules/RuntimeStatistics/RuntimeStatistics.swf +0 -0
  898. data/lib/rubyfox/server/data/root/admin/modules/RuntimeStatistics/icon.png +0 -0
  899. data/lib/rubyfox/server/data/root/admin/modules/ServerConfigurator/ServerConfigurator.swf +0 -0
  900. data/lib/rubyfox/server/data/root/admin/modules/ServerConfigurator/icon.png +0 -0
  901. data/lib/rubyfox/server/data/root/admin/modules/ZoneConfigurator/ZoneConfigurator.swf +0 -0
  902. data/lib/rubyfox/server/data/root/admin/modules/ZoneConfigurator/icon.png +0 -0
  903. data/lib/rubyfox/server/data/root/admin/modules/ZoneMonitor/ZoneMonitor.swf +0 -0
  904. data/lib/rubyfox/server/data/root/admin/modules/ZoneMonitor/icon.png +0 -0
  905. data/lib/rubyfox/server/data/root/admin/modules/config.xml +12 -0
  906. data/lib/rubyfox/server/data/root/admin/playerProductInstall.swf +0 -0
  907. data/lib/rubyfox/server/data/root/admin/swfobject.js +777 -0
  908. data/lib/rubyfox/server/data/root/crossdomain.xml +6 -0
  909. data/lib/rubyfox/server/data/root/index.html +63 -0
  910. data/lib/rubyfox/server/data/sfs2x-service +435 -0
  911. data/lib/rubyfox/server/data/sfs2x-service.vmoptions +5 -0
  912. data/lib/rubyfox/server/data/sfs2x.sh +12 -0
  913. data/lib/rubyfox/server/data/www/.keep +0 -0
  914. data/lib/rubyfox/server/data/www/BlueBox.war +0 -0
  915. data/lib/rubyfox/server/data/www/root/_css_/default.css +170 -0
  916. data/lib/rubyfox/server/data/www/root/_css_/reset.css +49 -0
  917. data/lib/rubyfox/server/data/www/root/_images_/background_gradient.png +0 -0
  918. data/lib/rubyfox/server/data/www/root/_images_/background_logo.png +0 -0
  919. data/lib/rubyfox/server/data/www/root/_images_/favicon.png +0 -0
  920. data/lib/rubyfox/server/data/www/root/_images_/logo_smartfoxserver.png +0 -0
  921. data/lib/rubyfox/server/data/www/root/admin/.keep +0 -0
  922. data/lib/rubyfox/server/data/www/root/admin/AdminTool.html +108 -0
  923. data/lib/rubyfox/server/data/www/root/admin/AdminTool.swf +0 -0
  924. data/lib/rubyfox/server/data/www/root/admin/ReleaseNotes.txt +63 -0
  925. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/adobeFlashPlayer.png +0 -0
  926. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/advanced.png +0 -0
  927. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/banManager.png +0 -0
  928. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bannedIPs.png +0 -0
  929. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bannedUsernames.png +0 -0
  930. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bookmarks.png +0 -0
  931. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bootLog.png +0 -0
  932. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/buddyList.png +0 -0
  933. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/buddyProperties.png +0 -0
  934. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/connection.png +0 -0
  935. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/databaseManager.png +0 -0
  936. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/floodFilter.png +0 -0
  937. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/gameSettings.png +0 -0
  938. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/general.png +0 -0
  939. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/globalServerStatus.png +0 -0
  940. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/hTML5WebSockets.png +0 -0
  941. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/iPFilter.png +0 -0
  942. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/jVMSettings.png +0 -0
  943. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/logsDownload.png +0 -0
  944. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/mailer.png +0 -0
  945. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/permissionsAndEvents.png +0 -0
  946. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/privilegeManager.png +0 -0
  947. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/remoteAdmin.png +0 -0
  948. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomExtension.png +0 -0
  949. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomVariables.png +0 -0
  950. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomsAndGroups.png +0 -0
  951. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeLog.png +0 -0
  952. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeRoomSettings.png +0 -0
  953. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeUserSettings.png +0 -0
  954. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeZoneSettings.png +0 -0
  955. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/systemQueueStatus.png +0 -0
  956. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/userManagement.png +0 -0
  957. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/userVariables.png +0 -0
  958. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/usersTraffic.png +0 -0
  959. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/webServer.png +0 -0
  960. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/wordsFilter.png +0 -0
  961. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/zoneExtension.png +0 -0
  962. data/lib/rubyfox/server/data/www/root/admin/index.html +108 -0
  963. data/lib/rubyfox/server/data/www/root/admin/modules/BanManager/BanManager.swf +0 -0
  964. data/lib/rubyfox/server/data/www/root/admin/modules/BanManager/icon.png +0 -0
  965. data/lib/rubyfox/server/data/www/root/admin/modules/BlueBoxMonitor/BlueBoxMonitor.swf +0 -0
  966. data/lib/rubyfox/server/data/www/root/admin/modules/BlueBoxMonitor/icon.png +0 -0
  967. data/lib/rubyfox/server/data/www/root/admin/modules/Dashboard/Dashboard.swf +0 -0
  968. data/lib/rubyfox/server/data/www/root/admin/modules/Dashboard/icon.png +0 -0
  969. data/lib/rubyfox/server/data/www/root/admin/modules/LicenseManager/LicenseManager.swf +0 -0
  970. data/lib/rubyfox/server/data/www/root/admin/modules/LicenseManager/icon.png +0 -0
  971. data/lib/rubyfox/server/data/www/root/admin/modules/LogViewer/LogViewer.swf +0 -0
  972. data/lib/rubyfox/server/data/www/root/admin/modules/LogViewer/icon.png +0 -0
  973. data/lib/rubyfox/server/data/www/root/admin/modules/RuntimeStatistics/RuntimeStatistics.swf +0 -0
  974. data/lib/rubyfox/server/data/www/root/admin/modules/RuntimeStatistics/icon.png +0 -0
  975. data/lib/rubyfox/server/data/www/root/admin/modules/ServerConfigurator/ServerConfigurator.swf +0 -0
  976. data/lib/rubyfox/server/data/www/root/admin/modules/ServerConfigurator/icon.png +0 -0
  977. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneConfigurator/ZoneConfigurator.swf +0 -0
  978. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneConfigurator/icon.png +0 -0
  979. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneMonitor/ZoneMonitor.swf +0 -0
  980. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneMonitor/icon.png +0 -0
  981. data/lib/rubyfox/server/data/www/root/admin/modules/config.xml +12 -0
  982. data/lib/rubyfox/server/data/www/root/admin/playerProductInstall.swf +0 -0
  983. data/lib/rubyfox/server/data/www/root/admin/swfobject.js +777 -0
  984. data/lib/rubyfox/server/data/www/root/crossdomain.xml +6 -0
  985. data/lib/rubyfox/server/data/www/root/examples/.keep +0 -0
  986. data/lib/rubyfox/server/data/www/root/examples/index.html +43 -0
  987. data/lib/rubyfox/server/data/www/root/index.html +63 -0
  988. data/lib/rubyfox/server/data/zones/.keep +0 -0
  989. data/lib/rubyfox/server/environment.rb +31 -0
  990. data/lib/rubyfox/server/version.rb +5 -0
  991. data/lib/rubyfox/server.rb +9 -0
  992. data/rubyfox-server.gemspec +22 -0
  993. metadata +1076 -0
@@ -0,0 +1,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()