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